Finally, it specifies a different @file{ChangeLog} file name for any
file in the @file{src/imported} subdirectory.
+If the @file{.dir-locals.el} file contains multiple different values
+for a variable using different mode names or directories, the values
+will be applied in an order such that the values for more specific
+modes take priority over more generic modes. Values specified under a
+directory have even more priority. For example:
+
+@example
+((nil . ((fill-column . 40)))
+ (c-mode . ((fill-column . 50)))
+ (prog-mode . ((fill-column . 60)))
+ ("narrow-files" . ((nil . ((fill-column . 20))))))
+@end example
+
+Files that use @code{c-mode} also match @code{prog-mode} because the
+former inherits from the latter. The value used for
+@code{fill-column} in C files will however be @code{50} because the
+mode name is more specific than @code{prog-mode}. Files using other
+modes inheriting from @code{prog-mode} will use @code{60}. Any file
+under the directory @file{narrow-files} will use the value @code{20}
+even if they use @code{c-mode} because directory entries have priority
+over mode entries.
+
You can specify the variables @code{mode}, @code{eval}, and
@code{unibyte} in your @file{.dir-locals.el}, and they have the same
meanings as they would have in file local variables. @code{coding}
;; No cache entry.
locals-dir)))
+(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
(read (current-buffer))))
(end-of-file nil))))
(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))