如何设置全局覆盖并优先于该键的所有其他绑定的键绑定?我想覆盖所有主要/次要模式映射并确保我的绑定始终有效。
这当然行不通:
(global-set-key "\C-i" 'some-function)
它在 text-mode
中有效,但是当我使用 lisp-mode
时,C-i
会反弹到 lisp-indent-line
。
我可以在 lisp-mode
和其他所有模式中单独遍历并覆盖此绑定,但必须有更简单的方法。每次我为新文件类型安装新模式时,我都必须返回并检查以确保我的所有键绑定都没有被新模式覆盖。
我想这样做是因为我想模仿我已经从其他编辑器那里学到并根深蒂固的绑定。
我对所有“覆盖”键绑定使用次要模式:
(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)
这还有一个额外的好处,就是能够一举关闭我的所有修改(只需禁用次要模式),以防其他人正在驱动键盘,或者如果我需要查看默认键绑定的作用。
请注意,您可能需要在 minibuffer 中将其关闭:
(defun my-minibuffer-setup-hook ()
(my-keys-minor-mode 0))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
作为 scottfrazer's answer 的补充,我编写了以下内容,以便我的键绑定保持优先级,即使随后加载的库引入了它们自己的新键映射。
因为可以在编译时生成键映射,所以 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)
minibuffer-setup-hook
上被禁用了吗?
我在搜索“emacs undefine org mode keybindings”时发现了这个问题,因为我想取消绑定现有的 Cc Cb 行为以允许我的全局映射埋入缓冲区以在 org 缓冲区中工作。
这最终成为我最简单的解决方案:
(add-hook 'org-mode-hook
(lambda ()
(local-unset-key (kbd "C-c C-b"))))
尽管 scottfrazer 的答案正是您所要求的,但我会为后代提及另一种解决方案。
“不要将 Cc 字母定义为 Lisp 程序中的键。由 Cc 和字母(大写或小写)组成的序列是为用户保留的;它们是为用户保留的唯一序列,所以不要阻止它们。”
如果您将您的个人全局绑定绑定到 Cc 加一个字母,那么您“应该”是安全的。但是,这只是一个约定,任何模式仍然可以覆盖您的绑定。
C-c b
是 no longer suggested in the manual。
如果您想“始终使用映射中的键绑定,除非我为特定模式映射显式覆盖它们”,并假设您使用的是 scottfrazier's approach,您希望:
(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
是专门为覆盖所有其他地图而设计的。但是使用它是危险的。
除非你真的想自己做,否则你应该检查一下,看看其他人是否已经做过。
有一个适用于 Emacs 的包,它为您提供类似 Windows 的键绑定。你应该可以通过谷歌找到它。
cua-mode
。
在 Emacs 27 中,有 override-global-map。然后,您可以执行以下操作: (define-key override-global-map (kbd "Mh") 'backward-kill-word)
这个答案不对,不好意思。
不定期副业成功案例分享