之前一直嫌贵没有买的《vim 实用技巧》终于蹭着公司经费买了下来,看完之后简直像打开 新世界大门。

上一篇 vim 的使用姿势 里面说过,个人认为背 vim 指令其实还挺没趣的,但是现在发现,自己的词汇量实在是太少 了。很多命令确实是没想到,比如 ; 之前一直被我当成 map leader 来用,但其实在行 内查找的时候,作用还是很大的。

构造可重复的模式

虽然之前也知道,用 vim 提高效率的方法就是减少重复的输入,但是由于不知道 . 命令 (对的,我的 vim 词汇量太可怜了)并没有领悟到精髓。 之前只是用各种 map 减少常用的输入,用宏解决量比较大的操作,但使用最最频繁的操作, 却还是带着很多的重复输入,也就是没有构造可重复模式的意识。

.范式

. 的功能是重复上一个修改,那什么称为一个修改呢,比如果你从进入 insert 模式开始到退出 insert 模式中间的修改都被当成一个修改,u 指令撤销的粒度也是跟这个一样。 那为了方便地使用 . 命令,我们最好把想做的事情限定到一次修改中。 之前修改的时候使用的都是删除指令(dx)然后再插入(ia) 但其实是可以压缩成 c 指令和 s 的(没错,我之前连 c 都不知道)。 减少了一次按键当然提高效率,但更重要的是这样删除和插入就都被囊括到一次修改中了, 可以使用 . 来方便地重复。既然是重复操作,也很少会在同一个地方执行,中间一般会伴随有移动。 同样的,最好能把移动也限定到一个按键的范围内。这样就可以 {位置}{操作} 两个键轮流按重复下去了。

比如说现在想要把文件里面的 this 改成 $this 用来表示 jQuery 元素,但并不是所有的都要改, 毕竟 this 还有其他使用的情景,须要联系上下文决定修改。这时候就可以用到上面说得技巧了, 先用 **/\v** 查找 文件中的 this,在第一个须要修改的 this 上输入 **cw$this** 完成修改。接下来就可以使用 **n.** 来进行相同的修改了,当 **n** 移动到不像修改的地方, 只要不按 **.** 就好了。这就是所谓的 **.范式**。

更大的范围

.范式在平常的批量修改中使用频率还是挺高的,但毕竟单纯的模式匹配,只在一个文件内部生效。 如果说遇到说,技术部门定了新的编码规范,须要改一下老代码这种情况,修改量可是非大的, 涉及的文件数量也很多,光用上面所说的技巧就不够了。我们须要扩大重复模式的范围。

vim 的缓冲区可以储存多个文件到内存中,同时也提供了对他们进行批量操作的方法,比如 :argdo:bufdo 命令,分别是对参数列表中和缓冲区中的文件批量执行命令。 而 vim 的命令中又有一条 :normal 命令,可以让我们在指定范围使用 vim 普通模式命令。 将这些组合到一起,就可以批量的在文件中执行普通模式的命令了。

比如我须要在所有 js 文件头部加上一个 author 的注释。可以这么做,在静态资源目录打开 vim 使用 :args 命令以及它支持的 Glob 模式,比如这样 :args script/*.js,把所有 js 文件载入到参数列表中。然后设定好操作内容 **qqggI// author: xxxq** 到 q 寄存器, 接着使用 **:argdo normal @q** (当然要记得提前设置 hidden 选项)。

指定的范围

批量修改有时候也不能满足我们的需求,有时候我们须要更精确的范围指定。 比如说我们有一个 html 文件,像下面这样

<body>
    <a href="">somthing lowcase</a>
    <p>
        <span></span>
        <a href="">other string lowcase</a>
    </p> 
<body>

我们想把所有 a 标签里面的文字转成大写。虽然大写转换是一个可以重复的操作,但是操作并不是全局的, 也不能压缩成一个简单的修改(如果单纯在可是模式下用 . 的话就会体会到可视模式在这种情况下的诡异表现)。

首先压缩操作到一个步骤可以简单地使用宏做到,qqvitUq 对于这个例子已经足够了。 那怎么确定操作的影响范围呢,使用上面讲 .范式 时讲到的查找技巧也可以做到。 但这样毕竟每有一个匹配就须要按一次 n. 也是不小的负担。这时候就须要 :global 命令帮忙了,此命令的功能是在匹配模式的行上执行 vim 命令行命令,融合了模式匹配与命令执行两大功能。 我们先写一个 a 标签的匹配,比如这样 /<a[^>]>.<\/a> 在本例中就已经够了, 然后执行 :g /<a[^>]*>.*<\/a>/ normal @q] 就可以通过匹配来执行 normal 状态下的宏命令了。

:wq

说到底,还是要培养构造重复模式的意识,大批量的修改自己能想到用各种方法减少输入, 但平时的小操作其实还是有很大的提高空间,没有仔细的研究,手指跑的比脑子快了,得改改。