Function: dir-locals-read-from-dir

dir-locals-read-from-dir is a byte-compiled function defined in files.el.gz.

Signature

(dir-locals-read-from-dir DIR)

Documentation

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 least one dir-local file (which is a file holding variables to apply). Return the new class name, which is a symbol named DIR.

Aliases

dir-locals-read-from-file (obsolete since 25.1)

Source Code

;; Defined in /usr/src/emacs/lisp/files.el.gz
(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
least one dir-local file (which is a file holding variables to
apply).
Return the new class name, which is a symbol named DIR."
  (let* ((class-name (intern dir))
         (files (dir-locals--all-files dir))
	 ;; If there was a problem, use the values we could get but
	 ;; don't let the cache prevent future reads.
	 (latest 0) (success 0)
         (variables))
    (with-demoted-errors "Error reading dir-locals: %S"
      (dolist (file files)
	(let ((file-time (file-attribute-modification-time
			  (file-attributes file))))
	  (if (time-less-p latest file-time)
	    (setq latest file-time)))
        (with-temp-buffer
          (insert-file-contents file)
          (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))))
            (unless (listp newvars)
              (message "Invalid data in %s: %s" file newvars)
              (setq newvars 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)
                    ;; We want to make the variable setting from
                    ;; newvars (the second .dir-locals file) take
                    ;; presedence over the old variables, but we also
                    ;; want to preserve all `eval' elements as is from
                    ;; both lists.
                    (map-merge-with
                     'list
                     (lambda (a b)
                       (let ((ag
                              (seq-group-by
                               (lambda (e) (eq (car e) 'eval)) a))
                             (bg
                              (seq-group-by
                               (lambda (e) (eq (car e) 'eval)) b)))
                         (append (map-merge 'list
                                            (assoc-default nil ag)
                                            (assoc-default nil bg))
                                 (assoc-default t ag)
                                 (assoc-default t bg))))
                     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))