From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Johan Claesson Newsgroups: gmane.emacs.bugs Subject: bug#12357: 24.2; list-load-path-shadow should ignore .dir-locals.el Date: Tue, 04 Mar 2014 23:29:24 +0100 Message-ID: <87eh2hr41n.fsf@bredband.net> References: <87harcsi6n.fsf@bredband.net> <87ipbor4jg.fsf@bredband.net> <871ui1lrtk.fsf@bredband.net> <87y50yqmwd.fsf@gnu.org> <8761nwqmd5.fsf@bredband.net> <87r46kgrco.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1393972213 32278 80.91.229.3 (4 Mar 2014 22:30:13 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 4 Mar 2014 22:30:13 +0000 (UTC) Cc: 12357@debbugs.gnu.org To: Xue Fuqiao Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Mar 04 23:30:21 2014 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WKxqu-0000i2-EM for geb-bug-gnu-emacs@m.gmane.org; Tue, 04 Mar 2014 23:30:20 +0100 Original-Received: from localhost ([::1]:48913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKxqt-0003yr-PH for geb-bug-gnu-emacs@m.gmane.org; Tue, 04 Mar 2014 17:30:19 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54839) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKxqk-0003t1-B7 for bug-gnu-emacs@gnu.org; Tue, 04 Mar 2014 17:30:16 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WKxqe-0001UH-Bi for bug-gnu-emacs@gnu.org; Tue, 04 Mar 2014 17:30:10 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:49684) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKxqe-0001Tf-8B for bug-gnu-emacs@gnu.org; Tue, 04 Mar 2014 17:30:04 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1WKxqc-0003jE-Ne for bug-gnu-emacs@gnu.org; Tue, 04 Mar 2014 17:30:03 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Johan Claesson Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 04 Mar 2014 22:30:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12357 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 12357-submit@debbugs.gnu.org id=B12357.139397216814250 (code B ref 12357); Tue, 04 Mar 2014 22:30:01 +0000 Original-Received: (at 12357) by debbugs.gnu.org; 4 Mar 2014 22:29:28 +0000 Original-Received: from localhost ([127.0.0.1]:50866 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1WKxq2-0003hl-Sn for submit@debbugs.gnu.org; Tue, 04 Mar 2014 17:29:28 -0500 Original-Received: from smtprelay-b22.telenor.se ([195.54.99.213]:51192) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1WKxpz-0003ha-9O for 12357@debbugs.gnu.org; Tue, 04 Mar 2014 17:29:25 -0500 Original-Received: from ipb2.telenor.se (ipb2.telenor.se [195.54.127.165]) by smtprelay-b22.telenor.se (Postfix) with ESMTP id E5489EB91B for <12357@debbugs.gnu.org>; Tue, 4 Mar 2014 23:29:21 +0100 (CET) X-SMTPAUTH-B2: [b157288] X-SENDER-IP: [85.224.212.166] X-LISTENER: [smtp.bredband.net] X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlODAK5SFlNV4NSmPGdsb2JhbABagwaIT7lDAgKBHhcDAQEBATg1giUBAQEBAgFWIwULCAMOEyUPAQQlChoTGodXDAHNXBcWjjsHhDgErhU7 X-IronPort-AV: E=Sophos;i="4.97,588,1389740400"; d="diff'?scan'208";a="838155906" Original-Received: from c-a6d4e055.1542-1-64736c20.cust.bredbandsbolaget.se (HELO goblin) ([85.224.212.166]) by ipb2.telenor.se with ESMTP; 04 Mar 2014 23:29:21 +0100 In-Reply-To: <87r46kgrco.fsf@gnu.org> (Xue Fuqiao's message of "Mon, 03 Mar 2014 06:36:55 +0800") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:86556 Archived-At: --=-=-= Content-Type: text/plain Ok, that is added to the loading.texi patch. Also list-load-path-dir-locals-shadows was renamed to list-dir-locals-shadows. An argument PATH was added since it makes sense to run this on other directories than load-path. And the argument STRINGP was added to align with list-load-path-shadows. NEWS suggestion: ** `list-load-path-shadows' no longer reports .dir-locals.el files. A .dir-locals.el file may shadow another .dir-locals.el file but not in the same sense as in `list-load-path-shadows'. A new command `list-dir-locals-shadows' is introduced. It detect shadows of .dir-locals.el files in a way that make sense for this type of files. ChangeLog suggestion: * emacs-lisp/shadows.el (load-path-shadows-find): Do not report .dir-locals.el files. (list-dir-locals-shadows): New command that reports shadows of .dir-locals.el in a way that make sense for that type of file. (dir-locals-shadows-find, dir-locals-shadows-find-1) (dir-locals-class-name, dir-locals-shadows-display): Auxiliary functions for list-dir-locals-shadows. Regards, /Johan --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=shadow.el.diff === 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-04 22:26:00 +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,21 @@ (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) + (let ((file (match-string (1+ i)))) + (when (file-exists-p file) + (make-button (match-beginning (1+ i)) + (match-end (1+ i)) + 'type 'load-path-shadows-find-file + 'shadow-file file)))))))) + ;;;###autoload (defun list-load-path-shadows (&optional stringp) @@ -231,6 +254,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-dir-locals-shadows'. + Shadowings are located by calling the (non-interactive) companion function, `load-path-shadows-find'." (interactive) @@ -257,14 +285,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 +302,93 @@ (forward-line 1)) (message "%s" msg))))))) + + + +;;;###autoload +(defun list-dir-locals-shadows (&optional stringp path) + "Display a list of .dir-locals.el 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. + +If the optional argument STRINGP is non-nil, returns any shadows +as a string. Otherwise, if interactive shows any shadows in a +`*Dir-Locals-Shadows*' buffer; else print a message listing any +shadows. + +The optional argument PATH is the directory or list of +directories to examine. It defaults to the value of `load-path'. + +This command complements the command `list-load-path-shadows'." + (interactive) + (unless path + (setq path load-path)) + (let ((string (dir-locals-shadows-find path))) + (if stringp + string + (if (zerop (length string)) + (message "No dir-local shadows found.") + (if (called-interactively-p 'interactive) + (dir-locals-shadows-display string) + (message "Dir-locals shadows:\n%s" string)))))) + +(defun dir-locals-shadows-find (path) + "Return a string of .dir-locals.el files that shadows other such files. + +The argument PATH is the directory or list of directories to +examine. + +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." + (when (stringp path) + (setq path (list path))) + (with-temp-buffer + (dolist (dir path) + (if (file-directory-p dir) + (dir-locals-shadows-find-1 dir (dir-locals-find-file (file-name-as-directory dir))) + (insert (format "Invalid dir %s\n" dir)))) + (buffer-string))) + +(defun dir-locals-shadows-find-1 (dir locals) + "Auxiliary function for `dir-locals-shadows-find'." + (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-find-1 subdir subdir-locals)))))) + +(defun dir-locals-class-name (class) + "Returns a describing string for directory-local class CLASS. + +CLASS is a values returned from `dir-locals-find-file'. It +can be a string or a list. See that function for details." + (if (stringp class) + class + (if (file-name-directory (symbol-name (cadr class))) + (concat (car class) dir-locals-file) + (format "%s (class %s)" (car class) (cadr class))))) + +(defun dir-locals-shadows-display (string) + "Display the dir-locals shadows STRING in a buffer." + (with-current-buffer (get-buffer-create "*Dir-Locals-Shadows*") + (load-path-shadows-mode) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert string) + (load-path-shadows-make-buttons) + (display-buffer (current-buffer))))) + (provide 'shadow) ;;; shadow.el ends here --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=loading.texi.diff === 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-04 22:12:52 +0000 @@ -411,12 +411,35 @@ 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. But see the command @code{list-dir-locals-shadows} +below. + 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 +optional argument @var{stringp} is non-@code{nil}, it instead returns the shadowed files as a string. @end deffn +@deffn Command list-dir-locals-shadows &optional stringp path +This command displays a list of @file{.dir-locals.el} files that shadow other +such files. + +A @file{.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. + +If the optional argument @var{stringp} is non-@code{nil}, returns any +shadows as a string. Otherwise, if interactive shows any shadows in a +buffer; else prints a message listing any shadows. + +The optional argument @var{path} is the directory or list of directories +to examine. It defaults to the value of @code{load-path}. +@end deffn + + @node Loading Non-ASCII @section Loading Non-@acronym{ASCII} Characters --=-=-= Content-Type: text/plain Xue Fuqiao writes: > Johan Claesson writes: > >> Do you think there should be a @deffn entry for >> list-load-path-dir-locals-shadows as well? > > I think so. --=-=-=--