Subject: bug#12357: 24.2; list-load-path-shadow should ignore .dir-locals.el

From: Johan Claesson <[email-masked]>
Date: Sun, 16 Sep 2012 20:56:39 +0200

A command to search for .dir-local.el shadows could look something like
below.  Let me know if a polished version of the code below would be
useful.

I should probably clarify that this was not at all what i had in mind
when writing this bug report/suggestion in the first place :).  I would
be happy if just the list-load-path-shadows command would ignore
.dir-locals.el files.

(defun list-load-path-dir-locals-shadows ()
  (interactive)
  (dir-locals-shadows load-path))

(defun dir-locals-shadows (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-aux 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-aux (dir locals)
  (dolist (file (directory-files dir nil nil t))
    (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-aux subdir subdir-locals))))))

Regards,

/Johan

Johan Claesson <[email-masked]> writes:

> I did not think about that kind of shadowing.  I agree that would also
> be nice to have reported.  But i think it is a different thing.  Also
> it could be that the user wants the lower dir-locals file to shadow the
> higher one.  But i guess no user wants one lisp file to shadow another
> in the load-path.  
>
> Maybe a separate command could search for dir-local files shadowing
> other dir-local files for a given directory or list of directories.
> (I could submit such a function.)
>
> I usually run list-load-path-shadows in the same go as compiling my
> elisp directory and just like it is nice to have no compiler warnings it
> is nice to have no shadow warnings.
>
> Regards,
>
> /Johan
>
>
> Glenn Morris <[email-masked]> writes:
>
>> Johan Claesson wrote:
>>
>>> A minor suggestion for shadow.el.  list-load-path-shadows will detect
>>> if there are two lisp files with the same name in the load-path.  Such
>>> a clash could cause problems for normal lisp files.  But i think it is
>>> normal to have multiple .dir-locals.el files spread across the
>>> load-path.  In order to avoid false warnings list-load-path-shadows
>>> could ignore the special file name .dir-locals.el.
>>
>> I think you are right, but if any one given directory has more than one
>> dir-locals file above it in the directory tree, then the "lowest" one
>> does indeed shadow all the "higher" ones. So it might be good to still
>> report such cases?