V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tracyone
V2EX  ›  Vim

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

  •  
  •   tracyone · 2016-11-06 19:26:27 +08:00 · 3126 次点击
    这是一个创建于 2699 天前的主题,其中的信息可能已经有所发展或是发生改变。
    在终端下的 vim ,我想为 command 按键映射一些按键,但是发现 command 按键被 terminal.app 占据了好几个....

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

    比 nmap <D-s> :wa<cr>,这样的话由于 terminal.app 也有这样的,所以搞不定。
    ashfinal
        6
    ashfinal  
       2016-11-09 20:56:44 +08:00
    @tracyone 可是。这样就不能跨平台用了啊
    而且相对于组合键,我更偏向于单键序列
    tracyone
        7
    tracyone  
    OP
       2016-11-09 21:28:21 +08:00
    @ashfinal 我有办法跨平台,非 mac 用 ctrl,mac 用 command.
    ashfinal
        8
    ashfinal  
       2016-11-10 19:37:23 +08:00
    @tracyone 按键不统一很蛋疼的 (手动斜眼
    skywind3000
        9
    skywind3000  
       2016-11-19 02:11:57 +08:00   ❤️ 1
    最简单的做法是,在 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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2746 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 00:23 · PVG 08:23 · LAX 17:23 · JFK 20:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.