【问题标题】:Wrong type argument: listp, eval-after-load in .dir-locals.el错误的类型参数:.dir-locals.el 中的 listp、eval-after-load
【发布时间】:2013-04-26 13:19:36
【问题描述】:

我正在写我的第一个.dir-locals.el,我在*Messages* 中遇到错误。

代码:

(eval-after-load "grep"
  '(add-to-list 'grep-find-ignored-directories "blur"))

追踪:

.dir-locals error: Wrong type argument: listp, eval-after-load

我做错了什么?

【问题讨论】:

    标签: emacs eval-after-load


    【解决方案1】:

    .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 文件。

    【讨论】:

      【解决方案2】:

      .dir-locals.el 文件有特定的格式。您需要将某种模式与某些变量相关联。如果您想为所有模式应用变量,请使用nil。以下作品:

      ((nil
        (eval-after-load "grep" '(add-to-list 'grep-find-ignored-directories "blur"))))
      

      但是,这可能不是(可能不是)您想要的。如果您在编辑此目录中的任何文件之前加载grep,则不会产生任何影响。

      【讨论】:

      • 恐怕这都是错的。首先,您使用符号eval-after-load 设置局部变量。其次,如果它确实按照您的想法进行,那么它绝对在加载 grep 后对访问的文件进行评估,因为如果加载了库,则立即评估 eval-after-load 正文。 (请注意,这不是您想做的,这是正确的;只是出于正确的原因。)
      • 非常有意义。解释了为什么我得到的唯一自动完成是 eval 而不是 eval-after-load。感谢您的更正。
      猜你喜欢
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 2011-02-13
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多