检查/修改Emacs小模式的钩子

3
我使用以下代码来启用Python缓冲区的linum-mode:
(defun my-python-mode-hook () 
  (linum-mode 1)) 
(add-hook 'python-mode-hook 'my-python-mode-hook)

然而,我对hooks的理解仍然非常有限。据我所知,上面的代码将一个函数添加到python-mode-hook中,因此我认为这个hook已经被定义了,甚至可能已经有一些代码在其中。有以下问题:
  1. Emacs是否为所有小模式定义形式为<minor_mode_name>-hook的hook?还是模式本身定义它们?
  2. 如何查找已添加到hook的代码?
  3. 如何更改该hook的元素?

这个问题部分是由于 GitHub 上 issue 的启发而来,该问题与 elpy 相关,其中 elpy-mode 似乎在卸载 elpy 后仍留下了一个钩子用于 python-mode。请注意,保留 HTML 标签。

1
小问题:python-mode实际上是一个主模式。主模式是互斥的(即在给定缓冲区中一次只能有一个处于活动状态),而任意数量的次要模式(例如linum-mode)可以处于活动状态。钩子对于主模式和次要模式都是相同的。 - legoscia
1个回答

4

(1) Emacs并不会自动定义一个次要模式钩子,但你可以使用:after-hook关键字定义一个(参见定义次要模式的手册页面)。(更新:根据Legoscia的最新评论,从Emacs 24.3.90版本开始,次要模式钩子将被自动定义。感谢Legoscia!)

(2) 钩子只是变量,因此您可以像检查其他变量一样检查它们(例如,C-h vM-x describe-variable RET some-hook)。

(3) 您可以使用add-hookremove-hook更改钩子的元素(请参阅设置钩子的手册),例如:

(add-hook 'python-mode-hook 'my-python-mode-hook)

(remove-hook 'python-mode-hook 'my-python-mode-hook)

(顺便提一句,最好在钩子中使用命名函数而不是匿名lambda函数,因为您可以在命名函数上使用remove-hook。)

1
使用 define-minor-mode 定义的次要模式将自动获得一个钩子变量。:after-hook 用于在钩子运行后运行代码。 - legoscia
你确定吗?在定义次要模式手册页面上,(define-minor-mode hungry-mode ...)的最小示例未生成钩子变量(意思是hungry-mode-hook或类似的变量;当然,它确实定义了hungry-mode)。我有遗漏什么吗? - Dan
2
啊,你说得对:hungry-mode-hook 只在 Emacs 24.3.90 及以上版本中定义。 - legoscia
1
编辑了答案以包含那些信息。很好的发现! - Dan
1
钩子变量的声明有点可选。如果最近已经明确添加了它,那可能是出于词法与动态绑定的原因。无论如何,通过define-*-mode宏定义的所有模式函数都将运行一个MODENAME-hook;这种情况已经存在很长时间了。add-hook函数不介意指定的钩子变量是否被绑定,因此您可以放心地使用(add-hook 'some-example-mode-hook 'myfunc)来处理任何some-example-mode,而不管该模式是否已加载,以及钩子变量当前是否已定义。 - phils
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接