启用次要模式的正确方法


24

我有foo-mode,并会为其启用bar-minor-mode。那么哪种方法更普遍和更可取呢?

一种

(add-hook 'foo-mode-hook 'bar-minor-mode)

(add-hook 'foo-mode-hook (lambda ()
                           "Turn on `bar-minor-mode' mode."
                           (bar-minor-mode 1)))

C

(defun bar-minor-mode-on ()
  "Turn on `bar-minor-mode' mode."
  (interactive)
  (bar-minor-mode 1))

(add-hook 'foo-mode-hook 'bar-minor-mode-on)

d

•C型,但功能推向上游

Ë

•变体C,但功能存储在插件的配方中


4
嗨@Netsu,我注意到您加回了从lambda中删除的报价。总的来说,引用lambda很有害,因此我和Stefan只是试图激励良好的做法。:-)
马拉巴巴2014年

Answers:


26

这取决于您正在使用(或定位)的Emacs版本。如果您仅使用Emacs 24+,则可以安全地使用变体A:

* Incompatible Lisp Changes in Emacs 24.1

** Passing a nil argument to a minor mode function call now ENABLES
the minor mode unconditionally.  This is so that you can write e.g.

 (add-hook 'text-mode-hook 'foo-mode)

to enable foo-mode in Text mode buffers, removing the need for
`turn-on-foo-mode' style functions.  This affects all mode commands
defined by `define-minor-mode'.  If called interactively, the mode
command still toggles the minor mode.

这来自NEWS文件,但是根据注释,对功能符号使用功能引号是一种很好的做法,如下所示:

 (add-hook 'text-mode-hook #'foo-mode)

如果代码可能需要在Emacs 23(或更早版本)下运行,那么我将使用变体C,因为我个人不喜欢在hook变量中看到匿名函数。(请注意,我不确定我理解变体D&E的意思)。


3
您最好在次要模式下使用函数引号,以便字节编译器可以在未定义模式时警告您。
lunaryorn 2014年

谢谢。但是,仍然需要函数引用吗?它有什么优势?Lambda也是必需的吗?
Netsu 2014年


7

假设您正在编辑自己的配置,而不是分发的程序包,这是具有某些优点的另一种方法。

(add-hook 'foo-mode-hook
          #'custom-foo-hook)

(defun custom-foo-hook ()
  (bar-minor-mode 1)
  (baz-minor-mode 1)
  ;; ...
  (define-key foo-mode-map "C-c C-b" #'foobar))

这样做的好处是,所有内容都存储在一个钩子中,因此不必禁用某些内容remove-hook,而不必在custom-foo-hook和中注释某些内容C-M-x

您甚至可以编写从任何模式跳转到其自定义钩子的命令。


1
这(本质上)是变体C,具有不同的名称,但是我同意值得强调。当然,这是我在自己的配置中自定义主要模式行为时采用的方法。
菲尔2014年

1
变体C意味着add-hook要启用的每个次要模式都有多个语句。我想强调一点,只有一个add-hook陈述是有利的。
abo-abo 2014年

同意 在我的脑海中,我几乎将变体C转换为“定义启用模式的自定义函数”,而不是“定义启用模式的自定义函数”,但是回想起来,后者似乎是我们的意图。正如您所说,这取决于代码是否供个人使用。
菲尔2014年

7

您为什么要定义一个新命令,该命令究竟能做什么bar-minor-mode呢?

从24.1开始,所有这些都是完全等效的,因此,只需使用较少冗余的选项即可:选项A

(add-hook 'foo-mode-hook #'bar-minor-mode)

1
这是安全的解决方案吗?我的意思是,如果foo-mode-hook父模式之一具有与bar-minor-mode相同的钩子,则将调用两次,因此将被禁用。意外的行为。
Netsu 2014年

2
@Netsu是,调用不带参数的次要模式函数将无条件启用次要模式。
马拉巴巴2014年

4
@Malabarba仅从Emacs 24开始。在早期版本中,它实际上是在切换模式。
lunaryorn 2014年

1
@lunaryorn是的,这就是phils的答案更好的原因。:-)我太懒了,无法解决我的问题。
马拉巴巴2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.