Function: hack-dir-local-variables
hack-dir-local-variables is a byte-compiled function defined in
files.el.gz.
Signature
(hack-dir-local-variables)
Documentation
Read per-directory local variables for the current buffer.
Store the directory-local variables in dir-local-variables-alist
and file-local-variables-alist, without applying them.
This does nothing if either enable-local-variables or
enable-dir-local-variables are nil.
Source Code
;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun hack-dir-local-variables ()
"Read per-directory local variables for the current buffer.
Store the directory-local variables in `dir-local-variables-alist'
and `file-local-variables-alist', without applying them.
This does nothing if either `enable-local-variables' or
`enable-dir-local-variables' are nil."
(let (items)
(when (and enable-local-variables
enable-dir-local-variables
(or enable-remote-dir-locals
(not (file-remote-p (or (buffer-file-name)
default-directory)))))
(run-hook-wrapped 'hack-dir-local-get-variables-functions
(lambda (fun)
(let ((res (funcall fun)))
(cond
((null res))
((consp (car-safe res))
(setq items (append res items)))
(t (push res items))))
nil)))
;; Sort the entries from nearest dir to furthest dir.
(setq items (sort (nreverse items)
:key (lambda (x) (length (car-safe x))) :reverse t))
;; Filter out duplicates, preferring the settings from the nearest dir
;; and from the first hook function.
(let ((seen nil))
(dolist (item items)
(when seen ;; Special case seen=nil since it's the most common case.
(setcdr item (seq-filter (lambda (vv) (not (memq (car-safe vv) seen)))
(cdr item))))
(setq seen (nconc (seq-difference (mapcar #'car (cdr item))
'(eval mode))
seen))))
;; Rather than a loop, maybe we should handle all the dirs
;; "together", e.g. prompting the user only once. But if so, we'd
;; probably want to also merge the prompt for file-local vars,
;; which comes from the call to `hack-local-variables-filter' in
;; `hack-local-variables'.
(dolist (item items)
(let ((dir-name (car item))
(variables (cdr item)))
(when variables
(dolist (elt variables)
(if (eq (car elt) 'coding)
(unless hack-dir-local-variables--warned-coding
(setq hack-dir-local-variables--warned-coding t)
(display-warning 'files
"Coding cannot be specified by dir-locals"))
(unless (memq (car elt) '(eval mode))
(setq dir-local-variables-alist
(assq-delete-all (car elt) dir-local-variables-alist)))
(push elt dir-local-variables-alist)))
(hack-local-variables-filter variables dir-name))))))