如何“组合”挂钩?


14

在某些情况下,例如显示尾随空格,显示缓冲区边界,彩虹定界符以及其他一些我想在大多数模式下启用的功能,或者是所有与编程和文本相关的模式(因为在其中显示尾随空格,例如ediff-mode,将与主要模式发生冲突),而不是使用带有例外规则的全球化次要模式。由于大多数模式是从prog-mode或派生的text-mode,因此将有问题的函数添加到两者中prog-mode-hooktext-mode-hook可以正常工作,但是有很多模式不遵循此规范,例如css-modeLaTeX-mode

我想定义一个仅将功能添加到一个钩子的钩子,其中包含所有这些模式。让我们称之为non-special-mode-hook(与区别special-mode-hook)。我将如何创建在所有主要模式下运行的钩子?


Answers:


19

只需将这些设置组合到一个函数中,然后将该函数添加到所有相关的挂钩函数中:

(defun my-non-special-mode-setup ()
  (setq show-trailing-whitespace t)
  ...)
(dolist (hook '(prog-mode-hook text-mode-hook css-mode-hook ...))
  (add-hook hook 'my-non-special-mode-setup))

没有其他方法可以更简洁:无论发生什么情况,在某个地方您将拥有模式的白名单或黑名单。在实践中,您只会找到一些需要添加到列表中的模式,因此我建议您保持简单。

在我自己的配置中,我正是使用此技巧来统一几种面向Lisp的模式的配置。


谢谢,我想我也会针对其他有用的小组(例如,棘手的小组)调整此解决方案。
wasamasa 2014年

1
这正是我做我自己:github.com/purcell/emacs.d/blob/...
sanityinc

1
太好了,您可以将URL添加到答案中吗?我相信突出显示的代码片段不仅可以很好地说明实际用法,还可以演示进一步的用法,例如将Emacs Lisp相关的“挂钩”用作更大的“挂钩”的子集,以及如何从现有的主要模式中自动创建挂钩名称与derived-mode-hook-name
wasamasa 2014年

我比我更喜欢这个,只是对于(dolist ...)vs (add-hook ...)<repeat>。当仅将特定于模式的更改分开(每个模式文件use-packageel-get)时,我只会坚持我的做法。两者都是一站式解决方案,但观点不同。
乔纳森·里奇·佩平2014年

请注意,如果您APPENDadd-hook此处未提供非null 参数,则将以与您提供的列表顺序相反的顺序调用挂钩。没有错; 请注意这一点,以防顺序很重要。
德鲁

5

您可以向添加一个函数after-change-major-mode-hook,该函数检查新模式是否是一种有趣的模式(可能通过(not (derived-mode-p 'special-mode))),是否可以运行non-special-mode-hook


这听起来很漂亮(曾经有人弄清楚了所有“非特殊”模式,因为有一些只是使用fundamental-mode,而不仅仅是显示文本而已),但是对于我的口味来说有点太神奇了。因此,赞成。
wasamasa 2014年

4

我发现自己经常采用@sanityinc的模式,将设置和次要模式激活包装在defun中,并通过钩子循环调用它,但是我想要一种更简洁的方法,所以我写了这个宏:

(defmacro hook-modes (modes &rest body)
  (declare (indent 1))
  `(--each ,modes
     (add-hook (intern (format "%s-hook" it))
               (lambda () ,@body))))

注意:我是dash.el为了保持清洁,但可以很容易地将其适应使用(dolist)

然后,您可以将分组模式定义为列表变量,并按如下方式使用它:

(defvar progish-modes
  '(prog-mode css-mode sgml-mode))

(hook-modes progish-modes
  (highlight-symbol-mode)
  (highlight-symbol-nav-mode))

1
请注意,在这里您可以derived-mode-hook-name用来获取模式的hook变量的名称,从而避免了intern麻烦。
sanityinc

@sanityinc TIL derived-mode-hook-name。不错的提示!
waymondo'4-4-19

1

您可以执行以下操作,而不是定义适用于所有这些非派生模式的新钩子。

(defun run-my-hooks ()
  "Run all the following functions in the hook"
  (smartparens-mode 1)
  (whitespace-mode 1)
  (my-needed-mode 1)
  ...)

(add-hook 'specific-mode-hook 'run-my-hooks)
(add-hook 'another-mode-hook 'run-my-hooks)

您仍然需要将其添加到所有模式,但是通过定义函数以包括所有模式,您仅需在添加/删除附加功能时更改一个定义。


-2

也许您可以尝试以下方法:

(setq lisp-dialects-mode-hook '(lisp-mode-hook
                            lisp-interaction-mode-hook
                            emacs-lisp-mode-hook
                            ;; common-lisp-mode-hook
                            scheme-mode-hook
                            clojure-mode-hook
                            cider-repl-mode-hook
                            ))

(add-hook 'lisp-dialects-mode-hook 'func)
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.