aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorNeil Roberts2019-05-10 12:57:28 +0200
committerNoam Postavsky2019-05-12 09:59:55 -0400
commit02bee7860f7e650ef13e00fe1a7f9a362e3eb001 (patch)
tree33546f9e230f8906a26c8af65d692e9f701d9d16 /lisp
parentb1235f9abd0f255ff65e13b18ef3ee4e19278484 (diff)
downloademacs-02bee7860f7e650ef13e00fe1a7f9a362e3eb001.tar.gz
emacs-02bee7860f7e650ef13e00fe1a7f9a362e3eb001.zip
Let dir locals for more specific modes override those from less
The list of dir local variables to apply is now sorted by the number of parent modes of the mode used as the key in the association list. That way when the variables are applied in order the variables from more specific modes will override those from less specific modes. If there are directory entries in the list then they are sorted in order of name length. The list of modes for that dir is then recursively sorted with the same mechanism. That way variables tied to a particular subdirectory override those in in a parent directory. Previously the behaviour didn’t seem to be well defined anyway and was dependent on the order they appeared in the file. However this order was changed in version 26.1 and it probably also depended on the number of dir-local files that are merged. Bug#33400 * lisp/files.el (dir-locals-get-sort-score, dir-locals-sort-variables) (dir-locals-read-from-dir): Sort the dir locals so that more precise modes and directory-specific entries have override lesser ones. * doc/emacs/custom.texi (Directory Variables): Document the priority.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/files.el47
1 files changed, 47 insertions, 0 deletions
diff --git a/lisp/files.el b/lisp/files.el
index d7ed2487862..f3b502095dd 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4026,6 +4026,52 @@ This function returns either:
4026 ;; No cache entry. 4026 ;; No cache entry.
4027 locals-dir))) 4027 locals-dir)))
4028 4028
4029(defun dir-locals--get-sort-score (node)
4030 "Return a number used for sorting the definitions of dir locals.
4031NODE is assumed to be a cons cell where the car is either a
4032string or a symbol representing a mode name.
4033
4034If it is a mode then the the depth of the mode (ie, how many
4035parents that mode has) will be returned.
4036
4037If it is a string then the length of the string plus 1000 will be
4038returned.
4039
4040Otherwise it returns -1.
4041
4042That way the value can be used to sort the list such that deeper
4043modes will be after the other modes. This will be followed by
4044directory entries in order of length. If the entries are all
4045applied in order then that means the more specific modes will
4046override the values specified by the earlier modes and directory
4047variables will override modes."
4048 (let ((key (car node)))
4049 (cond ((null key) -1)
4050 ((symbolp key)
4051 (let ((mode key)
4052 (depth 0))
4053 (while (setq mode (get mode 'derived-mode-parent))
4054 (setq depth (1+ depth)))
4055 depth))
4056 ((stringp key)
4057 (+ 1000 (length key)))
4058 (t -2))))
4059
4060(defun dir-locals--sort-variables (variables)
4061 "Sorts VARIABLES so that applying them in order has the right effect.
4062The variables are compared by dir-locals--get-sort-score.
4063Directory entries are then recursively sorted using the same
4064criteria."
4065 (setq variables (sort variables
4066 (lambda (a b)
4067 (< (dir-locals--get-sort-score a)
4068 (dir-locals--get-sort-score b)))))
4069 (dolist (n variables)
4070 (when (stringp (car n))
4071 (setcdr n (dir-locals--sort-variables (cdr n)))))
4072
4073 variables)
4074
4029(defun dir-locals-read-from-dir (dir) 4075(defun dir-locals-read-from-dir (dir)
4030 "Load all variables files in DIR and register a new class and instance. 4076 "Load all variables files in DIR and register a new class and instance.
4031DIR is the absolute name of a directory which must contain at 4077DIR is the absolute name of a directory which must contain at
@@ -4054,6 +4100,7 @@ Return the new class name, which is a symbol named DIR."
4054 (read (current-buffer)))) 4100 (read (current-buffer))))
4055 (end-of-file nil)))) 4101 (end-of-file nil))))
4056 (setq success latest)) 4102 (setq success latest))
4103 (setq variables (dir-locals--sort-variables variables))
4057 (dir-locals-set-class-variables class-name variables) 4104 (dir-locals-set-class-variables class-name variables)
4058 (dir-locals-set-directory-class dir class-name success) 4105 (dir-locals-set-directory-class dir class-name success)
4059 class-name)) 4106 class-name))