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
next prev parent 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
* 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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.