听起来您基本上想为“特定缓冲区”打开或关闭特定的次要模式。通常,“特定缓冲区”可以通过它们的主要模式来区分,这就是我通常看待这类问题的方式。如何打开或关闭次要模式取决于您尝试打开/关闭的次要模式和您尝试打开/关闭的主要模式的实现。
根据主要模式启用/禁用事物的常用方法是通过major-mode-hook 变量。这是您自定义模式的地方:
(add-hook 'text-mode-hook 'auto-fill-mode)
我通常编写自己的函数,即使它是一个简单的单行函数,因为我几乎总是会在以后添加东西:
(defun my-text-mode-hook ()
"Stuff to do when `text-mode' is invoked."
(auto-fill-mode 1))
(add-hook 'text-mode-hook 'my-text-mode-hook)
你也可以在钩子中设置条件:
(defun my-text-mode-hook ()
"Stuff to do when `text-mode' is invoked."
;; skip modes based on text-mode
(when (eq major-mode 'text-mode)
(auto-fill-mode 1))
)
(add-hook 'text-mode-hook 'my-text-mode-hook)
我通常在major-mode-load-hook 中完成所有这些操作,因此只有在加载主模式的代码时才会发生:
(defun my-tnt-load-hook ()
(defun my-tnt-im-mode-hook ()
"Hook for TNT's im-mode hook."
(flyspell-mode 1)
(setq fill-column (- (frame-width) 5)))
(add-hook 'tnt-im-mode-hook 'my-tnt-im-mode-hook)
(add-hook 'tnt-chat-mode-hook 'my-tnt-im-mode-hook))
(add-hook 'tnt-load-hook 'my-tnt-load-hook)
编写良好的主模式将定义一个load-hook 变量(我通常查看该模式的源代码以找出答案)。如果它没有load-hook,你可以用eval-after-load函数模拟一个:
(defun my-view-mode-after-load-hook ()
"Stuff to do after view mode loads."
(defun my-view-mode-hook ()
"Stuff to run in `view-mode'."
(flyspell-mode 0))
(add-hook 'view-mode-hook 'my-view-mode-hook)
(define-key view-mode-map "b" 'View-scroll-page-backward)
(define-key view-mode-map [(delete)] 'View-scroll-page-backward)
(define-key view-mode-map "q" 'View-kill-and-leave)
(define-key view-mode-map "Q" 'View-quit))
(eval-after-load 'view '(my-view-mode-after-load-hook))
如果您不在load-hook 中执行此操作,那么您必须确保mode-hook 是可自定义的,然后通过自定义添加您的my-mode-hook;我宁愿把所有的东西都放在我的 .emacs 中的一个地方,所以我通常不会这样自定义我的钩子。
如果您发现没有major-mode-hook 的主模式,您可以使用define-derived-mode 基于它创建自己的主模式。然后,您必须在旧模式出现时调用新定义的模式。
(defun replace-alist-mode (alist oldmode newmode)
(dolist (aitem alist)
(if (eq (cdr aitem) oldmode)
(setcdr aitem newmode))))
(define-derived-mode hooked-foobar-mode foobar-mode "Foobar")
(replace-alist-mode auto-mode-alist 'foobar-mode 'hooked-foobar-mode)
(defun my-hooked-foobar-mode-hook ()
"Hook to run when `hooked-foobar-mode' is called."
(flyspell-mode 0))
(add-hook 'hooked-foobar-mode-hook 'my-hooked-foobar-mode-hook)
一些次要模式可以全局启用。如果您希望它们大部分时间都打开并且它支持它,您可以全局打开它,然后针对特定的主要模式将其关闭。
(global-font-lock-mode 1)
;; example of how to do it without a defun
(add-hook 'text-mode-hook (function
(lambda () ""
(interactive)
(font-lock-mode 0))))
如果无法全局启用次要模式,或者您不希望全局启用它,只需针对特定模式将其打开即可,如上所示。