带 Touch Bar 的老款 MacBook Pro,它的 Esc 是不可能习惯的了了,对于喜欢 vi-mode 的用户来说,解决这个问题,有两个办法:一是使用 + [;二将其他按键映射成为 Esc。这里从个人习惯出发,整理一下收集到的第二种方式,覆盖了这些 vi-mode:ZSH、VIM、VS Code、iPython、以及 Jupyterlab。

ZSH

在 .zshrc 当中增加如下内容即可,注意后面的 timeout 不要设置为0,不然按键起不了作用。

bindkey -v
bindkey -M viins jj vi-cmd-mode
KEYTIMEOUT=25

开启和设定 vi 模式比较简单,麻烦的是配置响应 vim 模式的光标样式。我的日常情况是这样:Alacritty 终端默认启动一个 Tmux,运行 Zsh。一直以来,Esc 和光标,总有小问题,比如 Esc 突然响应不及时、卡死,光标突然不跟随模式而改变形状了。一番折腾,目前最推荐这个写法,使用时间不长,但暂时还没发现什么问题。

VIM

我用的 Neovim,只是配置文件名跟 Vim 不一样,写法是同样的。注意第二行,它的目的,是在两个 j 之间设定一个较短的等待时间,尽量缓解 j j 是正常输入不是模式切换时的停顿感。

inoremap jj <Esc>
:autocmd InsertEnter * set timeoutlen=200
:autocmd InsertLeave * set timeoutlen=1000

VS Code

偏好设置当中搜索或直接在 settings.json 中加入以下内容即可。

"vim.insertModeKeyBindings": [
     {
         "before": ["j", "j"],
         "after": ["<esc>"]
     }
]

这里还有一点问题,中文输入模式下按下这两个键,会有混乱情况出现。比如,可以拿小鹤双拼输入 jpjt(解决)试试看。

iPython

创建或修改 ~/.ipython/profile_default/startup/keybindings.py

from IPython import get_ipython
from prompt_toolkit.enums import DEFAULT_BUFFER
from prompt_toolkit.filters import HasFocus, ViInsertMode
from prompt_toolkit.key_binding.vi_state import InputMode

ip = get_ipython()

def switch_to_navigation_mode(event):
   vi_state = event.cli.vi_state
   vi_state.input_mode = InputMode.NAVIGATION

if getattr(ip, 'pt_app', None):
   registry = ip.pt_app.key_bindings
   registry.add_binding(u'j',u'j',
                        filter=(HasFocus(DEFAULT_BUFFER)
                                 & ViInsertMode()))(switch_to_navigation_mode)

Jupyterlab

可以使用这个插件 jupyterlab-vimrc 来自定义需要的键位。比如,在偏好设置的 vimrc 内添加以下内容即可模拟 j jEsc

"imap": 
  [
      ["jj", "<Esc>"],
  ]