什么是Emacs Lisp中的"with-eval-after-load"

Tal*_*Kit 25 emacs macros elisp

with-eval-after-load试图persp-mode这里安装时遇到了宏.但是我无法在Emacs和/或Google上找到宏.它在哪里定义?它是标准Emacs Lisp的一部分吗?

leg*_*cia 46

来自etc/NEWS:

* Lisp Changes in Emacs 24.4
...
** New macro `with-eval-after-load'.
This is like the old `eval-after-load', but better behaved.
Run Code Online (Sandbox Code Playgroud)

Emacs 24.4于2014年10月20日发布.

eval-after-load被认为是不正常的,因为它是一个函数,而不是一个宏,因此需要引用其中的代码,这意味着它不能进行字节编译.它也只接受一个表单,所以如果你有多个表单,你需要使用progn.例如:

(eval-after-load "foo"
  '(progn
     (setq foo 42)
     (setq bar 17)))
Run Code Online (Sandbox Code Playgroud)

相同的版本with-eval-after-load将是:

(with-eval-after-load "foo"
  (setq foo 42)
  (setq bar 17))
Run Code Online (Sandbox Code Playgroud)

正如Clément在评论中指出的那样,一个缺点with-eval-after-load是您不能依赖于相关模块中定义的宏,而eval-after-load您可以确定这些宏已定义并可供使用.这在emacs-devel上讨论过.

  • @Drew`with-eval-after-load`安排主体进行字节编译,而`eval-after-load`则不行.这是其增加的主要原因,iirc. (6认同)
  • @lunaryorn:我错误地认为每次评估“BODY”都是不同的。请参阅 Emacs [bug #16810](http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16810)。 (3认同)
  • 另一方面,with-eval-after-load的语义略有不同:你不能(可靠地)在`with-eval-after-load'foo`块中调用包`foo`中定义的宏.https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00714.html (3认同)
  • *FWIW:*如果这就是“表现更好”的全部含义,那么我会说这几乎是虚假广告。我真诚地希望有一个比“新闻”中给出的更好的理由来费心将这个宏添加到 Emacs 中。 (2认同)
  • @lunaryorn:是的,你是对的,我应该超越文档,代码. (2认同)