Vim中的宏:自动化魔法

清明节闲着没事写点Vim的东西。我对Vim有诸多怨念,不过Vim有几个地方我很喜欢,最重要的一个就是操作可以组合和自动化。

宏的魔法世界

宏可以完成很多自动化的操作,不过相比自动化,更迷人的是像写代码一样编辑文本。有一点元编程的画风,不过相比于模板元那种黑魔法,vim里的宏是人见人爱的白魔法。而且vim编辑文本的操作命令很简单,你要打印1000个 Hello, World!,不使用循环等高级功能,只需要将print这一行复制999次

1
print("Hello, World!")

用vim这很简单,只需要yy1000p这种组合命令就可以了。用别的编程语言生成这么1000行print都比把print直接放在循环里麻烦。

如果是很简单的重复操作,也不需要专门录制宏。比如:

. 重复上一个edit命令
; 重复上一个查找命令
& 替换下一个文本
@: 命令重复上一个Editor Command,这个我不常用,我喜欢上箭头选上一个然后回车

但是如果想连续执行一段;., 就需要用宏了(11;.的结果是先执行11次;再执行11次.)

如果要输出从1到1000,用vim的循环也可以完成

1
2
3
:for i in range(6)
: call setline(i, i.' '.getline(i))
:endfor

如果用宏来操作是这样的,Ctrl+aCtrl+x分别是对数字自增和自减,我们可以将操作分解成复制粘贴自增,然后重复998次就可以了

1
2
3
4
5
6
7
第一行输入1

qa 开始宏录制
yyp 复制并粘贴第一行
C-a 自增1
q 结束宏录制
998@ 重复998次,输出1-1000

稍微正经点的用途的例子

注释几行文本:

1
2
3
4
5
6
qa  开始宏录制
I# insert模式行首加#
Esc 退出insert
j 下一行
q 完成宏录制
7@a 注释7

同理,我们想要把开头序号1.都变成1)的样子

1
2
3
qa  q开始录制,保存到a寄存器中
0f. 跳转到开头并查找第一个.
j 跳转到下一行

大多数时候这种情况正则更方便,但是有的时候一堆混乱的文本容易误伤,宏的操作加入了位置信息等操作比较容易控制

1
2
3
4
1. X1..XX
2. SN.1FN
3. PIN.GF
4. 12 3.

这里举例子用宏加注释什么的,其实有很多操作并不需要宏来完成,比如注释有插件。

关于Vim的使用姿势

曾经几年前我对Vim实在说不上喜欢,当时我还在Windows上(Windows上的vim体验你也知道),经常要连到linux上改改东西的时候我日常使用nano(后来发现了micro)。如果只是将Vim当成一套键盘操作,那效率可能并不比IDE的快捷键+鼠标操作更好。(而且vim的hjkl的键位等操作,对很多人是极大的劝退)
Vim的键位用好了可以形成肌肉记忆将操作交给小脑解放大脑,而宏这些操作是要开动大脑的。
我觉得吸引玩家入坑vim就应该从录制宏等操作讲起,这些才是图形界面的点击操作不具备的优势。

宏适合干的就是重复的动作,比较适合处理一些枯燥的工作。比如经典的某些大道至简的语言sublime多光标实现泛型这样的事情,我们可以写一个宏去完成它。(其实我个人还是喜欢多光标)

Go Type Parameters in Sublime

【译】Vim 不需要多光标编辑功能
You don’t need more than one cursor in vim