emacs的keybinding

2012-11-05

keymaps

按下一个键,emacs会执行一条命令,中间通过keymap来实现
keymap中记录了一个键,到一个symbol,这个symbol的函数就是要执行的command

如果是C-xC-c这样的键序列是如何实现的呢?有个prefix keymap的概念.
一个keymap出去的symbol,那个函数可能是另外一个keymap,这种就是prefix keymap
比如通过keymap查C-x绑定的东西,发现绑定的符号是ctl-x-map,它不是一个函数而是另一个keymap,这时再按下C-c就会在这个keymap中继续查找

模式与keymaps

emacs默认有一个global的keymap.然后每个major mode会定义各自的local的keymap

各个minor mode也可能会定义keymap

minor mode定义的keymap会覆盖local的keymap键绑定,local的keymap又会覆盖global的keymap的键绑定

值得注意的是这个覆盖关系并没这么简单.在prefix keymap中会有一些不同

比如global keymap中C-x是绑定到了一个prefix keymap,然后我在自己的mode中的keymap中也把C-x定义到了一个prefix keymap

emacs查键的时候会两个keymap都查的,这样做的意义是不会因为mode的keymap屏蔽掉整个C-x开头的命令的使用.

自己的mode中定义了C-xC-f,没定义其它按键.这时C-xC-c还是可用的,minor -> local -> global这种屏蔽规则只是作用于command,而不作用于prefix keymap

evil的实现

我没具体看evil的源代码,但推测它的实现,应该是定义一个minor mode.
这个minor中又分了好几种state,就是vi对就的几种状态
每种state下有自己的keymap,切换state时这个minor mode就会切换到对应的keymap
又因为它是minor mode的,它优先级最高,会覆盖掉major mode和global的键绑定

像vi一样使用emacs

emacs的ctrl到死确实很受不了.我把大多数的keybind都改得更vi风格了.

  1. 首先是使用evil,这个不必说.
  2. 然后是把原来C-x开头的各种全局键,绑定用z开头的序列

    zf 代替C-xC-f zb 代替C-xb zB 代替C-xC-b 类似还有zk zw zc等等等

  3. 再定义了一些方便操作的全局键

比如org-mode的一些键定义成zo开头,zoa代表org-agenda这种

  1. 最后是把C-c开头的各种模式特定的键,改成s开头的序列

    se 代替原来各模式的C-xC-e sp 代替原来各模式的C-xC-p sn 代替原来各模式的C-xC-n

改完觉得爽多了…再在.bashrc中加入 alias vi='emacsclient -t -a ""'

然后就完美了

emacs