unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Johan Claesson <johanclaesson@bredband.net>
To: Xue Fuqiao <xfq@gnu.org>
Cc: 12357@debbugs.gnu.org
Subject: bug#12357: 24.2; list-load-path-shadow should ignore .dir-locals.el
Date: Sun, 02 Mar 2014 23:14:30 +0100	[thread overview]
Message-ID: <8761nwqmd5.fsf@bredband.net> (raw)
In-Reply-To: <87y50yqmwd.fsf@gnu.org> (Xue Fuqiao's message of "Wed, 26 Feb 2014 16:49:22 +0800")

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]



Great.  Attached is a loading.texi patch that just add to the
description of list-load-path-shadows that it will not report
.dir-locals.el files.  Do you think there should be a @deffn entry for 
list-load-path-dir-locals-shadows as well?

Also attached is a shadow.el patch with the following changes: 

1. Some more doc string text. 
2. list-load-path-dir-locals-shadows uses the same button making code as
list-load-path-shadows. 
3. Inherit the major mode from special-mode instead of fundamental-mode
to get quit on ?q etc. 
4. Also bind forward-button to tab in this mode.  And backward-button to
backtab. 
5. It will not bail out on an invalid directory in load-path any more (i
happened to have some invalid directories in load-path while testing
this :) ). 

Regards,

/Johan


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: loading.texi.diff --]
[-- Type: text/x-diff, Size: 825 bytes --]

=== modified file 'doc/lispref/loading.texi'
--- old/doc/lispref/loading.texi	2014-01-01 07:43:34 +0000
+++ new/doc/lispref/loading.texi	2014-03-02 21:39:14 +0000
@@ -411,12 +411,19 @@
 directory.  Such a situation might indicate a problem in the way Emacs
 was installed.
 
+Files named @file{.dir-locals.el} are not reported by this command.
+These files specify directory local variables, see @ref{Directory
+Local Variables}.  It is normal that it exists multiple files with
+this name.
+
 When called from Lisp, this function prints a message listing the
 shadowed files, instead of displaying them in a buffer.  If the
 optional argument @code{stringp} is non-@code{nil}, it instead returns
 the shadowed files as a string.
 @end deffn
 
+
+
 @node Loading Non-ASCII
 @section Loading Non-@acronym{ASCII} Characters
 


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: shadow.el.diff --]
[-- Type: text/x-diff, Size: 6049 bytes --]

=== modified file 'lisp/emacs-lisp/shadow.el'
--- old/lisp/emacs-lisp/shadow.el	2014-01-01 07:43:34 +0000
+++ new/lisp/emacs-lisp/shadow.el	2014-03-02 22:06:37 +0000
@@ -115,7 +115,8 @@
 	  ;; FILE now contains the current file name, with no suffix.
 	  (unless (or (member file files-seen-this-dir)
 		      ;; Ignore these files.
-		      (member file '("subdirs" "leim-list")))
+		      (member file '("subdirs" "leim-list"))
+                      (string= file (file-name-sans-extension dir-locals-file)))
 	    ;; File has not been seen yet in this directory.
 	    ;; This test prevents us declaring that XXX.el shadows
 	    ;; XXX.elc (or vice-versa) when they are in the same directory.
@@ -169,20 +170,27 @@
      . (1 font-lock-warning-face)))
   "Keywords to highlight in `load-path-shadows-mode'.")
 
-(define-derived-mode load-path-shadows-mode fundamental-mode "LP-Shadows"
+(define-derived-mode load-path-shadows-mode special-mode "LP-Shadows"
   "Major mode for load-path shadows buffer."
   (set (make-local-variable 'font-lock-defaults)
        '((load-path-shadows-font-lock-keywords)))
   (setq buffer-undo-list t
 	buffer-read-only t))
 
+(let ((map (make-sparse-keymap)))
+  (define-key map [tab] 'forward-button)
+  (define-key map [backtab] 'backward-button)
+  (setq load-path-shadows-mode-map map))
+
 ;; TODO use text-properties instead, a la dired.
 (require 'button)
 (define-button-type 'load-path-shadows-find-file
   'follow-link t
-;;  'face 'default
   'action (lambda (button)
-	    (let ((file (concat (button-get button 'shadow-file) ".el")))
+	    (let* ((shadow-file (button-get button 'shadow-file))
+                   (file (if (equal (file-name-extension shadow-file) "el")
+                             shadow-file
+                           (concat shadow-file ".el"))))
 	      (or (file-exists-p file)
 		  (setq file (concat file ".gz")))
 	      (if (file-readable-p file)
@@ -190,6 +198,20 @@
 		(error "Cannot read file"))))
   'help-echo "mouse-2, RET: find this file")
 
+(defun load-path-shadows-make-buttons ()
+  "Create buttons for `load-path-shadows-mode'."
+  (let ((inhibit-read-only t))
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward "\\(^.*\\) hides \\(.*$\\)"
+                                nil t)
+        (dotimes (i 2)
+          (make-button (match-beginning (1+ i))
+                       (match-end (1+ i))
+                       'type 'load-path-shadows-find-file
+                       'shadow-file
+                       (match-string (1+ i))))))))
+
 \f
 ;;;###autoload
 (defun list-load-path-shadows (&optional stringp)
@@ -231,6 +253,11 @@
 XXX.elc in an early directory (that does not contain XXX.el) is
 considered to shadow a later file XXX.el, and vice-versa.
 
+Files named .dir-locals.el are not reported by this command.
+These files specify directory local variables.  It is normal that
+it exists multiple files with this name.  But see the command
+`list-load-path-dir-locals-shadows'.
+
 Shadowings are located by calling the (non-interactive) companion
 function, `load-path-shadows-find'."
   (interactive)
@@ -257,14 +284,7 @@
 		  (erase-buffer)
 		  (insert string)
 		  (insert msg "\n")
-		  (while (re-search-backward "\\(^.*\\) hides \\(.*$\\)"
-					     nil t)
-		    (dotimes (i 2)
-		      (make-button (match-beginning (1+ i))
-				   (match-end (1+ i))
-				   'type 'load-path-shadows-find-file
-				   'shadow-file
-				   (match-string (1+ i)))))
+                  (load-path-shadows-make-buttons)
 		  (goto-char (point-max)))))
 	  ;; We are non-interactive, print shadows via message.
 	  (unless (zerop n)
@@ -281,6 +301,64 @@
 	      (forward-line 1))
 	    (message "%s" msg)))))))
 
+
+
+\f
+
+(defun list-load-path-dir-locals-shadows ()
+  "Display a list of dir-local files that shadow other such files.
+
+A .dir-locals.el file will shadow any other such file higher up
+in the directory tree.  Sometimes this is what you want,
+sometimes it is not.  This command will show all such shadowing
+in the current `load-path'.
+
+This command complements the command `list-load-path-shadows'.
+"
+  (interactive)
+  (dir-locals-shadows load-path))
+
+(defun dir-locals-shadows (path)
+  "Display a list of dir-local files that shadow other files under PATH."
+  (when (stringp path)
+    (setq path (list path)))
+  (with-current-buffer (get-buffer-create "*Dir-Locals-Shadows*")
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (dolist (dir path)
+        (if (file-directory-p dir)
+            (dir-locals-shadows-1 dir (dir-locals-find-file (file-name-as-directory dir)))
+          (insert (format "invalid dir %s\n" dir)))))
+    (load-path-shadows-mode)
+    (load-path-shadows-make-buttons)
+    (if (> (point-max) (point-min))
+        (display-buffer (current-buffer))
+      (kill-buffer (current-buffer))
+      (message "No dir-local shadows found."))))
+
+(defun dir-locals-class-name (class)
+  (if (stringp class)
+      class
+    (if (file-name-directory (symbol-name (cadr class)))
+        (concat (car class) dir-locals-file)
+      (format "%s%s (class %s)" (car class) dir-locals-file (cadr class)))))
+
+(defun dir-locals-shadows-1 (dir locals)
+  "Auxiliary function for `dir-locals-shadows'."
+  (dolist (file (directory-files dir nil nil 'no-sort))
+    (let ((subdir (expand-file-name file dir)))
+      (when (and (file-directory-p subdir)
+                 (not (or (string-equal file ".")
+                          (string-equal file "..")
+                          (file-symlink-p subdir))))
+        (let ((subdir-locals (dir-locals-find-file (file-name-as-directory subdir))))
+          (and locals
+               (not (equal locals subdir-locals))
+               (insert (format "%s hides %s\n"
+                               (dir-locals-class-name subdir-locals)
+                               (dir-locals-class-name locals))))
+          (dir-locals-shadows-1 subdir subdir-locals))))))
+
 (provide 'shadow)
 
 ;;; shadow.el ends here


[-- Attachment #4: Type: text/plain, Size: 3006 bytes --]






Xue Fuqiao <xfq@gnu.org> writes:

> Johan Claesson <johanclaesson@bredband.net> writes:
>
>> A command to search for .dir-local.el shadows could look something like
>> below.
>
> Looks fine to me.  I made a patch (and tested it).  Any comments?
>
> (I haven't written the documentation/ChangeLog/NEWS yet.)
>
> === modified file 'lisp/emacs-lisp/shadow.el'
> --- lisp/emacs-lisp/shadow.el	2014-01-01 07:43:34 +0000
> +++ lisp/emacs-lisp/shadow.el	2014-02-26 08:38:54 +0000
> @@ -115,7 +115,8 @@
>  	  ;; FILE now contains the current file name, with no suffix.
>  	  (unless (or (member file files-seen-this-dir)
>  		      ;; Ignore these files.
> -		      (member file '("subdirs" "leim-list")))
> +		      (member file '("subdirs" "leim-list"))
> +		      (string= file (file-name-sans-extension dir-locals-file)))
>  	    ;; File has not been seen yet in this directory.
>  	    ;; This test prevents us declaring that XXX.el shadows
>  	    ;; XXX.elc (or vice-versa) when they are in the same directory.
> @@ -281,6 +282,49 @@
>  	      (forward-line 1))
>  	    (message "%s" msg)))))))
>  
> +\f
> +
> +(defun list-load-path-dir-locals-shadows ()
> +  "Display a list of dir-local files that shadow other files."
> +  (interactive)
> +  (dir-locals-shadows load-path))
> +
> +(defun dir-locals-shadows (path)
> +  "Display a list of dir-local files that shadow other files under PATH."
> +  (when (stringp path)
> +    (setq path (list path)))
> +  (with-current-buffer (get-buffer-create "*Dir-Locals-Shadows*")
> +    (erase-buffer)
> +    (dolist (dir path)
> +      (dir-locals-shadows-1 dir (dir-locals-find-file (file-name-as-directory dir))))
> +    (if (> (point-max) (point-min))
> +        (display-buffer (current-buffer))
> +      (kill-buffer (current-buffer))
> +      (message "No dir-local shadows found."))))
> +
> +(defun dir-locals-class-name (class)
> +  (if (stringp class)
> +      class
> +    (if (file-name-directory (symbol-name (cadr class)))
> +        (concat (car class) dir-locals-file)
> +      (format "%s%s (class %s)" (car class) dir-locals-file (cadr class)))))
> +
> +(defun dir-locals-shadows-1 (dir locals)
> +  "Auxiliary function for `dir-locals-shadows'."
> +  (dolist (file (directory-files dir nil nil 'no-sort))
> +    (let ((subdir (expand-file-name file dir)))
> +      (when (and (file-directory-p subdir)
> +                 (not (or (string-equal file ".")
> +                          (string-equal file "..")
> +                          (file-symlink-p subdir))))
> +        (let ((subdir-locals (dir-locals-find-file (file-name-as-directory subdir))))
> +          (and locals
> +               (not (equal locals subdir-locals))
> +               (insert (format "%s shadows %s\n"
> +                               (dir-locals-class-name subdir-locals)
> +                               (dir-locals-class-name locals))))
> +          (dir-locals-shadows-1 subdir subdir-locals))))))
> +
>  (provide 'shadow)
>  
>  ;;; shadow.el ends here

  reply	other threads:[~2014-03-02 22:14 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-05 13:38 bug#12357: 24.2; list-load-path-shadow should ignore .dir-locals.el Johan Claesson
2012-09-05 16:23 ` Johan Claesson
2012-09-08  1:13 ` Glenn Morris
2012-09-08 14:08   ` Johan Claesson
2012-09-16 18:56     ` Johan Claesson
2014-02-26  8:49       ` Xue Fuqiao
2014-03-02 22:14         ` Johan Claesson [this message]
2014-03-02 22:36           ` Xue Fuqiao
2014-03-04 22:29             ` Johan Claesson
2014-03-05  0:54               ` Leo Liu
2014-03-05  7:09                 ` Johan Claesson
2014-03-06  2:07                   ` Glenn Morris
2014-03-06 21:58                     ` Johan Claesson
2014-03-05  7:25                 ` Johan Claesson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8761nwqmd5.fsf@bredband.net \
    --to=johanclaesson@bredband.net \
    --cc=12357@debbugs.gnu.org \
    --cc=xfq@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).