关于快捷键的优先级问题

使用global-set-key给forward-paragraph绑定了快捷键

(global-set-key (kbd "C-i") 'forward-paragraph)

但是在geiser-repl-mode下,C-i被定义成别的键了,请问如何让上面的设置不会被覆盖掉

1 个赞

global key map 的优先级是最低的。

把后面那个 map 上的按键设置成 nil 就行了,即取消。

我也不喜欢模式随便覆盖我自己定义的按键,所以我做了个minor mode,把自定义按键都放进去

(defvar my-keys-minor-mode-map (make-sparse-keymap) "my-keys-minor-mode keymap.")
(define-key my-keys-minor-mode-map (kbd "C-x g")   'magit-status)
(define-key my-keys-minor-mode-map (kbd "C-`")     'shell-pop)
#...
(define-minor-mode my-keys-minor-mode
  "A minor mode so that my key settings override annoying major modes."
  :init-value t :lighter "")
(my-keys-minor-mode 1)
4 个赞

这个方法好,不过怎么保证自己的 key map 总是能够优先命中呢?

minor mode 的按键总是比major mode高

Keymap优先级

我懒得折腾直接用general.el

1 个赞

根据 @casouri 提供的 Keymap 优先级链接,优先级由高到低依次是:

  1. overriding-terminal-local-map
  2. overriding-local-map
  3. text property 之 'keymap
  4. emulation-mode-map-alists
  5. minor-mode-overriding-map-alist
  6. minor-mode-map-alist (Minor Mode)
  7. text property 之 'local-map
  8. (current-local-map) (Major Mode)
  9. (current-global-map) (Global Map)

多个 Minor Mode 同时绑定同一个键,我猜测是最近启动的 Minor Mode 优先。


如果你有用 use-package / bind-key 的话,可以用 bind-key*,它用的是 emulation-mode-map-alists,对应上面的第 4 优先级。

(bind-key* "C-c C-c" #'emacs-version)
;; 解除上面的绑定
;; (unbind-key "C-c C-c" override-global-map)
3 个赞

感谢各位的解答