如何在emacs宏中避免急切的宏扩展失败?

时间:2014-08-02 17:50:34

标签: emacs macros

我定义了这个宏:

(defmacro with-current-directory (directory &rest body)
  "Set the working directory temporarily set to DIRECTORY and run BODY.
DIRECTORY is expanded"
  `(let ((default-directory
          ,(file-name-as-directory
            (expand-file-name (eval directory)))))
     ,@body))

我在emacs打开时加载的一些lisp函数中使用。我总是得到这些警告:

Eager macro-expansion failure: (void-variable repo-dir)
Eager macro-expansion failure: (wrong-type-argument stringp nil)

我理解这种情况正在发生,因为这些变量未在加载时定义,而emacs正试图评估它们。我的问题是,我如何避免收到这些警告。有没有办法定义宏以便不会发生?我无法弄清楚如何使用变量的值,而不是变量本身的符号。

2 个答案:

答案 0 :(得分:5)

像这样:

`(let ((default-directory
        (file-name-as-directory (expand-file-name ,directory))))

由于directory不是值,而是计算值的lisp表达式,因此需要将表达式(使用逗号运算符)插入到宏的扩展中。如果在调用file-name-as-directory之前放入逗号,则必须能够在表达式的标记上仅基于 的宏扩展时计算目录,这是不能的如果directory引用变量名称,请执行。

答案 1 :(得分:1)

看起来有些人打败了我。看看另一个答案。

您不应该在扩展时评估文件名扩展。 eval调用也不应该存在。宏扩展期间唯一应该发生的事情是将directory的值放在返回的表达式中。删除eval并将逗号放在目录前面。

很高兴知道,无论何时使用eval,你都可能做错了什么