2012-10-27 73 views
14

我想要使用次要模式,该模式重新绑定了我一定要保留的主要模式密钥。如何重新绑定密钥而不将其从全局次模式映射中删除?我知道我可以使用define-key,但我想保留其他缓冲区/主要模式的绑定。缓冲区本地覆盖Emacs中的次要模式密钥绑定

任何人都可以帮忙吗?

回答

12

这样做有点麻烦。你可以这样做:

(add-hook '<major-mode>-hook 
    (lambda() 
    (let ((oldmap (cdr (assoc '<minor-mode> minor-mode-map-alist))) 
      (newmap (make-sparse-keymap))) 
     (set-keymap-parent newmap oldmap) 
     (define-key newmap [<thekeyIwanttohide>] nil) 
     (make-local-variable 'minor-mode-overriding-map-alist) 
     (push `(<minor-mode> . ,newmap) minor-mode-overriding-map-alist)))) 
+0

大,这项工作!我很惊讶,这个看似简单的任务是如此繁琐...... – sebhofer

+0

sebhofer:特定于模式的关键映射的全部意图是,它们*在所有模式处于活动状态时都会生效,所以我不会称之为绕过那种“看似简单”的行为。鉴于这些情况,该解决方案看起来非常优雅。 – phils

+0

@phils从有点幼稚的角度来看,任务是:覆盖给定缓冲区中的键绑定。对我来说似乎很简单。 – sebhofer

11

这里有一个函数来处理所有繁琐的位。

(defun local-set-minor-mode-key (mode key def) 
    "Overrides a minor mode keybinding for the local 
    buffer, by creating or altering keymaps stored in buffer-local 
    `minor-mode-overriding-map-alist'." 
    (let* ((oldmap (cdr (assoc mode minor-mode-map-alist))) 
     (newmap (or (cdr (assoc mode minor-mode-overriding-map-alist)) 
        (let ((map (make-sparse-keymap))) 
         (set-keymap-parent map oldmap) 
         (push `(,mode . ,map) minor-mode-overriding-map-alist) 
         map)))) 
    (define-key newmap key def))) 

此后,你可以做

(local-set-minor-mode-key '<minor-mode> (kbd "key-to-hide") nil) 
+0

非常感谢,按预期工作! – sebhofer

1

在我的情况,company-mode被重写cider-repl-mode绑定M-pM-n当公司落成菜单中显示。完成菜单的键盘图是company-active-map,但没有与之对应的次要模式(company-mode用于菜单为而不是有效),因此我无法使用任何现有答案。

这就是我想出了替代:

(add-hook 'cider-repl-mode-hook 
      (lambda() 
      (make-local-variable 'company-active-map) 
      (setq company-active-map (copy-tree company-active-map)) 
      (define-key company-active-map (kbd "M-p") nil) 
      (define-key company-active-map (kbd "M-n") nil)))