在特定模式的前缀键映射中定义键

时间:2014-08-27 10:26:42

标签: emacs elisp key-bindings

我把所有的键绑定都放在一个单独的次要模式中 - 首先,要确保我认为强制的键绑定不会被某些主要模式覆盖;第二,能够在一个命令中禁用所有这些,以防我需要。

到目前为止,我一直在扩展前缀键,如下所示:

(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)

但在这种情况下,我的次要模式与它无关,所以我失去了使用它的所有优点。

一种方法是确定哪个键绑定到该特定前缀键映射,然后在绑定中使用该键。但它有一个缺点 - 如果我在加载我的次要模式后将其重新映射,则前缀键不会重新映射到我的次要模式。

那么还有更好的方法吗?

2 个答案:

答案 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可以是以下两种方法之一:

  1. 变量包含列表,其中第一个元素是符号'keymap(通常是如何在emacs中使用键盘映射)
  2. 符号whos函数单元格被设置为keymap变量(我从来没有看到任何人像这样使用它)
  3. 首先,我们要为我们的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