Đây là một cách khác nhau để làm điều này.
Tôi định nghĩa một hàm tạo ra danh sách tất cả các thư mục trong hệ thống phân cấp thư mục hiện tại.
(defun file-name-directory-nesting-helper (name previous-name accumulator)
(if (string= name previous-name)
accumulator ; stop when names stop changing (at the top)
(file-name-directory-nesting-helper
(directory-file-name (file-name-directory name))
name
(cons name accumulator))))
(defun file-name-directory-nesting (name)
(file-name-directory-nesting-helper (expand-file-name name) "" ()))
Một ví dụ là theo thứ tự:
(file-name-directory-nesting "/foo/bar/baz/quux/foo.el")
;; => ("/" "/foo" "/foo/bar" "/foo/bar/baz" "/foo/bar/baz/quux" "/foo/bar/baz/quux/foo.el")
Bây giờ tôi có thể thêm lời khuyên để hack-dir-local-variables
làm cho nó "giả vờ" rằng chúng tôi đang truy cập một tệp ở đầu cây, áp dụng cài đặt thư mục cục bộ, sau đó bước xuống một cấp, áp dụng lại cài đặt, v.v.
(defun hack-dir-local-variables-chained-advice (orig)
"Apply dir-local settings from the whole directory hierarchy,
from the top down."
(let ((original-buffer-file-name (buffer-file-name))
(nesting (file-name-directory-nesting (or (buffer-file-name)
default-directory))))
(unwind-protect
(dolist (name nesting)
;; make it look like we're in a directory higher up in the
;; hierarchy; note that the file we're "visiting" does not
;; have to exist
(setq buffer-file-name (expand-file-name "ignored" name))
(funcall orig))
;; cleanup
(setq buffer-file-name original-buffer-file-name))))
(advice-add 'hack-dir-local-variables :around
#'hack-dir-local-variables-chained-advice)
.dir-locals
? .