最简单的做法是,在 iTerm 里面配置->键盘->添加一个映射,将 CMD+X 映射成 “发送以 ESC 开头的字符串"
然后填写字符串内容为:"]{1}X~" ,意思是当你按下 CMD+X 时, iterm 将向终端发送字符串:
"\033]{1}X~"
然后你就可以在 VIM 里面把那一串字符串当成一个连续击键动作了:
noremap <ESC>]{1}X~ (你的命令)
这样你在 iTerm/
Terminal.App 里面按下 CMD+X ,终端里面的 Vim 就能做出正确的反应。
然后你会发现,其实你只要手速够快,连续按下:<ESC>, ], {1}, X, ~ 也能触发该操作,(在 timeout 值内连续按下)
所以我们设置后面的那串字符串第一个字符为 "]" 的意思就是,正常操作 Vim ,不大可能按了 ESC 以后一秒以内(默认 timeout )马上又按下 "]"。即便按下了,也不大可能再次马上按“{”,
如此,“<ESC>]{1}?~” 基本上是正常操作里面不可能一秒内出现的字符串,用于表示你的 CMD+X 再合适不过。
就像你不设置 ttimeout, ttimeoutlen ,然后快速的在 VIM 里面按下 <ESC>OP , Vim 将会以为你按下了 <F1>一样,
因为 F1 的终端下字符串序列就是 <ESC>OP ,而你在 Insert 模式下面马上<ESC>退出并按下大写 O ,向上插入一行,
Vim 将会等待一秒钟(默认 timeout ),确认后面没有一个 P ,才会进一步确认,不是 F1 ,而是向上插行。
所以上面用 "\033]" 开头就是避免出现这种情况
进一步,终端下设置 ALT 键时也可以用这种序列,比如所有 ALT 组合键在 securecrt/xshell/iterm 下可以设置发送
“\033]{0}X~” 形式的字符串,然后按照上面方法映射,不过,还有更好的方法,直接在终端下:
noremap <M-X> (命令)
exec "set <m-X>=\e]{0}X~"
这样就可以告诉 Vim ,<m-x>这个键的终端码为:"<ESC>]{0}X~"
然后你把 ttimeout 打开,并且把 ttimeoutlen 设置为 100 毫秒,
如此,万事大吉了,绝对不可能有手速可以在 100 毫秒内连续敲入上面几个按键,
你可以理解成,你从终端到 Vim ,重新定义了一个新的键盘码。
设置成一个新键盘码而不是直接 map 那串<ESC>开头的字符串,好处在于,可以让 Vim 知道这是一个完整按键
可惜的是,你在终端下不能象设置<M-X> 一样设置<D-X> 的键盘码,你 set <D-X> vim 会报错,可能那部分处理代码并没有加入对 <D-X>的支持,不过没事情。还有几个键盘上从来没有出现过的按键给你使用,那就是
<F13> - <F37> 一共有 25 个虚拟功能键给你使用,足够你用了吧?
最终的方法为:
在 iterm 下,新增设置 D+X 为发送以 <ESC>开头的字符串,字符串内容为:“]{1}X~”
在 Vim 中:
noremap <F13> (命令)
exec "set <F13>=\e]{1}X~"
好了,你可以自由的在终端下使用你的 CMD 了。
然后可以覆盖 iterm 下面的按键,同时,你链接到其他服务器上使用 vim ,只要你 iterm 里有这个配置,就都能使用。
不限于 Mac