在同一缓冲区中使用两个主模式映射


11

我遇到了一些情况,其中非常需要将一种主要模式的键盘映射用作另一种主要模式的后备键盘映射。例如:

  • 我在一些组织文档中写了很多LaTeX,因此latex-mode在编辑时轻松使用命令 会很棒org-mode
  • 我经常去Markc支持的irc会议室,因此将markdown-modekeybinds添加到中也很不错erc-mode

在这两种情况下,此额外的键盘映射都应作为后备(这就是为什么我不能仅使用次要模式的原因)。我不希望乳胶命令覆盖任何org-mode键。我想要的是:
如果键是在latex-mode-mapAND中定义的,并且未在中定义,请 org-mode-map使用latex-mode-mapbinding

问:如何将键盘映射设置为主要模式的后备键盘映射?

问:如何在不覆盖任何内容的情况下将键从一个主模式映射复制到另一个主模式映射?


只是要清楚。我知道我可以一一定义这些键,但是拥有一个自动化的解决方案将更加方便。


6
使用键盘映射合并。请参阅make-composed-keymap
德鲁2014年

Answers:


12

事实证明,这比预期的要简单。正如在这里的评论和关于这个问题的建议:

(with-eval-after-load 'erc
  (require 'markdown-mode)
  (require 'cl-lib)
  (setq erc-mode-map
        (make-composed-keymap (cl-copy-list erc-mode-map)
                              markdown-mode-map)))

这将创建一个keymap,它是的副本,erc-mode-map但也从继承markdown-mode-map。因此,所有markdown按键与erc按键碰撞时都会被遮盖。

如果您确实希望后备键映射的某些键胜过主Kemap,只需在主键中禁用它们即可。

(define-key erc-mode-map "\C-c\C-a" nil)

2
我注意到,define-key在的返回值上使用make-composed-keymap可能会对原始键盘映射产生意想不到的副作用,而且我怀疑同样的情况可能也适用于此手动appended映射。如果要使用define-key,似乎最安全的方法是创建一个新的键盘映射,其父键盘映射是一个组合键盘映射。
乔恩·O。

@JonO。实际上,我很惊讶地发现这里没有发生这种情况。如果我这样做(define-key erc-mode-map "\C-c\C-s" nil)即使在erc缓冲区中,相应的markdown-mode键仍然可用。
马拉巴巴

马拉巴巴:我相信您的最后评论在该代码更改后将不再适用。该make-composed-keymap文档说:“ MAPS中的nil绑定会覆盖PARENT中的任何对应绑定,但不会覆盖MAPS的其他键图中的对应绑定。” 正如markdown-mode-map您的示例中的PARENT一样,我希望该nil绑定抑制markdown绑定吗?
菲利普斯(朋友)2014年

2
我的解释是,那(make-composed-keymap (list erc-mode-map markdown-mode-map)) 产生您所描述的效果,但是?
phils 2014年

1
cl-copy-list不会真正做到你想要的。如果要复制键盘映射,则应使用copy-keymap
Stefan

3

如@Malabarba所述,您可以使用make-composed-keymap它。但是,如果您确实希望新的键映射继承自两个键映射,那么修改新的键映射不会影响其他两个键映射中的任何一个,则需要分两个步骤进行:

(make-composed-keymap
 nil (make-composed-keymap (list erc-mode-map markdown-mode-map)))

这是因为define-key有时可以修改作为第一个参数传递的映射,make-composed-keymap但不能修改作为第二个参数传递的映射。我想您应该M-x report-emacs-bug并要求make-composed-keymap接受键盘映射列表作为第二个参数,所以您可以这样做

(make-composed-keymap nil (list erc-mode-map markdown-mode-map))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.