全局覆盖Emacs中的键绑定

时间:2009-03-25 20:59:41

标签: emacs keyboard-shortcuts

如何设置全局覆盖的键绑定,并优先于该键的所有其他绑定?我想覆盖所有主要/次要模式地图,并确保我的绑定始终有效。

这当然不起作用:

(global-set-key "\C-i" 'some-function)

适用于text-mode,但当我使用lisp-mode时,C-i会反弹为lisp-indent-line

我可以单独在lisp-mode和其他所有模式中覆盖并覆盖此绑定,但必须有一种更简单的方法。每次我为新文件类型安装新模式时,我都必须返回并检查以确保所有的键绑定都没有被新模式覆盖。

我想这样做,因为我想模仿我已经学过并从其他编辑那里根深蒂固的绑定。

8 个答案:

答案 0 :(得分:140)

我对所有“覆盖”键绑定使用次要模式:

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

这样做的另一个好处是能够一举关闭所有修改(只是禁用次要模式)以防其他人正在驾驶键盘或者我需要查看默认键绑定的作用。< / p>

请注意,您可能需要在迷你缓冲区中将其关闭:

(defun my-minibuffer-setup-hook ()
  (my-keys-minor-mode 0))

(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)

答案 1 :(得分:30)

作为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))))

答案 2 :(得分:16)

安装use-package,eval,你已经完成了:

(require 'bind-key)
(bind-key* "C-i" 'some-function)

答案 3 :(得分:14)

我在搜索&#34; emacs undefine org mode keybindings&#34;时发现了这个问题,因为我想要取消绑定现有的Cc Cb行为,以允许我的全局映射使bury-buffer在组织缓冲区中工作。 / p>

这最终成为我最简单的解决方案:

(add-hook 'org-mode-hook
      (lambda ()
        (local-unset-key (kbd "C-c C-b"))))

答案 4 :(得分:12)

虽然scottfrazer的回答正是你所要求的,但我会提到后人的另一种解决方案。

来自The Emacs Manual

  

“不要将Cc字母定义为Lisp程序中的键。由Cc和字母组成的序列(大写或小写)是为用户保留的;它们是为用户保留的唯一序列,因此不要阻止它们。“

如果您将个人全局绑定绑定到C-c加上一封信,那么您“应该”是安全的。但是,这只是一个约定,任何模式仍然可以覆盖您的绑定。

答案 5 :(得分:3)

如果你想“始终在地图中使用键绑定,除非我为特定的模式地图明确覆盖它们”,并假设你使用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)

应仅从当前缓冲区中的次模式中删除“\ C-i”绑定。警告:这是完全未经测试的,但似乎是正确的方法。设置父级而不是仅仅处理my-keys-minor-mode-map的全局值的关键是,对全局值的任何后续更改都会自动反映在本地值中。

答案 6 :(得分:2)

我认为你不能。这大致相当于说您要定义一个全局变量,该变量不能被函数中的局部变量声明隐藏。范围只是不起作用。

但是,可能有一种方法可以编写一个elisp函数来浏览模式列表并为您重新分配它。

答案 7 :(得分:2)

除非你真的想自己这样做,否则你应该检查一下,看看其他人是否已经做过。

Emacs有一个包,可以提供类似Windows的键绑定。你应该可以通过谷歌找到它。