;; No cache entry.
locals-dir)))
-override the values specified by the earlier modes and directory
+(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
(setq latest file-time)))
(with-temp-buffer
(insert-file-contents file)
- (condition-case-unless-debug nil
- (setq variables
+ (let ((newvars
+ (condition-case-unless-debug nil
+ ;; As a defensive measure, we do not allow
+ ;; circular data in the file/dir-local data.
+ (let ((read-circle nil))
+ (read (current-buffer)))
+ (end-of-file nil))))
+ (setq variables
+ ;; Try and avoid loading `map' since that also loads cl-lib
+ ;; which then might hamper bytecomp warnings (bug#30635).
+ (if (not (and newvars variables))
+ (or newvars variables)
+ (require 'map)
(map-merge-with 'list (lambda (a b) (map-merge 'list a b))
variables
- (read (current-buffer))))
- (end-of-file nil))))
+ 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))
(defcustom sgml-mode-hook nil
"Hook run by command `sgml-mode'.
`text-mode-hook' is run first."
- :group 'sgml
:type 'hook)
- ;; As long as Emacs's syntax can't be complemented with predicates to context
- ;; sensitively confirm the syntax of characters, we have to live with this
- ;; kludgy kind of tradeoff.
- (defvar sgml-specials '(?\")
+ ;; The official handling of "--" is complicated in SGML, and
+ ;; historically not well supported by browser HTML parsers.
+ ;; Recommendations for writing HTML comments is to use <!--...-->
+ ;; (where ... doesn't contain "--") to avoid the complications
+ ;; altogether (XML goes even further by requiring this in the spec).
+ ;; So there is probably no need to handle it "correctly".
+ (defvar sgml-specials '(?\" ?\')
"List of characters that have a special meaning for SGML mode.
This list is used when first loading the `sgml-mode' library.
- The supported characters and potential disadvantages are:
+ The supported characters are ?\\\", ?\\=', and ?-.
- ?\\\" Makes \" in text start a string.
- ?\\=' Makes \\=' in text start a string.
- ?- Makes -- in text start a comment.
-
- When only one of ?\\\" or ?\\=' are included, \"\\='\" or \\='\"\\=', as can be found in
- DTDs, start a string. To partially avoid this problem this also makes these
- self insert as named entities depending on `sgml-quick-keys'.
-
- Including ?- has the problem of affecting dashes that have nothing to do
- with comments, so we normally turn it off.")
+ Including ?- makes double dashes into comment delimiters, but
+ they are really only supposed to delimit comments within DTD
+ definitions. So we normally turn it off.")
(defvar sgml-quick-keys nil
"Use <, >, &, /, SPC and `sgml-specials' keys \"electrically\" when non-nil.