使用define-globalized-minor-mode
1宏创建的全局次要模式有一些棘手的问题。你的代码似乎没有任何作用的原因是,全局化模式利用after-change-major-mode-hook
来激活它们控制的缓冲区本地次要模式;而那个钩子在主模式自己的钩子之后立刻运行4。
各个模式可以实现自定义方式来指定某种黑名单或其他方法,以防止该模式在某些情况下启用,因此通常值得查看相关的M-x customize-group
选项,以查看是否存在这样的功能。然而,目前令我感到困惑的是,没有找到一个好的干净的通用方法来实现这一点,适用于任何全局化的次要模式。
可惜的是,由该宏定义的MODE-enable-in-buffers
函数没有执行与全局模式函数执行的(with-current-buffer buf (if ,global-mode ...))
检查相同的操作。如果有的话,你可以简单地使用slime-repl-mode-hook
将全局模式变量设置为缓冲区本地并将其设为nil。
一个快速的hack是检查2全局化次要模式定义的turn-on
参数(在本例中是centered-cursor-mode
本身3),并编写一些around advice,以防止对相关模式执行该操作。
(defadvice centered-cursor-mode (around my-centered-cursor-mode-turn-on-maybe)
(unless (memq major-mode
(list 'slime-repl-mode 'shell-mode))
ad-do-it))
(ad-activate 'centered-cursor-mode)
我们可以使用一个简单可重复的模式,立即在启用缓冲区局部次要模式后再次禁用它。通过使用APPEND
参数添加到add-hook
的after-change-major-mode-hook
函数将可靠地在全局化的次要模式生效后运行,因此我们可以执行以下操作:
(add-hook 'term-mode-hook 'my-inhibit-global-linum-mode)
(defun my-inhibit-global-linum-mode ()
"Counter-act `global-linum-mode'."
(add-hook 'after-change-major-mode-hook
(lambda () (linum-mode 0))
:append :local))
1 或它的别名 define-global-minor-mode
,我认为应该避免使用,因为它可能会与使用 define-minor-mode
创建的“全局”次要模式混淆。虽然“全球化”的次要模式仍涉及到全局次要模式,但在实践中工作方式非常不同,因此最好将它们称为“全球化”,而不是“全局”。
2 C-hf define-globalized-minor-mode
RET 显示 turn-on
是第三个参数,在模式定义中我们可以通过 M-x find-function
RET global-centered-cursor-mode
RET 进行检查。
3 采用这种方法,事实上将阻止您从slime-repl-mode或shell-mode缓冲区启用此次要模式,而具有单独 turn-on 函数的全球化次要模式仍然可以以其非全局形式调用,如果您想要这样做的话。
4 https://dev59.com/GXfZa4cB1Zd3GeqPV8zl#19295380