使用 keymap-set 管理 Emacs 快捷键
2024-01-31
以前简单粗暴地直接用 global-set-key
来定义快捷键,于是配置文件里常常有下面这种一大段的代码:
(global-set-key (kbd "C-c n d") #'denote)
(global-set-key (kbd "C-c n t") #'denote-keywords-add)
(global-set-key (kbd "C-c n T") #'denote-keywords-remove)
最近看了 prot 刚出的视频, Emacs: define prefix/leader key (nested key maps) ,发现自己定义 keymap 其实很简单的,使用 defvar-keymap
,可以从上面的配置中抽取 C-c n 作为一个 prefix key ,定义如下:
(defvar-keymap hsk/notetaking-map
:doc "My notetaking keymap"
"d" #'denote
"t" #'denote-keywords-add
"T" #'denote-keywords-remove)
然后就可以用:
(global-set-key (kbd "C-c n") hsk/notetaking-map)
来将上面定义的 keymap 绑定到 C-c n 上。不过从 emacs-29 开始,更推荐用 keymap-set
,上面的代码可以改成:
(keymap-set global-map "C-c n" hsk/notetaking-map)
省去了 (kbd ...)
这一层,比较方便。
比起原先每个快捷键单独定义,使用 keymap 好处是便于管理,比如之后我想更换快捷键前缀,从 C-c n 换成 C-c C-n ,只要改一处 keymap-set
就可以了。
另一个优点是可以嵌套定义,比如我想要将 org-journal
相关的操作也挂到 hsk/notetaking-map
下面,可以先定义一个 hsk/org-journal-map
:
(defvar-keymap hsk/org-journal-map
:doc "My org-journal keymap"
"n" #'org-journal-new-entry
"s" #'org-journal-search
"o" #'org-journal-open-current-journal-file)
然后将它嵌套进另一个 map 下面:
(defvar-keymap hsk/notetaking-map
:doc "My notetaking keymap"
;;...
"j" hsk/org-journal-map)
这样 org-journal-new-entry
就映射到 C-c n j n 上了,非常优雅。