Function: dir-locals-collect-variables
dir-locals-collect-variables is a byte-compiled function defined in
files.el.gz.
Signature
(dir-locals-collect-variables CLASS-VARIABLES ROOT VARIABLES &optional PREDICATE)
Documentation
Collect entries from CLASS-VARIABLES into VARIABLES.
ROOT is the root directory of the project. Return the new variables list. If PREDICATE is given, it is used to test a symbol key in the alist to see whether it should be considered.
Source Code
;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun dir-locals-collect-variables (class-variables root variables
&optional predicate)
"Collect entries from CLASS-VARIABLES into VARIABLES.
ROOT is the root directory of the project.
Return the new variables list.
If PREDICATE is given, it is used to test a symbol key in the alist
to see whether it should be considered."
(let* ((file-name (or (buffer-file-name)
;; Handle non-file buffers, too.
(expand-file-name default-directory)))
(sub-file-name (if (and file-name
(file-name-absolute-p file-name))
;; FIXME: Why not use file-relative-name?
(substring file-name (length root)))))
(condition-case err
(dolist (entry class-variables variables)
(let ((key (car entry)))
(cond
((stringp key)
;; Don't include this in the previous condition, because we
;; want to filter all strings before the next condition.
(when (and sub-file-name
(>= (length sub-file-name) (length key))
(string-prefix-p key sub-file-name))
(setq variables (dir-locals-collect-variables
(cdr entry) root variables predicate))))
((if predicate
(funcall predicate key)
(or (not key)
(derived-mode-p key)))
;; If KEY is an extra parent it may remain not loaded
;; (hence with some of its mode-specific vars missing their
;; `safe-local-variable' property), leading to spurious
;; prompts about unsafe vars (bug#68246).
(if (and (symbolp key) (autoloadp (indirect-function key)))
(ignore-errors (autoload-do-load (indirect-function key))))
(let* ((alist (cdr entry))
(subdirs (assq 'subdirs alist)))
(if (or (not subdirs)
(progn
(setq alist (remq subdirs alist))
(cdr-safe subdirs))
;; TODO someone might want to extend this to allow
;; integer values for subdir, where N means
;; variables apply to this directory and N levels
;; below it (0 == nil).
(equal root (expand-file-name default-directory)))
(setq variables (dir-locals-collect-mode-variables
alist variables))))))))
(error
;; The file's content might be invalid (e.g. have a merge conflict), but
;; that shouldn't prevent the user from opening the file.
(message "%s error: %s" dir-locals-file (error-message-string err))
nil))))