Use keycode in terminal and vim

Vim 的按键映射在 GUI 情况下的支持是相当完备的, 例如 <M-...>, <D-...>, 但是如果 vim 处于 terminal 中, 那么就需要做额外一些处理
terminal 中的 vim 接受的按键是经过 terminal 处理的, 换句话说, 如果在 terminal 中就不能正确接受到一个按键组合, 那么 运行在 terminal 上的 vim 是不可能获得正确事件并作出相应动作的
keycode
我们做映射的关键就是理解 keycode 在 terminal 到 vim 的传递及转化
terminal key code:^[[1;2A,^[表示ESCvim key code:,<S-Up>, Vim 的 keycode 具有字面含义, 因为他要运行在不同的系统上
查看方式
terminal: 使用cat或sed -n l等支持管道的命令, 然后直接按下按键组合即可显示vim: 在命令模式下使用<C-v>key可显示当前按键组合在 vim 中所产生的字符序列
vim 支持的 keycode
总的来说, vim 支持
<F1>~<F37><S-F1>~<S-F37><C-Home>,<C-End><S-Home>,<S-End><S-a>~<S-z><C-a>~<C-z><A-a>~<A-z>-…
默认情况下, 以下的 keycode 是没有使用的, 我们可以映射为以下按键
<S-F1>~<S-F12><F13>~<F37><S-F13>~<S-F37><xF1>~<xF4><S-xF1>~<S-xF4>
set vim internal keycode
首先我们在终端中将我们需要的按键的 terminal keycode 获得, 然后在 vim 中使用 set 来绑定 vim keycode, 最后使用 map 对该 vim keycode 进行映射
:set <S-Down>=^[[1;2B:^[表示ESC, 将终端产生的term keycode绑定为 vim 的<S-Down>:set <C-S-Down>=^[[1;6B: 错误! 因为 vim 不支持这样的keycode:map <Esc>[1;6B <C-S-Down>: 使用这种方式可以避免上个的错误, 这样是将term keycode转换为了vim keystrokeexecute "nmap \ed-r <D-r>": 使用<ESC>d-r序列进行映射, 将term keycode转换为了vim keystrokenmap <lt>D-r> <D-r>: 直接用<D-r>字符串进行映射, 将term keycode转换为了vim keystroke:set <S-Down>={C-v}{Esc}[1;2B: 使用字面意义进行绑定,{}表示真实的按键所产生的结果:set <S-Down>={C-v}{S-Down}: 同上
当我们在
term keycode->vim keycode这一步不允许时, 可以转变思路为term keycode->vim keystroke当我们写脚本时, 不能使用set <C-S-Down>=^[[1;6B, 需要使用execute "set <C-S-Down>=\e[1;6B"
一些错误写法示范
:set <F13>=^[[1;2B,:map <F13> <S-Down>: 多余,<S-Down>默认已经被vim keycode支持了, 不需要使用<F13>, 直接:set <S-Down>=^[[1;2B:map <C-{C-v}{BS}> <C-BS>: 不正确,{C-v}{BS}可以使用<C-^?>代替, 不需要再使用没必要的映射
ASCII 标准键盘字符码表

如何从 MacVim 中映射 command 与 option
默认下, MacVim 支持设置 <D-...> 的 map 使用 ⌘ 键与其他按键的组合, 设置 set macmeta 后可以用 <M-...> 来表示 ⌥ 键与其他按键的组合
因为有一些 ⌘ 组合键已经被 MacVim 预定义了, 我们可以使用 macmenu &File.Print key=<nop> 的方式移除快捷键, 然后定义自己的动作
如何从 iterm 中映射 command 与 option
本文讲的就是如何让 terminal 中发射的字符被 vim 正确利用. 在理解了以上文章的基础上, 我们可以使用任何终端进行自定义, 针对于 iterm2, 我们可以这样

当然, iTerm2 还支持一个选项: Send Test with "vim" Special Chars, 这个选项用来法 <C-...> 系列的按键还是可以的, 但是对于 <D-...> 按键来说则不生效, 如果要使用, 我们还是需要将 term keycode 转为 vim keystroke

这样使用 <D-b> 的话就和直接 Send Text 没什么区别了
未知问题
set <D-r>=...会报错
参考
本博客文章采用 CC 4.0 协议,转载需注明出处和作者。
