diff options
Diffstat (limited to 'lisp/files.el')
-rw-r--r-- | lisp/files.el | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/lisp/files.el b/lisp/files.el index 8477c227bcc..8fa7f16de01 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4110,6 +4110,52 @@ This function returns either: (declare-function map-merge-with "map" (type function &rest maps)) (declare-function map-merge "map" (type &rest maps)) +(defun dir-locals--get-sort-score (node) + "Return a number used for sorting the definitions of dir locals. +NODE is assumed to be a cons cell where the car is either a +string or a symbol representing a mode name. + +If it is a mode then the the depth of the mode (ie, how many +parents that mode has) will be returned. + +If it is a string then the length of the string plus 1000 will be +returned. + +Otherwise it returns -1. + +That way the value can be used to sort the list such that deeper +modes will be after the other modes. This will be followed by +directory entries in order of length. If the entries are all +applied in order then that means the more specific modes will + override the values specified by the earlier modes and directory +variables will override modes." + (let ((key (car node))) + (cond ((null key) -1) + ((symbolp key) + (let ((mode key) + (depth 0)) + (while (setq mode (get mode 'derived-mode-parent)) + (setq depth (1+ depth))) + depth)) + ((stringp key) + (+ 1000 (length key))) + (t -2)))) + +(defun dir-locals--sort-variables (variables) + "Sorts VARIABLES so that applying them in order has the right effect. +The variables are compared by dir-locals--get-sort-score. +Directory entries are then recursively sorted using the same +criteria." + (setq variables (sort variables + (lambda (a b) + (< (dir-locals--get-sort-score a) + (dir-locals--get-sort-score b))))) + (dolist (n variables) + (when (stringp (car n)) + (setcdr n (dir-locals--sort-variables (cdr n))))) + + variables) + (defun dir-locals-read-from-dir (dir) "Load all variables files in DIR and register a new class and instance. DIR is the absolute name of a directory which must contain at @@ -4147,6 +4193,7 @@ Return the new class name, which is a symbol named DIR." variables newvars)))))) (setq success latest)) + (setq variables (dir-locals--sort-variables variables)) (dir-locals-set-class-variables class-name variables) (dir-locals-set-directory-class dir class-name success) class-name)) |