diff options
| author | Chong Yidong | 2009-04-11 15:26:26 +0000 |
|---|---|---|
| committer | Chong Yidong | 2009-04-11 15:26:26 +0000 |
| commit | 25760acbb959a2c852d18746b9cde77db5227d0d (patch) | |
| tree | 508f9057a5093d26d0081c2be09739414908bc69 | |
| parent | 9291a2d6ae06ca63cf8b17bc124b5dccd0f0b3ab (diff) | |
| download | emacs-25760acbb959a2c852d18746b9cde77db5227d0d.tar.gz emacs-25760acbb959a2c852d18746b9cde77db5227d0d.zip | |
* files.el (dir-locals-directory-cache): Change format to include
the mtime of the directory-local variables file (Bug#2833).
(dir-locals-set-directory-class): New arg mtime. Store it in
dir-locals-directory-cache.
(dir-locals-find-file): Check cache validity using the mtime.
(dir-locals-read-from-file): Save the file mtime in the cache.
(hack-dir-local-variables): Adapt to new
dir-locals-directory-cache entry format.
| -rw-r--r-- | lisp/ChangeLog | 9 | ||||
| -rw-r--r-- | lisp/files.el | 75 |
2 files changed, 59 insertions, 25 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1162741502d..139b3f299c0 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,14 @@ | |||
| 1 | 2009-04-11 Chong Yidong <cyd@stupidchicken.com> | 1 | 2009-04-11 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 2 | ||
| 3 | * files.el (dir-locals-directory-cache): Change format to include | ||
| 4 | the mtime of the directory-local variables file (Bug#2833). | ||
| 5 | (dir-locals-set-directory-class): New arg mtime. Store it in | ||
| 6 | dir-locals-directory-cache. | ||
| 7 | (dir-locals-find-file): Check cache validity using the mtime. | ||
| 8 | (dir-locals-read-from-file): Save the file mtime in the cache. | ||
| 9 | (hack-dir-local-variables): Adapt to new | ||
| 10 | dir-locals-directory-cache entry format. | ||
| 11 | |||
| 3 | * international/mule-diag.el (describe-font-internal): Change | 12 | * international/mule-diag.el (describe-font-internal): Change |
| 4 | ignored argument to IGNORED. | 13 | ignored argument to IGNORED. |
| 5 | (describe-font): Elide unnecessary argument to | 14 | (describe-font): Elide unnecessary argument to |
diff --git a/lisp/files.el b/lisp/files.el index 499948c4176..878f8a3e333 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -3185,10 +3185,19 @@ already the major mode." | |||
| 3185 | ;;; Handling directory-local variables, aka project settings. | 3185 | ;;; Handling directory-local variables, aka project settings. |
| 3186 | 3186 | ||
| 3187 | (defvar dir-locals-class-alist '() | 3187 | (defvar dir-locals-class-alist '() |
| 3188 | "Alist mapping class names (symbols) to variable lists.") | 3188 | "Alist mapping directory-local variable classes (symbols) to variable lists.") |
| 3189 | 3189 | ||
| 3190 | (defvar dir-locals-directory-alist '() | 3190 | (defvar dir-locals-directory-cache '() |
| 3191 | "Alist mapping directory roots to variable classes.") | 3191 | "List of cached directory roots for directory-local variable classes. |
| 3192 | Each element in this list has the form (DIR CLASS MTIME). | ||
| 3193 | DIR is the name of the directory. | ||
| 3194 | CLASS is the name of a variable class (a symbol). | ||
| 3195 | MTIME is the recorded modification time of the directory-local | ||
| 3196 | variables file associated with this entry. This time is a list | ||
| 3197 | of two integers (the same format as `file-attributes'), and is | ||
| 3198 | used to test whether the cache entry is still valid. | ||
| 3199 | Alternatively, MTIME can be nil, which means the entry is always | ||
| 3200 | considered valid.") | ||
| 3192 | 3201 | ||
| 3193 | (defsubst dir-locals-get-class-variables (class) | 3202 | (defsubst dir-locals-get-class-variables (class) |
| 3194 | "Return the variable list for CLASS." | 3203 | "Return the variable list for CLASS." |
| @@ -3230,18 +3239,20 @@ Return the new variables list." | |||
| 3230 | (setq variables (dir-locals-collect-mode-variables | 3239 | (setq variables (dir-locals-collect-mode-variables |
| 3231 | (cdr entry) variables)))))))) | 3240 | (cdr entry) variables)))))))) |
| 3232 | 3241 | ||
| 3233 | (defun dir-locals-set-directory-class (directory class) | 3242 | (defun dir-locals-set-directory-class (directory class mtime) |
| 3234 | "Declare that the DIRECTORY root is an instance of CLASS. | 3243 | "Declare that the DIRECTORY root is an instance of CLASS. |
| 3235 | DIRECTORY is the name of a directory, a string. | 3244 | DIRECTORY is the name of a directory, a string. |
| 3236 | CLASS is the name of a project class, a symbol. | 3245 | CLASS is the name of a project class, a symbol. |
| 3246 | MTIME is either the modification time of the directory-local | ||
| 3247 | variables file that defined this this class, or nil. | ||
| 3237 | 3248 | ||
| 3238 | When a file beneath DIRECTORY is visited, the mode-specific | 3249 | When a file beneath DIRECTORY is visited, the mode-specific |
| 3239 | variables from CLASS will be applied to the buffer. The variables | 3250 | variables from CLASS are applied to the buffer. The variables |
| 3240 | for a class are defined using `dir-locals-set-class-variables'." | 3251 | for a class are defined using `dir-locals-set-class-variables'." |
| 3241 | (setq directory (file-name-as-directory (expand-file-name directory))) | 3252 | (setq directory (file-name-as-directory (expand-file-name directory))) |
| 3242 | (unless (assq class dir-locals-class-alist) | 3253 | (unless (assq class dir-locals-class-alist) |
| 3243 | (error "No such class `%s'" (symbol-name class))) | 3254 | (error "No such class `%s'" (symbol-name class))) |
| 3244 | (push (cons directory class) dir-locals-directory-alist)) | 3255 | (push (list directory class mtime) dir-locals-directory-cache)) |
| 3245 | 3256 | ||
| 3246 | (defun dir-locals-set-class-variables (class variables) | 3257 | (defun dir-locals-set-class-variables (class variables) |
| 3247 | "Map the type CLASS to a list of variable settings. | 3258 | "Map the type CLASS to a list of variable settings. |
| @@ -3284,12 +3295,15 @@ It has to be constant to enforce uniform values | |||
| 3284 | across different environments and users.") | 3295 | across different environments and users.") |
| 3285 | 3296 | ||
| 3286 | (defun dir-locals-find-file (file) | 3297 | (defun dir-locals-find-file (file) |
| 3287 | "Find the directory-local variables FILE. | 3298 | "Find the directory-local variables for FILE. |
| 3288 | This searches upward in the directory tree. | 3299 | This searches upward in the directory tree from FILE. |
| 3289 | If a local variables file is found, the file name is returned. | 3300 | If the directory root of FILE has been registered in |
| 3290 | If the file is already registered, a cons from | 3301 | `dir-locals-directory-cache' and the directory-local variables |
| 3291 | `dir-locals-directory-alist' is returned. | 3302 | file has not been modified, return the matching entry in |
| 3292 | Otherwise this returns nil." | 3303 | `dir-locals-directory-cache'. |
| 3304 | Otherwise, if a directory-local variables file is found, return | ||
| 3305 | the file name. | ||
| 3306 | Otherwise, return nil." | ||
| 3293 | (setq file (expand-file-name file)) | 3307 | (setq file (expand-file-name file)) |
| 3294 | (let* ((dir-locals-file-name | 3308 | (let* ((dir-locals-file-name |
| 3295 | (if (eq system-type 'ms-dos) | 3309 | (if (eq system-type 'ms-dos) |
| @@ -3300,19 +3314,31 @@ Otherwise this returns nil." | |||
| 3300 | ;; `locate-dominating-file' may have abbreviated the name. | 3314 | ;; `locate-dominating-file' may have abbreviated the name. |
| 3301 | (when locals-file | 3315 | (when locals-file |
| 3302 | (setq locals-file (expand-file-name dir-locals-file-name locals-file))) | 3316 | (setq locals-file (expand-file-name dir-locals-file-name locals-file))) |
| 3303 | (dolist (elt dir-locals-directory-alist) | 3317 | ;; Find the best cached value in `dir-locals-directory-cache'. |
| 3318 | (dolist (elt dir-locals-directory-cache) | ||
| 3304 | (when (and (eq t (compare-strings file nil (length (car elt)) | 3319 | (when (and (eq t (compare-strings file nil (length (car elt)) |
| 3305 | (car elt) nil nil | 3320 | (car elt) nil nil |
| 3306 | (memq system-type | 3321 | (memq system-type |
| 3307 | '(windows-nt cygwin ms-dos)))) | 3322 | '(windows-nt cygwin ms-dos)))) |
| 3308 | (> (length (car elt)) (length (car dir-elt)))) | 3323 | (> (length (car elt)) (length (car dir-elt)))) |
| 3309 | (setq dir-elt elt))) | 3324 | (setq dir-elt elt))) |
| 3310 | (if (and locals-file dir-elt) | 3325 | (let ((use-cache (and dir-elt |
| 3311 | (if (> (length (file-name-directory locals-file)) | 3326 | (or (null locals-file) |
| 3312 | (length (car dir-elt))) | 3327 | (<= (length (file-name-directory locals-file)) |
| 3313 | locals-file | 3328 | (length (car dir-elt))))))) |
| 3314 | dir-elt) | 3329 | (if use-cache |
| 3315 | (or locals-file dir-elt)))) | 3330 | ;; Check the validity of the cache. |
| 3331 | (if (and (file-readable-p (car dir-elt)) | ||
| 3332 | (or (null (nth 2 dir-elt)) | ||
| 3333 | (equal (nth 2 dir-elt) | ||
| 3334 | (nth 5 (file-attributes (car dir-elt)))))) | ||
| 3335 | ;; This cache entry is OK. | ||
| 3336 | dir-elt | ||
| 3337 | ;; This cache entry is invalid; clear it. | ||
| 3338 | (setq dir-locals-directory-cache | ||
| 3339 | (delq dir-elt dir-locals-directory-cache)) | ||
| 3340 | locals-file) | ||
| 3341 | locals-file)))) | ||
| 3316 | 3342 | ||
| 3317 | (defun dir-locals-read-from-file (file) | 3343 | (defun dir-locals-read-from-file (file) |
| 3318 | "Load a variables FILE and register a new class and instance. | 3344 | "Load a variables FILE and register a new class and instance. |
| @@ -3320,14 +3346,13 @@ FILE is the name of the file holding the variables to apply. | |||
| 3320 | The new class name is the same as the directory in which FILE | 3346 | The new class name is the same as the directory in which FILE |
| 3321 | is found. Returns the new class name." | 3347 | is found. Returns the new class name." |
| 3322 | (with-temp-buffer | 3348 | (with-temp-buffer |
| 3323 | ;; We should probably store the modtime of FILE and then | ||
| 3324 | ;; reload it whenever it changes. | ||
| 3325 | (insert-file-contents file) | 3349 | (insert-file-contents file) |
| 3326 | (let* ((dir-name (file-name-directory file)) | 3350 | (let* ((dir-name (file-name-directory file)) |
| 3327 | (class-name (intern dir-name)) | 3351 | (class-name (intern dir-name)) |
| 3328 | (variables (read (current-buffer)))) | 3352 | (variables (read (current-buffer)))) |
| 3329 | (dir-locals-set-class-variables class-name variables) | 3353 | (dir-locals-set-class-variables class-name variables) |
| 3330 | (dir-locals-set-directory-class dir-name class-name) | 3354 | (dir-locals-set-directory-class dir-name class-name |
| 3355 | (nth 5 (file-attributes file))) | ||
| 3331 | class-name))) | 3356 | class-name))) |
| 3332 | 3357 | ||
| 3333 | (declare-function c-postprocess-file-styles "cc-mode" ()) | 3358 | (declare-function c-postprocess-file-styles "cc-mode" ()) |
| @@ -3348,8 +3373,8 @@ without applying them." | |||
| 3348 | (setq dir-name (file-name-directory (buffer-file-name))) | 3373 | (setq dir-name (file-name-directory (buffer-file-name))) |
| 3349 | (setq class (dir-locals-read-from-file variables-file))) | 3374 | (setq class (dir-locals-read-from-file variables-file))) |
| 3350 | ((consp variables-file) | 3375 | ((consp variables-file) |
| 3351 | (setq dir-name (car variables-file)) | 3376 | (setq dir-name (nth 0 variables-file)) |
| 3352 | (setq class (cdr variables-file)))) | 3377 | (setq class (nth 1 variables-file)))) |
| 3353 | (when class | 3378 | (when class |
| 3354 | (let ((variables | 3379 | (let ((variables |
| 3355 | (dir-locals-collect-variables | 3380 | (dir-locals-collect-variables |