aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Morris2011-02-23 23:47:06 -0800
committerGlenn Morris2011-02-23 23:47:06 -0800
commitebe401f69718e17144fc7f7a8ab36f7c12452f2a (patch)
treeab63b751d0a36e636a21ee113818df8a5fb8fe90
parenta22e7484fa1e26e3caf2658c91d5e245169b55a1 (diff)
downloademacs-ebe401f69718e17144fc7f7a8ab36f7c12452f2a.tar.gz
emacs-ebe401f69718e17144fc7f7a8ab36f7c12452f2a.zip
Partial fix for bug#8095.
* lisp/files.el (dir-locals-find-file): Doc fix. Fix the check for cache elements that have no associated file, and the mtime check for those that do. Still to do: some places that use dir-locals-find-file assume the result is always a file, which is not true. (The function name is misleading.)
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/files.el77
2 files changed, 51 insertions, 30 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 6ce81a9214a..d77e6b7ccd8 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,9 @@
12011-02-24 Glenn Morris <rgm@gnu.org> 12011-02-24 Glenn Morris <rgm@gnu.org>
2 2
3 * files.el (dir-locals-find-file): Doc fix.
4 Fix the check for cache elements that have no associated file,
5 and the mtime check for those that do.
6
3 * dired-x.el (dired-hack-local-variables): 7 * dired-x.el (dired-hack-local-variables):
4 Handle interrupts during hacking local variables. (Bug#5216) 8 Handle interrupts during hacking local variables. (Bug#5216)
5 9
diff --git a/lisp/files.el b/lisp/files.el
index 3409ebe02e1..e4cc782b1d1 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3347,11 +3347,11 @@ Each element in this list has the form (DIR CLASS MTIME).
3347DIR is the name of the directory. 3347DIR is the name of the directory.
3348CLASS is the name of a variable class (a symbol). 3348CLASS is the name of a variable class (a symbol).
3349MTIME is the recorded modification time of the directory-local 3349MTIME is the recorded modification time of the directory-local
3350 variables file associated with this entry. This time is a list 3350variables file associated with this entry. This time is a list
3351 of two integers (the same format as `file-attributes'), and is 3351of two integers (the same format as `file-attributes'), and is
3352 used to test whether the cache entry is still valid. 3352used to test whether the cache entry is still valid.
3353 Alternatively, MTIME can be nil, which means the entry is always 3353Alternatively, MTIME can be nil, which means the entry is always
3354 considered valid.") 3354considered valid.")
3355 3355
3356(defsubst dir-locals-get-class-variables (class) 3356(defsubst dir-locals-get-class-variables (class)
3357 "Return the variable list for CLASS." 3357 "Return the variable list for CLASS."
@@ -3460,13 +3460,20 @@ across different environments and users.")
3460(defun dir-locals-find-file (file) 3460(defun dir-locals-find-file (file)
3461 "Find the directory-local variables for FILE. 3461 "Find the directory-local variables for FILE.
3462This searches upward in the directory tree from FILE. 3462This searches upward in the directory tree from FILE.
3463If the directory root of FILE has been registered in 3463It stops at the first directory that has been registered in
3464 `dir-locals-directory-cache' and the directory-local variables 3464`dir-locals-directory-cache' or contains a `dir-locals-file'.
3465 file has not been modified, return the matching entry in 3465If it finds an entry in the cache, it checks that it is valid.
3466 `dir-locals-directory-cache'. 3466A cache entry with no modification time element (normally, one that
3467Otherwise, if a directory-local variables file is found, return 3467has been assigned directly using `dir-locals-set-directory-class', not
3468 the file name. 3468set from a file) is always valid.
3469Otherwise, return nil." 3469A cache entry based on a `dir-locals-file' is valid if the modification
3470time stored in the cache matches the current file modification time.
3471If not, the cache entry is cleared so that the file will be re-read.
3472
3473This function returns either nil (no directory local variables found),
3474or the matching entry from `dir-locals-directory-cache' (a list),
3475or the full path to the `dir-locals-file' (a string) in the case
3476of no valid cache entry."
3470 (setq file (expand-file-name file)) 3477 (setq file (expand-file-name file))
3471 (let* ((dir-locals-file-name 3478 (let* ((dir-locals-file-name
3472 (if (eq system-type 'ms-dos) 3479 (if (eq system-type 'ms-dos)
@@ -3475,8 +3482,8 @@ Otherwise, return nil."
3475 (locals-file (locate-dominating-file file dir-locals-file-name)) 3482 (locals-file (locate-dominating-file file dir-locals-file-name))
3476 (dir-elt nil)) 3483 (dir-elt nil))
3477 ;; `locate-dominating-file' may have abbreviated the name. 3484 ;; `locate-dominating-file' may have abbreviated the name.
3478 (when locals-file 3485 (if locals-file
3479 (setq locals-file (expand-file-name dir-locals-file-name locals-file))) 3486 (setq locals-file (expand-file-name dir-locals-file-name locals-file)))
3480 ;; Find the best cached value in `dir-locals-directory-cache'. 3487 ;; Find the best cached value in `dir-locals-directory-cache'.
3481 (dolist (elt dir-locals-directory-cache) 3488 (dolist (elt dir-locals-directory-cache)
3482 (when (and (eq t (compare-strings file nil (length (car elt)) 3489 (when (and (eq t (compare-strings file nil (length (car elt))
@@ -3485,23 +3492,32 @@ Otherwise, return nil."
3485 '(windows-nt cygwin ms-dos)))) 3492 '(windows-nt cygwin ms-dos))))
3486 (> (length (car elt)) (length (car dir-elt)))) 3493 (> (length (car elt)) (length (car dir-elt))))
3487 (setq dir-elt elt))) 3494 (setq dir-elt elt)))
3488 (let ((use-cache (and dir-elt 3495 (if (and dir-elt
3489 (or (null locals-file) 3496 (or (null locals-file)
3490 (<= (length (file-name-directory locals-file)) 3497 (<= (length (file-name-directory locals-file))
3491 (length (car dir-elt))))))) 3498 (length (car dir-elt)))))
3492 (if use-cache 3499 ;; Found a potential cache entry. Check validity.
3493 ;; Check the validity of the cache. 3500 ;; A cache entry with no MTIME is assumed to always be valid
3494 (if (and (file-readable-p (car dir-elt)) 3501 ;; (ie, set directly, not from a dir-locals file).
3495 (or (null (nth 2 dir-elt)) 3502 ;; Note, we don't bother to check that there is a matching class
3503 ;; element in dir-locals-class-alist, since that's done by
3504 ;; dir-locals-set-directory-class.
3505 (if (or (null (nth 2 dir-elt))
3506 (let ((cached-file (expand-file-name dir-locals-file-name
3507 (car dir-elt))))
3508 (and (file-readable-p cached-file)
3496 (equal (nth 2 dir-elt) 3509 (equal (nth 2 dir-elt)
3497 (nth 5 (file-attributes (car dir-elt)))))) 3510 (nth 5 (file-attributes cached-file))))))
3498 ;; This cache entry is OK. 3511 ;; This cache entry is OK.
3499 dir-elt 3512 dir-elt
3500 ;; This cache entry is invalid; clear it. 3513 ;; This cache entry is invalid; clear it.
3501 (setq dir-locals-directory-cache 3514 (setq dir-locals-directory-cache
3502 (delq dir-elt dir-locals-directory-cache)) 3515 (delq dir-elt dir-locals-directory-cache))
3503 locals-file) 3516 ;; Return the first existing dir-locals file. Might be the same
3504 locals-file)))) 3517 ;; as dir-elt's, might not (eg latter might have been deleted).
3518 locals-file)
3519 ;; No cache entry.
3520 locals-file)))
3505 3521
3506(defun dir-locals-read-from-file (file) 3522(defun dir-locals-read-from-file (file)
3507 "Load a variables FILE and register a new class and instance. 3523 "Load a variables FILE and register a new class and instance.
@@ -3531,6 +3547,7 @@ and `file-local-variables-alist', without applying them."
3531 (dir-name nil)) 3547 (dir-name nil))
3532 (cond 3548 (cond
3533 ((stringp variables-file) 3549 ((stringp variables-file)
3550 ;; FIXME seems like the wrong dir-name.
3534 (setq dir-name (if (buffer-file-name) 3551 (setq dir-name (if (buffer-file-name)
3535 (file-name-directory (buffer-file-name)) 3552 (file-name-directory (buffer-file-name))
3536 default-directory)) 3553 default-directory))