手指疼,写点代码缓解一下

我经常使用Emacs来干写字的活——有时候是写代码、有时候是用org-mode管理待办事项、有时候是用restclient-mode来测试HTTP API。Emacs丰富的快捷键让我可以双手不离主键盘区就做到很多事情,不过这也带来了别样的烦恼:快捷键按多了,手容易累。

导致手累的第一个因素,是Emacs的不少快捷键需要按住ctrl来使用,而ctrl常常不容易按到。以我的键盘为例,ctrl键分布在主键盘区的最外侧

为了便于尾指按到两侧的ctrl键,我在macOS中交换了commandcontrol键的效果

当需要按住两边的ctrl键(实际按下的是上面照片中的Windows图标键)时,手腕需要往外拐过去。这个问题在使用VSCode时同样存在,因为我在VSCode中用的也是Emacs的键映射。

第二个因素是Emacs的一些快捷键太繁琐,导致使用时双手像在键盘上起舞一般到处按来按去,敲击次数过多。例如,让光标上下左右移动的快捷键分别是ctrl-pctrl-nctrl-b,以及ctrl-f,这比直接用键盘上的方向键麻烦得多。有一些功能甚至要按三组快捷键,比如org-clock-out要先按ctrl-c,再按ctrl-x,最后按ctrl-o

有没有办法既可以保留快捷键的高效,又尽量地减少击键导致的手腕和手指的疲劳呢?

当然有。

在Emacs中改用Vim的快捷键

既然Emacs默认的快捷键不容易按,那么不妨换成Vim风格的快捷键。同样是上下左右移动光标,在Vim中只需要单击k/j/h/l这四个按键即可,不仅能够单手操作,而且这四个键正好是右手”触手可及“的位置。其它的功能,例如在文件内搜索、保存文件等,也只需要按/:w即可,比起Emacs真是”finger-friendly“得多了。

那么如何才能在Emacs中用上Vim的快捷键呢?答案是用evil插件。先用包管理器安装它

M-x package-install RET evil RET

然后在Emacs的启动配置文件中添加启用evil-mode的代码

(require 'evil)
(evil-mode 1)

现在便可以在Emacs中使用Vim风格的快捷键了

定制evil-mode

只是简单地启用evil-mode还不足以将双手从频繁的按ctrl中解放出来,因为在Emacs中还有不少其它的高频快捷键依赖于ctrl,例如用ctrl-x b来切换到其它的buffer中、用ctrl-x ctrl-f来打开或新建一个文件,甚至是用ctrl-c ctrl-x ctrl-o来停止一个任务的计时器。

就像在数据压缩中,用较短的串来代替出现频率较高的原始字符串一样,对于高频使用且快捷键较长的功能,可以为它们绑定较短的快捷键。在evil-mode中,g是一个前缀键并且也很好按,所以我把一些重度使用的功能都绑定了在了以它为前缀的快捷键上

;;; evil-mode相关的键绑定
(evil-global-set-key 'normal (kbd "g b") 'ido-switch-buffer)
(evil-global-set-key 'normal (kbd "g f") 'ido-find-file)
(evil-global-set-key 'normal (kbd "g o") 'org-clock-out)
(evil-global-set-key 'normal (kbd "g s") 'cuckoo-org-schedule)
(evil-global-set-key 'normal (kbd "g t") 'org-todo)
(evil-global-set-key 'normal (kbd "s") 'save-buffer)

在VSCode中改用Vim的快捷键

搬砖的工具是VSCode,用来写Node.js的项目,主要是因VSCode在写Node.js代码这方面确实比Emacs的js-modejs2-mode,以及tide-mode之流要好用那么一点。在VSCode中我也改用了Vim的键映射,只需要在插件市场中点击安装即可

VSCode的Vim键映射实际上是一个独立的插件Vim,它也支持进一步地自定义快捷键。出于个人喜好,我把s绑定为保存文件的功能

// VSCode的配置文件setting.json
"vim.normalModeKeyBindings": [
  {
    "before": ["s"],
    "commands": [
      "workbench.action.files.save"
    ]
  }
],

用BetterTouchTools补充evil-mode的不足

尽管在Emacs中可以将常用的功能绑定到一系列的、以g开头的较短的快捷键上,但这一招并不能用来处理所有的快捷键,因为太多的自定义快捷键也会带来记忆上的负担。但我不会就此止步。

仔细观察就会发现,多数较长的快捷键是以ctrl-cctrl-x作为前缀的。因此,如果能够让ctrl-cctrl-x更容易按——比如替换为单个按键,也有利于减少尾指按ctrl键的负担。

要用单键来代替ctrl-c,光凭Emacs其实也可以做到。比如可以让F10被按下的时候相当于按下ctrl-c

(defun simulate-C-c ()
  "模拟输入C-c"
  (interactive)
  (setq unread-command-events (listify-key-sequence "\C-c")))
(global-set-key [f10] 'simulate-C-c)

问题在于它不可组合。

例如,先按F10再按ctrl-x,等价于按下ctrl-c ctrl-x。但如果先按ctrl-x再按F10,则Emacs不会再将F10转换为ctrl-c,它只会认为我按下的是ctrl-x F10的键序列。

既要用F10代替ctrl-c,又要具备可组合性,怎么办?我的答案是使用BetterTouchTool。我用BTT将F9F12都重定义了一遍

如此一来,当我需要输入复杂的、含有ctrl-cctrl-x的快捷键的时候,只需要单击一次F10F11就足够了,轻而易举!

遗憾的是,BTT是一款macOS only的软件。

后记

或许脑机接口才是缓解手指劳损的终极解决方案吧。

阅读原文

你可能感兴趣的