Answers:
我对所有“覆盖”键绑定使用次要模式:
(defvar my-keys-minor-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-i") 'some-function)
map)
"my-keys-minor-mode keymap.")
(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")
(my-keys-minor-mode 1)
这样做还有一个好处,就是能够一举关闭我的所有修改(只需禁用次要模式),以防有人驱动键盘或需要查看默认按键绑定的功能。
请注意,您可能需要在迷你缓冲区中将其关闭:
(defun my-minibuffer-setup-hook ()
(my-keys-minor-mode 0))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
作为scottfrazer答案的补充,我编写了以下内容,即使后续加载的库引入了自己的新键映射,我的键绑定也保持优先级。
因为可以在编译时生成键映射,所以这load
似乎是最佳的选择。
(add-hook 'after-load-functions 'my-keys-have-priority)
(defun my-keys-have-priority (_file)
"Try to ensure that my keybindings retain priority over other minor modes.
Called via the `after-load-functions' special hook."
(unless (eq (caar minor-mode-map-alist) 'my-keys-minor-mode)
(let ((mykeys (assq 'my-keys-minor-mode minor-mode-map-alist)))
(assq-delete-all 'my-keys-minor-mode minor-mode-map-alist)
(add-to-list 'minor-mode-map-alist mykeys))))
安装use-package
,eval即可完成:
(require 'bind-key)
(bind-key* "C-i" 'some-function)
use-package
:Install package: use-package [No Match]
我在搜索“ emacs undefine org mode keybindings”时发现了这个问题,因为我想解除现有的Cc Cb行为的绑定,以允许我的全局映射能够在org缓冲区中工作。
这最终成为我最简单的解决方案:
(add-hook 'org-mode-hook
(lambda ()
(local-unset-key (kbd "C-c C-b"))))
尽管scottfrazer的答案恰好是您所要的,但我将为后代提及另一种解决方案。
从Emacs手册:
“不要在Lisp程序中将Cc字母定义为键。由Cc和一个字母(大写或小写)组成的序列是为用户保留的;它们是为用户保留的唯一序列,因此请不要阻塞它们。”
如果您将个人全局绑定绑定到Cc加一个字母,那么“应该”是安全的。但是,这仅仅是一个约定,任何模式仍然可以覆盖您的绑定。
如果要“始终使用映射中的键绑定,除非我为特定的模式映射显式覆盖它们”,并假设您正在使用scottfrazier的方法,则需要:
(defun locally-override (key cmd)
(unless (local-variable-p 'my-keys-minor-mode-map)
(set (make-variable-buffer-local 'my-keys-minor-mode-map)
(make-sparse-keymap))
(set-keymap-parent my-keys-minor-mode-map
(default-value 'my-keys-minor-mode-map)))
(define-key my-keys-minor-mode-map key cmd))
所以
(locally-override "\C-i" nil)
应该仅从当前缓冲区的次要模式中删除“ \ Ci”绑定。警告:这是完全未经测试的,但似乎是正确的方法。设置父级而不是仅仅应付my-keys-minor-mode-map的全局值的意义在于,这样以后对全局值的任何更改都会自动反映在本地值中。
我认为你不能。这大致相当于说您要定义一个全局变量,该变量不能被函数中的局部变量声明隐藏。范围就是这样。
但是,可能有一种方法可以编写一个elisp函数来浏览模式列表,然后为您重新分配它。
overriding-local-map
经过专门设计可覆盖所有其他地图。但是,使用它很危险。