如何覆盖主要模式绑定


38

有时,我的全局键绑定被主要模式覆盖。一个简单的例子是我的init文件中的以下设置

(global-set-key (kbd "C-j") 'newline-and-indent)

但是,令人讨厌的是,这种键绑定被暂存缓冲区的默认模式“ Lisp Interaction”主要模式隐藏了。

当我发现自己处于主要模式(或次要模式)隐藏全局键绑定的情况时,如何找回它?

注:我的问题是不是“我怎样才能绑定C-jnewline-and-indent‘?模式’” Lisp的互动 我对一个更通用的答案感兴趣,该答案关于如何处理因某些主要/次要模式而被隐藏的冲突或用户键绑定的键映射。


Answers:


39

如果您不想定义自己的次要模式(我在第一个答案中也提到过),那么对于相同的解决方案也有一种“捷径”方法。

您可以安装use-packageMelpa提供的软件包,并使用附带的软件包中的bind-key*bind-keys*宏。bind-keyuse-package

从以下文档中bind-key.el

;; If you want the keybinding to override all minor modes that may also bind
;; the same key, use the `bind-key*' form:
;;
;;   (bind-key* "<C-return>" 'other-window)

;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings
;; will not be overridden by other modes), you may use `bind-keys*' macro:
;;
;;    (bind-keys*
;;     ("C-o" . other-window)
;;     ("C-M-n" . forward-page)
;;     ("C-M-p" . backward-page))

万一有人好奇,请注意,这只是在幕后使用次要模式。通过使用emulation-mode-map-alists强制优先级,它确实采取了与其他次要模式冲突的不同方法。
菲尔2014年

由于其简单性,我将其标记为答案。本质上,它与该答案在做相同的事情,但是它在幕后为您方便地完成了大部分工作。
nispio 2014年

@nispio你是正确的。根据我的经验,唯一的区别是用于使次要模式绑定全局覆盖其他模式的方法。但是另一种方法(拥有自己的次要模式)的优点是,如果需要,您可以暂时将其关闭以尝试原始的emacs绑定(我需要这样做几次)。
Kaushal Modi 2014年

1
(bind-key* "C-M-&" 'override-global-mode),添加到您的init中,通常您可以根据需要快速取消绑定。由于override-global-mode不是“全局”次要模式,因此您仍然需要基于每个缓冲区停用它。因此,如果您发现自己经常停用全局覆盖键,则此解决方案不方便。
nispio 2014年

25

您可以定义自己的次要模式及其键映射,并使其覆盖所有其他模式(次要+主音)。这就是为什么我选择编写自己的次要模式。

设置键绑定的步骤将覆盖所有绑定:

  • 定义自己的次要模式和按键图,如下所示。
  • 全局激活您的次要模式
  • (define-key my-mode-map (kbd "C-j") #'newline-and-indent)

同样,在次要模式下设置的其他键绑定将覆盖其他模式下的绑定。

我强烈建议阅读Christopher Wellons 的博客文章,介绍如何编写次要模式。该博客加上必须nil在多个主要和次要模式下设置多个键绑定的烦恼启发了我编写自己的次要模式。

使用此方法的最好之处在于,当您要检查emacs的默认配置中的按键绑定时,只需关闭次要模式即可。然后将其重新打开,即可恢复自定义键绑定。

;; Main use is to have my key bindings have the highest priority
;; https://github.com/kaushalmodi/.emacs.d/blob/master/elisp/modi-mode.el

(defvar my-mode-map (make-sparse-keymap)
  "Keymap for `my-mode'.")

;;;###autoload
(define-minor-mode my-mode
  "A minor mode so that my key settings override annoying major modes."
  ;; If init-value is not set to t, this mode does not get enabled in
  ;; `fundamental-mode' buffers even after doing \"(global-my-mode 1)\".
  ;; More info: http://emacs.stackexchange.com/q/16693/115
  :init-value t
  :lighter " my-mode"
  :keymap my-mode-map)

;;;###autoload
(define-globalized-minor-mode global-my-mode my-mode my-mode)

;; https://github.com/jwiegley/use-package/blob/master/bind-key.el
;; The keymaps in `emulation-mode-map-alists' take precedence over
;; `minor-mode-map-alist'
(add-to-list 'emulation-mode-map-alists `((my-mode . ,my-mode-map)))

;; Turn off the minor mode in the minibuffer
(defun turn-off-my-mode ()
  "Turn off my-mode."
  (my-mode -1))
(add-hook 'minibuffer-setup-hook #'turn-off-my-mode)

(provide 'my-mode)

;; Minor mode tutorial: http://nullprogram.com/blog/2013/02/06/

5

要使全局绑定覆盖主模式绑定,只需nil在主模式下将绑定设置为即可:

(define-key my-major-mode-map (kbd "C-j") nil)

通常,不可能使全局绑定优先于所有模式(否则,没有主要模式是没有意义的),但是您可以通过使用最重要的绑定创建自己的次要模式来解决它。然后,您至少应优先于大多数(尽管不一定是全部)模式。


这对任何主模式都有效吗?换句话说,如果我安装了一个名为“ foo-mode”的主要模式,我可以将其放入(define-key foo-mode (kbd "C-j") nil).emacs文件,并希望它能正常工作吗?
nispio 2014年

实际上,您会希望它是foo-mode-map(我在答案中的示例很糟糕),但是,是的,这将在主模式下禁用键绑定,因此将改为使用全局键绑定(除非存在使用它的其他次要模式)。
shosti 2014年

foo-mode调用键盘映射是否相当普遍foo-mode-map
nispio 2014年

@nispio是的,对于大多数模式都是如此(尽管那里有一些流氓)。
shosti

0

您可以使用以下宏:

(defmacro expose-global-keybinding (binding map)
  `(define-key ,map ,binding (lookup-key (current-global-map) ,binding)))

(defmacro expose-bindings (map bindings)
  `(dolist (bnd ,bindings)
     (expose-global-keybinding (kbd bnd) ,map)))

编辑

检查以下示例:

如果键盘映射X覆盖了全局绑定Y,则您将编写:

(expose-bindings X '("Y"))

然后覆盖将被“撤消”。


您的宏将受益于使用反引号:`(定义键,映射,绑定(查找键(当前全局映射),绑定))
Sigma

您能否评论宏的功能以及如何使用它?从代码对我来说还不清楚。
nispio 2014年

第一个宏仅在全局映射中查找键并将结果分配给other map,从而通过公开全局映射绑定other map。第二个只是让您将前者应用于绑定列表。
Renan Ranelli 2014年

抱歉,如果我很忙,但我仍然不完全了解用法。我需要定义自己的特殊全局键盘映射吗?是否需要属于次要模式?我是否expose-bindings先执行,然后将这些键全局绑定到所需的命令?也许您可以显示一个示例,说明我可以将其放在init文件中以使其工作的情况。
nispio 2014年

2
请注意,这些宏名称是错误的。它们不“公开”全局绑定,而是复制全局绑定。如果实际的全局绑定更改,则这些重复的副本将不会更改。
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.