(format-message
"%s: `lexical-binding' at end of file unreliable"
(file-name-nondirectory
- (or buffer-file-name ""))))))
+ ;; We are called from
+ ;; 'with-temp-buffer', so we need
+ ;; to use 'thisbuf's name in the
+ ;; warning message.
+ (or (buffer-file-name thisbuf) ""))))))
(t
(ignore-errors
(push (cons (if (eq var 'eval)
applied by recursively following these rules."
(setf (alist-get class dir-locals-class-alist) variables))
-(defconst dir-locals-file ".dir-locals*.el"
- "Pattern for files that contain directory-local variables.
+(defconst dir-locals-file ".dir-locals.el"
+ "File that contains directory-local variables.
It has to be constant to enforce uniform values across different
environments and users.
+See also `dir-locals-file-2', whose values override this one's.
+See Info node `(elisp)Directory Local Variables' for details.")
-Multiple dir-locals files in the same directory are loaded in
-`string<' order.
+(defconst dir-locals-file-2 ".dir-locals-2.el"
+ "File that contains directory-local variables.
+This essentially a second file that can be used like
+`dir-locals-file', so that users can have specify their personal
+dir-local variables even if the current directory already has a
+`dir-locals-file' that is shared with other users (such as in a
+git repository).
See Info node `(elisp)Directory Local Variables' for details.")
-(defun dir-locals--all-files (file-or-dir)
- "Return a list of all readable dir-locals files matching FILE-OR-DIR.
-If FILE-OR-DIR is a file pattern, expand wildcards in it and
-return a sorted list of the results. If it is a directory name,
-return a sorted list of all files matching `dir-locals-file' in
-this directory.
-The returned list is sorted by `string<' order."
- (require 'seq)
- (let ((default-directory (if (file-directory-p file-or-dir)
- file-or-dir
- default-directory)))
- (seq-filter (lambda (f) (and (file-readable-p f)
- (file-regular-p f)))
- (file-expand-wildcards
- (cond ((not (file-directory-p file-or-dir)) file-or-dir)
- ((eq system-type 'ms-dos) (dosified-file-name dir-locals-file))
- (t dir-locals-file))
- 'full))))
+(defun dir-locals--all-files (directory)
+ "Return a list of all readable dir-locals files in DIRECTORY.
+The returned list is sorted by increasing priority. That is,
+values specified in the last file should take precedence over
+those in the first."
+ (when (file-readable-p directory)
+ (let* ((file-1 (expand-file-name (if (eq system-type 'ms-dos)
+ (dosified-file-name dir-locals-file)
+ dir-locals-file)
+ directory))
+ (file-2 (when (string-match "\\.el\\'" file-1)
+ (replace-match "-2.el" t nil file-1)))
+ (out nil))
+ ;; The order here is important.
+ (dolist (f (list file-2 file-1))
+ (when (and f
+ (file-readable-p f)
+ (file-regular-p f)
+ (not (file-directory-p f)))
+ (push f out)))
+ out)))
(defun dir-locals-find-file (file)
"Find the directory-local variables for FILE.
time stored in the cache matches the current file modification time.
If not, the cache entry is cleared so that the file will be re-read.
-This function returns either nil (no directory local variables found),
-or the matching entry from `dir-locals-directory-cache' (a list),
-or the full path to the `dir-locals-file' (a string) in the case
-of no valid cache entry. If `dir-locals-file' contains
-wildcards, then the return value is not a proper filename, it is
-an absolute version of `dir-locals-file' which is guaranteed to
-expand to at least one file."
+This function returns either:
+ - nil (no directory local variables found),
+ - the matching entry from `dir-locals-directory-cache' (a list),
+ - or the full path to the directory (a string) containing at
+ least one `dir-locals-file' in the case of no valid cache
+ entry."
(setq file (expand-file-name file))
(let* ((locals-dir (locate-dominating-file (file-name-directory file)
#'dir-locals--all-files))
- locals-file dir-elt)
+ dir-elt)
;; `locate-dominating-file' may have abbreviated the name.
(when locals-dir
- (setq locals-dir (expand-file-name locals-dir))
- (setq locals-file (expand-file-name (if (eq system-type 'ms-dos)
- (dosified-file-name dir-locals-file)
- dir-locals-file)
- locals-dir)))
+ (setq locals-dir (expand-file-name locals-dir)))
;; Find the best cached value in `dir-locals-directory-cache'.
(dolist (elt dir-locals-directory-cache)
(when (and (string-prefix-p (car elt) file
(delq dir-elt dir-locals-directory-cache))
;; Return the first existing dir-locals file. Might be the same
;; as dir-elt's, might not (eg latter might have been deleted).
- locals-file)
+ locals-dir)
;; No cache entry.
- locals-file)))
-
-(defun dir-locals-read-from-file (file)
- "Load a variables FILE and register a new class and instance.
-FILE is the absolute name of the file holding the variables to
-apply. It may contain wildcards.
-The new class name is the same as the directory in which FILE
-is found. Returns the new class name."
+ locals-dir)))
+
+(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."
(require 'map)
- (let* ((dir-name (file-name-directory file))
- (class-name (intern dir-name))
- (files (dir-locals--all-files file))
+ (let* ((class-name (intern dir))
+ (files (dir-locals--all-files dir))
(read-circle nil)
(success nil)
(variables))
(setq success t))
(dir-locals-set-class-variables class-name variables)
(dir-locals-set-directory-class
- dir-name class-name
+ dir class-name
(seconds-to-time
(if success
(apply #'max (mapcar (lambda (file)
0)))
class-name))
+(define-obsolete-function-alias 'dir-locals-read-from-file
+ 'dir-locals-read-from-dir "25.1")
+
(defcustom enable-remote-dir-locals nil
"Non-nil means dir-local variables will be applied to remote files."
:version "24.3"
(not (file-remote-p (or (buffer-file-name)
default-directory)))))
;; Find the variables file.
- (let ((file-pattern-or-cache (dir-locals-find-file
- (or (buffer-file-name) default-directory)))
+ (let ((dir-or-cache (dir-locals-find-file
+ (or (buffer-file-name) default-directory)))
(class nil)
(dir-name nil))
(cond
- ((stringp file-pattern-or-cache)
- (setq dir-name (file-name-directory file-pattern-or-cache)
- class (dir-locals-read-from-file file-pattern-or-cache)))
- ((consp file-pattern-or-cache)
- (setq dir-name (nth 0 file-pattern-or-cache))
- (setq class (nth 1 file-pattern-or-cache))))
+ ((stringp dir-or-cache)
+ (setq dir-name dir-or-cache
+ class (dir-locals-read-from-dir dir-or-cache)))
+ ((consp dir-or-cache)
+ (setq dir-name (nth 0 dir-or-cache))
+ (setq class (nth 1 dir-or-cache))))
(when class
(let ((variables
(dir-locals-collect-variables