Mercurial > emacs
comparison lisp/files.el @ 102935:f57e672f2ca5
* 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.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Sat, 11 Apr 2009 15:26:26 +0000 |
parents | fb16f3bdad15 |
children | 64ac89a8b9a8 |
comparison
equal
deleted
inserted
replaced
102934:ed0a00c1025a | 102935:f57e672f2ca5 |
---|---|
3183 (set (make-local-variable var) val)))) | 3183 (set (make-local-variable var) val)))) |
3184 | 3184 |
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." |
3195 (cdr (assq class dir-locals-class-alist))) | 3204 (cdr (assq class dir-locals-class-alist))) |
3196 | 3205 |
3228 ((or (not key) | 3237 ((or (not key) |
3229 (derived-mode-p key)) | 3238 (derived-mode-p key)) |
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. |
3248 CLASS is the project class, a symbol. VARIABLES is a list | 3259 CLASS is the project class, a symbol. VARIABLES is a list |
3249 that declares directory-local variables for the class. | 3260 that declares directory-local variables for the class. |
3282 "File that contains directory-local variables. | 3293 "File that contains directory-local variables. |
3283 It has to be constant to enforce uniform values | 3294 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) |
3296 (dosified-file-name dir-locals-file) | 3310 (dosified-file-name dir-locals-file) |
3297 dir-locals-file)) | 3311 dir-locals-file)) |
3298 (locals-file (locate-dominating-file file dir-locals-file-name)) | 3312 (locals-file (locate-dominating-file file dir-locals-file-name)) |
3299 (dir-elt nil)) | 3313 (dir-elt 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. |
3319 FILE is the name of the file holding the variables to apply. | 3345 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" ()) |
3334 | 3359 |
3335 (defun hack-dir-local-variables () | 3360 (defun hack-dir-local-variables () |
3346 (cond | 3371 (cond |
3347 ((stringp variables-file) | 3372 ((stringp variables-file) |
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 |
3356 (dir-locals-get-class-variables class) dir-name nil))) | 3381 (dir-locals-get-class-variables class) dir-name nil))) |
3357 (when variables | 3382 (when variables |