macOS 下的 vim 如何充分利用 command 按键?

2016-11-06 19:26:27 +08:00
 tracyone
在终端下的 vim ,我想为 command 按键映射一些按键,但是发现 command 按键被 terminal.app 占据了好几个....

怎么把 terminal.app 与 command 相关的按键都给去掉??
3149 次点击
所在节点    Vim
9 条回复
ashfinal
2016-11-06 20:36:42 +08:00
我做按键映射时还专门避开了这类按键。。。
包括 option/alt 、 shift 还有 F1-F12 等 按键不够用嘛?为啥非要用 command 键
tracyone
2016-11-06 21:06:50 +08:00
@ashfinal 离大拇指比较近啊。
wsdjeg
2016-11-08 21:27:41 +08:00
@tracyone 用 neovim ,支持映射 command 按键,
wsdjeg
2016-11-08 21:28:20 +08:00
同时还支持很多映射组合, alt 什么的也比 vim 做的好
tracyone
2016-11-08 21:50:19 +08:00
@wsdjeg 你说的支持是啥意思? vim 这边也支持啊,只不过和 terminal.app 冲突了,然后就用不了了。

比 nmap <D-s> :wa<cr>,这样的话由于 terminal.app 也有这样的,所以搞不定。
ashfinal
2016-11-09 20:56:44 +08:00
@tracyone 可是。这样就不能跨平台用了啊
而且相对于组合键,我更偏向于单键序列
tracyone
2016-11-09 21:28:21 +08:00
@ashfinal 我有办法跨平台,非 mac 用 ctrl,mac 用 command.
ashfinal
2016-11-10 19:37:23 +08:00
@tracyone 按键不统一很蛋疼的 (手动斜眼
skywind3000
2016-11-19 02:11:57 +08:00
最简单的做法是,在 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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/318520

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX