GNU emacs lisp:with-wrapper-hook宏有什么作用?你能提供一个描述和例子吗?

时间:2011-09-17 00:59:59

标签: emacs macros docstring

我发现这个宏的在线帮助没有信息。也许Stackoverflow可以做得更好?

我正在使用emacs trunk(24.0.50.1)以防万一。

谢谢!

1 个答案:

答案 0 :(得分:1)

首先,您需要阅读hooks上的手册,以及文档将此宏与之比较的around advice手册。宏使您能够编写可以被未来某些代码包围的代码,以更改其工作方式。

(with-wrapper-hook hook-name ()
   your code here)

然后其他人可以向hook-name添加一个类似这样的函数:

(defun my-hook (your-code)
   (let ((original-result (funcall your-code)))
      (modify original-result)))

参数your-code代表上面的your code here,封装在一个函数对象中。包装器可以使用(funcall your-code)调用原始代码,但不需要这样做,在这种情况下它会完全覆盖您的代码。钩子甚至可以包含几个函数,每个函数都接收下一个函数作为它的第一个参数,因此可以有一个包装器链,每个包装器修改下一个的结果。也可以为这些函数中的每一个定义一些额外的参数(这就是上面的空白例子)。

要查找示例,您可能希望围绕源代码进行grep。一个用途是expand-abbrev

(with-wrapper-hook abbrev-expand-functions () 
     ...)

expand-abbrev函数用于扩展abbreviations,并且有一个钩子(abbrev-expand-functions)可以自定义在不同模式下执行此操作的方法。这个钩子不能“正常”,因为它必须能够修改结果,并且它需要能够将一些结果返回给调用代码。 (正如关于钩子的文档中所解释的那样,在没有参数的情况下调用普通钩子并忽略它的返回值,因此只调用它对缓冲区的副作用。)

此挂钩上的函数可以执行自己的缩写扩展并忽略包装的代码,或调用包装的代码并修改结果,或使用不同的输入多次调用包装的代码。使用该挂钩的示例是mail-abbrev-expand-wrapper,它检查您是否在电子邮件中键入To:标头,在这种情况下,扩展您的邮件别名而不是标准缩写。该函数修改了影响缩放扩展的各种环境(语法表,缩写表),然后使用(funcall expand)调用包装函数来完成实际工作并直接返回其结果。