用Vim写代码经常遇到的一个操作是:复制一个单词(或其他text object),然后到下一个(多个)地方用复制的单词替换某个单词。我以前在这个简单的操作上浪费了很多时间……因为y
yank之后,用d
+p
来粘贴,会粘贴出来d
删除的内容……好吧,今天学到两种更快速的方法,记一下,以及原理。
第1种:选中文本并替换
操作步骤如下:
- 使用
yiw
yank(复制的意思)要复制的文本 - 移动到要替换的文本
viwp
使用yank的文本替换选中的文本- 移动到下一个需要替换的文本
viw"0p
使用步骤1yank的文本再次替换
首先要了解的是Vim中的寄存器概念。Vim有很多寄存器,顾名思义,其实和CPU的寄存器差不多意思,你可以将内容临时存放在寄存器里面。在命令行模式下输入:reg
可以看到寄存器的名字以及目前保存的内容。例如:使用"ayy
将会把当前行yank(复制)到a
寄存器。"ap
可以粘贴出a
寄存器的内容。
"
寄存器是默认使用的寄存器。所以说,无论是用y命令复制,还是用d删除,还是我们使用viw”0p命令覆盖选中内容,内容都会保存到”寄存器。p粘贴默认也是粘贴的”寄存器的内容。1-9
寄存器保存了删除的行,使用dd
删除行就会保存到1
寄存器,然后再删除一行,1
寄存器就会被更新,之前1
寄存器的内容就会移动到2
,以此类推。0
表示最近yank或删除的,也就是说,无论是y
命令还是d
命令都会将“最近”的文本保存到0
寄存器。这就是第5步要使用"0p
的原因,因为"
寄存器的内容在第3部已经被覆盖了,所以我们要使用“最近yank的内容”就要指定0
寄存器。关于所有寄存器的种类和解释,可以参考这篇文章,解释的很好。也可以看Vim的文档: :help reg
。
另外一个细节是使用了yiw
来yank一个单词。这是用了Vim的文本对象,这样光标无论在单词首,还是在单词里面,都可以快速复制整个单词,而不用选中再复制。文本对象是Vim很强大的一个地方,这篇博客对文本对象介绍的很好。
第2种:使用.
重复操作
步骤如下:
- 使用
yiw
yank要复制的单词 - 移动到要替换的位置
ciw
CTRL-R0
ESC 进入编辑模式,使用CTRL-R快捷键在插入模式中粘贴出寄存器0
的内容并退回到Normal模式- 移动到下一个要替换的位置
- 使用
.
重复步骤3的操作
这个用到了CTRL-R,这个组合键在Normal模式下是Redo的意思(重做,和Undo是对立的,说白点就是和CTRL-Z对立),但是在插入模式(其实在命令模式同样有效)下就变成了强大的“粘贴寄存器内容到当前光标处”的意思。这里有个不错的、简短的解释。
另外使用了.
进行重复操作。这个点表示“重复上次在Normal模式下的操作”,也就是步骤3的全部。
最后,如果对整行进行替换的话,可以对方法1进行改良,使用V
来选中整行。
替换整行的步骤如下:
yy
yank要复制的一行- 移动到要替换的行
- 使用
Vp
选中当前行并进行替换 - 移动到下一个要替换的行
- 使用
V"0p
替换一行。