我把所有的键绑定都放在一个单独的次要模式中 - 首先,要确保我认为强制的键绑定不会被某些主要模式覆盖;第二,能够在一个命令中禁用所有这些,以防我需要。
到目前为止,我一直在扩展前缀键,如下所示:
(define-key my-minor-mode-map (kbd "M-g f") 'my-goto-file-func)
但后来我意识到有前缀keymap这样的东西,而M-g
密钥则是goto-map
。所以我宁愿扩展这个键映射而不是硬编码前缀键,所以它会像:
(define-key goto-map (kbd "f") 'my-goto-file-func)
但在这种情况下,我的次要模式与它无关,所以我失去了使用它的所有优点。
一种方法是确定哪个键绑定到该特定前缀键映射,然后在绑定中使用该键。但它有一个缺点 - 如果我在加载我的次要模式后将其重新映射,则前缀键不会重新映射到我的次要模式。
那么还有更好的方法吗?
答案 0 :(得分:2)
按照您的方式扩展键非常好,因为它可以将复杂性降至最低。因此,虽然在次要模式下修改键映射当然是可能的,但它不一定更好。
要在次要模式中使用修改后的键盘而不覆盖原始键盘,只需将原件设置为父级,例如
(defvar my-goto-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map goto-map)
map))
然后,您可以在次要模式中使用修改后的版本:
(define-key my-goto-map "f" 'find-file)
(define-key my-mode-map (kbd "M-g") my-goto-map)
但原始的goto-map
仍然活着并且正在进行修改,修改它会反映在my-goto-map
中:
(define-key goto-map "i" 'info)
请参阅elisp手册中的“继承和键盘映射”。
答案 1 :(得分:0)
请注意,olab b的答案完全没问题,我会接受他的回答并自己使用,但是有一个问题:
原始goto-map
未受影响。想象一下假设情况,其中某些库提供了以某种方式使用goto-map
的命令 - 例如,为其中的命令提供一些奇特的界面或在其自己的键映射内绑定它 - 这是helm
如果他们足够疯狂就可以做到。由于我的所有密钥都会转到my-goto-map
,因此它们不会反映在这些扩展中。
所以这是一个奇怪的解决方案,只是为了解决这个问题:
首先,请注意elisp中的keymap可以是以下两种方法之一:
'keymap
(通常是如何在emacs中使用键盘映射)首先,我们要为我们的keymap定义一个变量:
(defvar my-goto-map (make-sparse-keymap))
接下来,将其值写入功能单元格:
(fset 'my-goto-map my-goto-map)
请注意,我们无法替换 goto-map
,因为已绑定到它的所有内容都无法取代。和keybindinds一个一个地操纵并不是很有趣。所以这是一个合适的插入:
(setcdr goto-map (cons (make-composed-keymap 'my-goto-map (cons (car goto-map) (cdr goto-map))) nil))
(当然我们可以将my-goto-map
追加到goto-map
,但在这种情况下,my-goto-map
与原始goto-map
之间的关系将是"邻居&#34 ;而不是"亲子&#34 ;;和"邻居"不允许取消定义的键绑定)
请注意,goto-map
现在取决于符号 my-goto-map
,因此我们可以使用该符号执行任何操作,而不会丢失我们的键盘映射。因此,我们可以轻松禁用所有自定义键绑定,如下所示:
(fset 'my-goto-map nil)
my-goto-map
的可变单元格未受影响,因此我们可以轻松恢复键绑定:
(fset 'my-goto-map my-goto-map)
主要缺点来自于emacs不允许"缓冲区本地功能"只有"缓冲区本地变量&#34 ;.在这里,我们需要一个本地函数 :(因此我们不能在次模式的钩子中激活前缀映射 - 导致修改将全局反映。
但至少该键映射的所有原始前缀键(只有M-g
IIRC)将自动使用所有自定义键绑定,因此无需将M-g
硬编码为前缀键my-goto-map
。