Practical Vim(1):The Vim Way
在本系列的第一篇博客,做一个说明,本系列是《Practical Vim》一书的笔记。这本书每一章讲述一个相关的Vim的操作主题,在每一章中都会以若干个Tip的形式讲述一下小的窍门或者说是实现某种任务的捷径,并且在这个过程中讲解很多Vim使用到的命令。作为一本成型的书来说,《Practical Vim》里面会有一些关于背景的描述,也会有一整套比较严谨的对于Vim输入命令以及显示结果的展示规则。我这里仅仅将每一个Tip涉及的问题,以及通过哪些命令来解决重点提取并且翻译出来,主要是总结备忘,另一方面也是分享。但是考虑到每一个Tip的标题都无法直译,因此我就不翻译了。最后,正所谓条条大路通罗马,每一个Tip中列出的命令都不见得是唯一方案,更不一定是最优方案(本书作者也是这么认为的)。
Tip1 Meet The Dot Command(使用.命令)
.命令可以重复上一次修改。我们先看看示例文本:
Line one Line two Line three Line four
我们可以使用x命令删除光标所在的字符。x删除一个字符就是一次更改。紧接着使用.命令就会重复上一次更改,也就是再次删除当前光标所在的一个字符。我们看一下书中给的演示(为了方便,这种演示我都截图):
此外,使用dd可以删除当前光标所在的行。.命令也可以重复这个操作。示例如下:
我们还可以使用>G来给当前行到文件末尾的所有行增加缩进,同样也可以重复上面的命令(个人感觉这个比较有用):
Tip2 Don’t Repeat Yourself
有这样一段js代码如下:
var foo = 1 var bar = 'a' var foobar = foo + bar
现在需要在代码的每一行的末尾都添加一个分号;。当然,我们可以将光标移到每一行的末尾(使用$),进入插入模式(a),然后输入;。但是问题是,这样的话过于麻烦。我们可以在第一行进行上述操作,然后每到下一行,使用.命令重复一下上次修改即可。示例如下:
在这个例子中,使用了组合命令A代替了命令序列$a。顺便说一下几个常用的组合命令:
Tip3 Take One Step Back, Then Three Forward(退一进三)
有这样一行js代码:
var foo = "method("+argument1+","+argument2+")";
这段代码做了几次字符串拼接操作。但是看起来很不爽,一般来说,会在+前后各加上一个空格。我们现在就需要完成这个任务。我们先直接展示操作过程,再分别讲解:
首先通过f+命令找到(从左到右找)当前行的第一个+字符,s空格+空格,将光标所在的这个字符修改为空格+空格。接下来找到下一个+字符,再使用.重复上一次修改,以此类推。我们在进行第二次查找+字符时,没有继续使用fx,而是使用了;。这是因为;可以重复上一次f命令所执行的查找操作。也就是说,这里的;实际上是重复了上一次fx操作。另外需要说明的是,f{char}可以在当前行从左往右查找{}内包含的字符,并且光标直接定位到找到的第一个字符。上面这个方案肯定不会是最好的方案,个人认为作者在这里讲这种方案纯粹是为了配合这一样Repeat的主题。
Tip4 Act, Repeat, Reverse
上面提到的.命令主要是重复上一次修改,而;却可以重复上一次查找以及移动。当我们面对重复性的工作时,比较好的一个策略是将移动和修改都变得可重复。这个Tip主要讲的就是如何重复各种上一次操作。
我们逐一解释:
当我们进行了一些编辑操作后,回到一般模式,使用.可以重复上一次修改,使用u可以撤销(相当于Windows下很多文本编辑器的ctrl+z)
f{char}或者t{char}从左往右找字符。那么;重复上一次查找与光标移动而,则可以执行一次反向查找与移动操作
F{char}或者T{char}从右往左找字符。那么;重复上一次查找与光标移动而,则可以执行一次反向查找与移动操作
/pattern<CR>。这个命令可以使用pattern这个模式来查找文本中匹配的串,并且跳转过去。使用n可以重复上一次查找(正向,从上往下找),N则可以进行一次对应的反向查找(从下往上)
?pattern<CR>。与上面相反。
:s/target/replacement这个命令在文本中找到target模式所匹配的文本,以replacement对应的字符串替换,可以使用&来重复一次,使用u撤销上次替换
qx{changes}q这个比较复杂。q实际上本身是一个记录命令,这里的x相当于是一个变量名,可以换成y,z等等。当输入qx之后,Vim的最下方会出现“记录中”,表示开始记录操作。紧接着你再进行的一系列键入操作,都会被记录在x这个变量所对应的寄存器里面。直到再按下q键,这一次记录操作算是完成。也就是说{changes}所对应的一系列编辑操作都被保存进了x对应的寄存器。接下来,你可以使用@x来重复x对应寄存器中保存的一系列操作。说了这么一堆,不是很好理解,这里我补充一个例子。
Vim原始屏幕如下:
我们先输入qy,紧接着Vim屏幕变化如下:
接着我输入a(在光标后面进入插入模式),Vim屏幕变化如下:
这说明我们进入了插入模式,并且这个操作被记录了,接下来我们输入真正要被写进去的字符,比如xxxxxx再看Vim屏幕的变化:
我们看到,我们输入的xxxxxx已经在字符e后面添加进去了,现在我们输入<ESC>来退出插入模式。我们再看Vim屏幕:
我们看到已经退出插入模式了,我们再按q键停止记录,再看看Vim屏幕:
已经停止记录了。到此为止,我们前面说的qy{changes}q命令算是输入完了。接下来是使用的问题。我们输入j$先跳转到下一行末尾,然后输入@y我们看看效果:
可以看到,我们寄存在y对应寄存器中的一系列编辑操作被重复执行了一次。以上就是补充的这个命令的一个解释。
Tip5 Find and Replace by Hand(手动查找和替换)
现在有这样一段话:
...We're waiting for content before the site can go live... ...If you are content with this, let's go ahead with it... ...We'll launch as soon as we have the content...
现在我们需要用copy来替换content。Vim提供了:substitute命令来进行替换操作,这个命令还有选项能提示我们对于找到的每一个单词是否替换。但是在这里并不介绍这个单词。我们先看一下作者在这里使用什么样的方案:
首先通过/content找到第一个content单词,使用*命令。*命令能够查找最近的一个光标所在的单词,也就是content,然后使用cwcopy命令修改这个单词为copy,然后使用n执行上一次查找操作,使用.重复上一次修改。依次类推。
Tip6 Meet the Dot Formula
这个Tip里没有介绍新的命令,只是总结了一下使用.命令的通用情况。这里不再赘述。
save me from myself