]> git.eshelyaron.com Git - emacs.git/commitdiff
Ensure .dir-locals-2.el behavior as documented (bug#75890)
authorshipmints <shipmints@gmail.com>
Sun, 16 Feb 2025 19:30:45 +0000 (14:30 -0500)
committerEshel Yaron <me@eshelyaron.com>
Sun, 23 Mar 2025 19:34:07 +0000 (20:34 +0100)
* lisp/files.el
(dir-locals--all-files): New &optional 'base-el-only' argument.
(dir-locals--base-file): New function.
(dir-locals-find-file): 'locate-dominating-file' only for the base
.dir-locals.el.

* test/lisp/files-tests.el
(files-test-dir-locals-2-solo): New test.
* test/lisp/files-resources/dir-locals-2-solo: New test support.
(files-test-dir-locals-2-paired): New test.
* test/lisp/files-resources/dir-locals-and-2: New test support.

(cherry picked from commit 81c21d89ede8dfa664b7a3700acd7bf4c9fa54aa)

lisp/files.el
test/lisp/files-resources/dir-locals-2-solo/.dir-locals-2.el [new file with mode: 0644]
test/lisp/files-resources/dir-locals-2-solo/dir-locals-2-solo.txt [new file with mode: 0644]
test/lisp/files-resources/dir-locals-and-2/.dir-locals-2.el [new file with mode: 0644]
test/lisp/files-resources/dir-locals-and-2/.dir-locals.el [new file with mode: 0644]
test/lisp/files-resources/dir-locals-and-2/dir-locals-and-2.txt [new file with mode: 0644]
test/lisp/files-tests.el

index 771e55effadaa80952288addba98b4963ce2da16..97d6280b5c60e695ce8a28040ff4a1c15a3164fb 100644 (file)
@@ -4756,21 +4756,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
@@ -4780,6 +4781,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.
@@ -4801,7 +4806,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 (file)
index 0000000..0858493
--- /dev/null
@@ -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 (file)
index 0000000..83ed648
--- /dev/null
@@ -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 (file)
index 0000000..0858493
--- /dev/null
@@ -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 (file)
index 0000000..2b57bf9
--- /dev/null
@@ -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 (file)
index 0000000..bb8a31c
--- /dev/null
@@ -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'
index 9f17747da1f022a1e247b42f356b8c425fe9beaf..91ca557204ee2d8de57e3cf995cce72819979ad9 100644 (file)
@@ -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"))