错误的类型参数:listp,.dir-locals.el中的eval-after-load

mca*_*dre 4 emacs eval-after-load

我正在写第一篇.dir-locals.el,我收到了错误*Messages*.

码:

(eval-after-load "grep"
  '(add-to-list 'grep-find-ignored-directories "blur"))
Run Code Online (Sandbox Code Playgroud)

跟踪:

.dir-locals error: Wrong type argument: listp, eval-after-load
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

phi*_*ils 8

.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))))
Run Code Online (Sandbox Code Playgroud)

但是,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"))))))
Run Code Online (Sandbox Code Playgroud)

但实际上这仍然是错误的,因为一旦你访问了这个目录下的文件,那么一旦加载eval-after-load就会触发(这是一个全局设置)grep,无论你当时在哪个缓冲区,所以你可以很容易在您调用grep的某个不需要的缓冲区中本地添加"blur"值,同时也无法将其添加到您想要的任何以前访问过的缓冲区中.

最简单的解决方案可能是在设置变量之前强制要求grep:

((nil . ((eval . (progn
                   (require 'grep)
                   (add-to-list 
                    (make-local-variable 'grep-find-ignored-directories)
                    "blur"))))))
Run Code Online (Sandbox Code Playgroud)

这确保了目录下的所有文件都将获得本地值(并且其他文件不会).

现在,这是解决一般问题的一种方法,但是看看这个特定情况,并且C-hv grep-find-ignored-directories,这个变量提供了一些功能,可以使解决方案更简单,并且不需要不必要地加载grep.

你的.dir-locals.el文件可以设置一个局部变量:

((nil . ((my-ignore-blur-p . t))))
Run Code Online (Sandbox Code Playgroud)

在.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")))
Run Code Online (Sandbox Code Playgroud)

然后,当您rgrep从设置了此局部变量的任何缓冲区执行时,我们在全局grep-find-ignored-directories变量中指定的自定义函数将返回非nil值,这将导致"模糊"包含在被忽略目录列表中.

(nb我对函数和变量都使用相同的名称,因为我可以 - elisp为变量和函数分别有单独的名称空间 - 但这不是必需的.为清楚起见,我指的是代码中的函数eval-after-load,以及该变量在功能码和.DIR-locals.el文件).

或者你可以将my-ignore-blur-p函数的行为基于dir参数(作为被搜索的目录),并完全忽略局部变量.这将决定从列表中包含或省略"blur",完全独立于启动rgrep命令的缓冲区,这可能更为可取.


1如果向grep-find-ignored-directories全局添加"模糊" 您想要的,那么根本不要使用.dir-locals.el- 只需将您的eval-after-load调用添加到.emacs文件即可.