.dir-locals.el 的一般格式如下所述:
要评估代码,您必须使用特殊的伪变量名称eval,如下所述:
例如:
((nil . ((indent-tabs-mode . t)
(eval . (eval-after-load "grep"
'(add-to-list 'grep-find-ignored-directories "blur")))
(fill-column . 80)))
(c-mode . ((c-file-style . "BSD")
(subdirs . nil))))
然而,grep-find-ignored-directories 不是一个自动缓冲区局部变量,我们在这里没有明确将其设置为目录局部变量(这里的“局部变量”是eval ),所以当grep-find-ignored-directories 以这种方式设置时,它是全局设置的,这肯定不是你想要的1。
你可以试试这样的:
((nil . ((eval . (eval-after-load "grep"
'(add-to-list
(make-local-variable 'grep-find-ignored-directories)
"blur"))))))
但实际上这仍然是错误的,因为一旦您访问了此目录下的文件,eval-after-load(这是一个全局设置)将在 grep 加载后立即触发,无论 您当时所在的缓冲区,因此您可以轻松地将您的“模糊”值本地添加到您调用 grep 的一些不需要的缓冲区中,同时也 未能为任何以前访问过的缓冲区。
最简单的解决办法大概是在设置变量之前强制要求grep:
((nil . ((eval . (progn
(require 'grep)
(add-to-list
(make-local-variable 'grep-find-ignored-directories)
"blur"))))))
这样可以确保目录下的所有文件都将获得本地值(而其他地方的文件则不会)。
现在,这是解决一般问题的一种方法,但看看这个特定的情况,C-hv grep-find-ignored-directories,这个变量提供了一些功能,可以使解决方案更简单,并且不需要不必要地加载 grep。
你的 .dir-locals.el 文件可以这样设置一个局部变量:
((nil . ((my-ignore-blur-p . t))))
在您的 .emacs 中,您可以执行以下操作:
(defun my-ignore-blur-p (dir)
"Return non-nil when the `my-ignore-blur-p' local variable is set."
(local-variable-if-set-p 'my-ignore-blur-p))
(eval-after-load "grep"
'(add-to-list 'grep-find-ignored-directories
(cons 'my-ignore-blur-p "blur")))
那么当你从任何设置了这个局部变量的缓冲区执行rgrep时,我们在全局grep-find-ignored-directories变量中指定的自定义函数将返回一个非nil的值,这会导致“模糊”被包含在被忽略的目录列表中。
(n.b. 我对函数和变量使用相同的名称,因为我可以 -- elisp 为变量和函数提供单独的名称空间 -- 但这不是必需的。为了清楚起见,我指的是 eval-after-load 代码中的函数,函数代码和.dir-locals.el 文件中的变量)。
或者您可以将my-ignore-blur-p 函数的行为基于dir 参数(即被搜索的目录),并完全忽略局部变量。这将使列表中包含或省略“模糊”的决定完全独立于您启动 rgrep 命令的缓冲区,这可能更可取。
1 如果在全局范围内向grep-find-ignored-directories 添加“模糊”,那么根本不要使用.dir-locals.el——只需添加您的@987654348 @调用你的 .emacs 文件。