diff --git a/lisp/files.el b/lisp/files.el index 461960d6f2b..4e3aeeb9246 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4713,21 +4713,22 @@ the \".dir-locals.el\". See Info node `(elisp)Directory Local Variables' for details.") -(defun dir-locals--all-files (directory) +(defun dir-locals--all-files (directory &optional base-el-only) "Return a list of all readable dir-locals files in DIRECTORY. The returned list is sorted by increasing priority. That is, values specified in the last file should take precedence over those in the first." (when (file-readable-p directory) (let* ((file-1 (expand-file-name (if (eq system-type 'ms-dos) - (dosified-file-name dir-locals-file) - dir-locals-file) - directory)) + (dosified-file-name dir-locals-file) + dir-locals-file) + directory)) (file-2 (when (string-match "\\.el\\'" file-1) (replace-match "-2.el" t nil file-1))) - (out nil)) - ;; The order here is important. - (dolist (f (list file-2 file-1)) + out) + (dolist (f (or (and base-el-only (list file-1)) + ;; The order here is important. + (list file-2 file-1))) (when (and f (file-readable-p f) ;; FIXME: Aren't file-regular-p and @@ -4737,6 +4738,10 @@ those in the first." (push f out))) out))) +(defun dir-locals--base-file (directory) + "Return readable `dir-locals-file' in DIRECTORY, or nil." + (dir-locals--all-files directory 'base-el-only)) + (defun dir-locals-find-file (file) "Find the directory-local variables for FILE. This searches upward in the directory tree from FILE. @@ -4758,7 +4763,7 @@ This function returns either: entry." (setq file (expand-file-name file)) (let* ((locals-dir (locate-dominating-file (file-name-directory file) - #'dir-locals--all-files)) + #'dir-locals--base-file)) dir-elt) ;; `locate-dominating-file' may have abbreviated the name. (when locals-dir diff --git a/test/lisp/files-resources/dir-locals-2-solo/.dir-locals-2.el b/test/lisp/files-resources/dir-locals-2-solo/.dir-locals-2.el new file mode 100644 index 00000000000..08584933c41 --- /dev/null +++ b/test/lisp/files-resources/dir-locals-2-solo/.dir-locals-2.el @@ -0,0 +1 @@ +((nil . ((dir-locals-2-loaded . t)))) diff --git a/test/lisp/files-resources/dir-locals-2-solo/dir-locals-2-solo.txt b/test/lisp/files-resources/dir-locals-2-solo/dir-locals-2-solo.txt new file mode 100644 index 00000000000..83ed6482e06 --- /dev/null +++ b/test/lisp/files-resources/dir-locals-2-solo/dir-locals-2-solo.txt @@ -0,0 +1,3 @@ +# Used by files-test.el. +# Due to solo .dir-locals-2.el, the local variable `dir-locals-2-loaded' +# should be undefined. diff --git a/test/lisp/files-resources/dir-locals-and-2/.dir-locals-2.el b/test/lisp/files-resources/dir-locals-and-2/.dir-locals-2.el new file mode 100644 index 00000000000..08584933c41 --- /dev/null +++ b/test/lisp/files-resources/dir-locals-and-2/.dir-locals-2.el @@ -0,0 +1 @@ +((nil . ((dir-locals-2-loaded . t)))) diff --git a/test/lisp/files-resources/dir-locals-and-2/.dir-locals.el b/test/lisp/files-resources/dir-locals-and-2/.dir-locals.el new file mode 100644 index 00000000000..2b57bf9e7c0 --- /dev/null +++ b/test/lisp/files-resources/dir-locals-and-2/.dir-locals.el @@ -0,0 +1 @@ +((nil . ((dir-locals-loaded . t)))) diff --git a/test/lisp/files-resources/dir-locals-and-2/dir-locals-and-2.txt b/test/lisp/files-resources/dir-locals-and-2/dir-locals-and-2.txt new file mode 100644 index 00000000000..bb8a31ca147 --- /dev/null +++ b/test/lisp/files-resources/dir-locals-and-2/dir-locals-and-2.txt @@ -0,0 +1,4 @@ +# Used by files-test.el. +# .dir-locals.el and .dir-locals-2.el should define: +# local variable `dir-locals-loaded' +# local variable `dir-locals-2-loaded' diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 9f17747da1f..91ca557204e 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -1782,6 +1782,21 @@ set to." ;; Invocation through env, with modified environment. (files-tests--check-shebang "#!/usr/bin/env -S PYTHONPATH=/...:${PYTHONPATH} python" 'python-base-mode)) +(ert-deftest files-test-dir-locals-2-solo () + "Ensure that solo `.dir-locals-2.el' is ignored." + (with-current-buffer + (find-file-noselect (ert-resource-file + (concat "dir-locals-2-solo/dir-locals-2-solo.txt"))) + (should-not (local-variable-p 'dir-locals-2-loaded)))) + +(ert-deftest files-test-dir-locals-2-paired () + "Ensure that `.dir-locals-2.el' is loaded, if paired." + (let ((enable-local-variables :all)) + (with-current-buffer (find-file-noselect + (ert-resource-file (concat "dir-locals-and-2/dir-locals-and-2.txt"))) + (should (local-variable-p 'dir-locals-loaded)) + (should (local-variable-p 'dir-locals-2-loaded))))) + (ert-deftest files-test-dir-locals-auto-mode-alist () "Test an `auto-mode-alist' entry in `.dir-locals.el'" (find-file (ert-resource-file "whatever.quux"))