7

这是 Emacs 中的一个常见场景:我想将一个函数绑定到一个键,但我不确定它是否可能与现有的键绑定(易于检查)或“流行”模块中的键绑定(难以检查,什么是“流行”?

如果有一本百科全书就好了:如果我查一下C-c C-t,我会发现它一定会:

  • org-todoorg-mode
  • sgml-tagsgml-mode
  • ...

有没有这样的事情?我知道我可以C-c A通过C-c-Z等方式使用,但有时不必按下并释放Ctrl键也很好。

4

1 回答 1

7

我从来没有遇到过这种事情的资源。包作者可以完全自由地添加和更改键绑定,无论是在他们自己的键映射中还是在全局键映射中。维护索引会很困难。

Emacs 可以动态加载功能,因此活动的键盘命令也是动态的,并且受制于您已安装的功能和required. 例如,如果您不需要 paredit,您将无法检查其键盘映射。

M-x describe-bindings将告诉您 Emacs 当前已加载的键绑定。这是一个很长的清单!下面的show-key-bindings函数会将其缩减为使用修饰键的绑定。

(defun get-bindings ()
  (with-temp-buffer
    (describe-buffer-bindings (current-buffer))
    (buffer-string)))

(defun format-binding (b)
  (let ((ws (split-string b))) 
    (apply 'format "%s\t%s" (butlast ws) (last ws))))

(defun binding? (str)
  (string-match-p (rx bol (any "C" "M" "H" "S")) str))

(defun join-string-lines (lines)
  (mapconcat 'identity lines "\n"))

(defun show-key-bindings ()
  "Show the active keybindings for the current buffer."
  (interactive)
  (let* ((bs  (split-string (get-bindings) "\n" t))
         (fmt (mapcar 'format-binding (remove-if-not 'binding? bs))))
    (save-excursion
      (let ((help-window-select t))
        (with-help-window  "*active bindings*"
          (princ (join-string-lines fmt)))))))

回顾一下,您可以使用一些函数来设置绑定:

  • global-set-key

    当您希望某些命令始终可用时使用此选项。

  • local-set-key

    设置当前缓冲区的键值。我喜欢在我的钩子中使用它来使键绑定可用于特定模式。

  • define-key

    将命令添加到键盘映射。键盘映射必须已经绑定,因此这往往太脆弱而无法在您的配置中使用。

如果您担心在您的 emacs 配置中意外覆盖模式的绑定,最简单的做法是确定您是否真的需要将命令设置为global。尽可能使用local-set-key

M-x package-install key-chord如果您发现您的键用完了,您还可以查看 key-chord ( ) 之类的包,或者使用自定义键映射定义您自己的次要模式。


使用一些精湛的 shell 脚本或 elisp,应该可以解析 elisp 文件列表并提取它们定义的键绑定。我以后可能会调查一下。

同时,以下 unix shell 命令将在目录树中找到对上述键绑定形式的所有引用。您可以在 .emacs.d 中运行它来检查 elpa 包中设置的键绑定。

tree -fxi -P '*.el' | xargs egrep -s 'local-set-key|define-key|global-set-key'
于 2013-04-11T02:23:36.820 回答