diff options
| author | Glenn Morris | 2011-02-23 23:47:06 -0800 |
|---|---|---|
| committer | Glenn Morris | 2011-02-23 23:47:06 -0800 |
| commit | ebe401f69718e17144fc7f7a8ab36f7c12452f2a (patch) | |
| tree | ab63b751d0a36e636a21ee113818df8a5fb8fe90 | |
| parent | a22e7484fa1e26e3caf2658c91d5e245169b55a1 (diff) | |
| download | emacs-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/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/files.el | 77 |
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 @@ | |||
| 1 | 2011-02-24 Glenn Morris <rgm@gnu.org> | 1 | 2011-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). | |||
| 3347 | DIR is the name of the directory. | 3347 | DIR is the name of the directory. |
| 3348 | CLASS is the name of a variable class (a symbol). | 3348 | CLASS is the name of a variable class (a symbol). |
| 3349 | MTIME is the recorded modification time of the directory-local | 3349 | MTIME is the recorded modification time of the directory-local |
| 3350 | variables file associated with this entry. This time is a list | 3350 | variables file associated with this entry. This time is a list |
| 3351 | of two integers (the same format as `file-attributes'), and is | 3351 | of two integers (the same format as `file-attributes'), and is |
| 3352 | used to test whether the cache entry is still valid. | 3352 | used to test whether the cache entry is still valid. |
| 3353 | Alternatively, MTIME can be nil, which means the entry is always | 3353 | Alternatively, MTIME can be nil, which means the entry is always |
| 3354 | considered valid.") | 3354 | considered 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. |
| 3462 | This searches upward in the directory tree from FILE. | 3462 | This searches upward in the directory tree from FILE. |
| 3463 | If the directory root of FILE has been registered in | 3463 | It 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 | 3465 | If it finds an entry in the cache, it checks that it is valid. |
| 3466 | `dir-locals-directory-cache'. | 3466 | A cache entry with no modification time element (normally, one that |
| 3467 | Otherwise, if a directory-local variables file is found, return | 3467 | has been assigned directly using `dir-locals-set-directory-class', not |
| 3468 | the file name. | 3468 | set from a file) is always valid. |
| 3469 | Otherwise, return nil." | 3469 | A cache entry based on a `dir-locals-file' is valid if the modification |
| 3470 | time stored in the cache matches the current file modification time. | ||
| 3471 | If not, the cache entry is cleared so that the file will be re-read. | ||
| 3472 | |||
| 3473 | This function returns either nil (no directory local variables found), | ||
| 3474 | or the matching entry from `dir-locals-directory-cache' (a list), | ||
| 3475 | or the full path to the `dir-locals-file' (a string) in the case | ||
| 3476 | of 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)) |