Emacs:钩子如何工作?

时间:2014-07-27 13:17:29

标签: function emacs elisp hook

我已经阅读了不同的教程和手册,但仍然无法将各种内容放在一起。

据我所知,当我需要在旧功能仍然保存的情况下向事件添加新功能时,我通过调用add-hook添加一个钩子。来自add-hook的手动输入:

  

在钩子列表的开头添加了FUNCTION(如果需要)   除非可选参数APPEND是非零

所以钩子只是函数的列表。但是这个列表怎么样?作品?从我的小研究中我发现除 car cdr 之外的每个 cons单元还有一个不可见的未提及的函数指针槽(可能是一个索引,这没关系)。那么如何手动创建一个函数列表并执行它呢?可能有add-to-list函数,但我尝试的所有内容都会触发错误。同样在手册mentioned中:

  

您可以使用setq设置钩子变量,就像任何其他Lisp变量一样,

这里出了点问题,因为指向函数的指针不会被setq复制。即:

(defun myfunc1 () (message "hello"))
(setq onemorefunc 'myfunc1)

执行(onemorefunc)调试器触发器后,setq只会忽略指针存储的未命名元素的值。

2 个答案:

答案 0 :(得分:2)

要调用变量中的函数,您必须使用funcallapply

(funcall onemorefunc)

(apply onemorefunc '())

当Emacs处理一个钩子变量时,它会遍历列表:

(do ((hooks blah-hook (cdr hooks)))
    ((null hooks))
  (funcall (car hooks)))

答案 1 :(得分:2)

在您的示例中,setq仅为onemorefunc提供myfunc1个名称。钩子需要是一个列表,你需要使用add-hook将钩子函数添加到该列表,这是push的美化版本,而不是使用{{1 }}。提及setq误导了你,虽然熟悉钩子的人很清楚它正在告诉你一些 else 。它说你可以设置一个钩子变量 - 而不是一个钩子本身 - 使用setq,你可以,但它不清楚的是你要设置的那个hook变量是另一个列表(零个或多个函数)而不是函数。因此,假设setq为空开始:

my-mode-start-hook

相当于:

(add-hook 'my-mode-start-hook #'my-func)

在实践中,你应该始终做前者,不要做后者,除非你确定你知道自己在做什么。