1. 点命令

在编辑文本时,我们应该尽可能地避免重复的动作。在这一章节中,你将会学习如何使用点命令来重放上一个修改操作。点命令是最简单的命令,然而又是减少重复操作最为有用的命令。

2. 用法

正如这个命令的名字一样,你可以通过按下.键来使用点命令。

比如,如果你想将下面文本中的所有”let“替换为"const":

let one = "1";
let two = "2";
let three = "3";

首先,使用/let来进行匹配。接着,使用cwconst<esc>来将"let"替换成"const"。第三步,使用n来找到下一个匹配的位置。最后,使用点命令(.)来重复之前的操作。持续地使用n . n .直到每一个匹配的词都被替换。

在这个例子里面,点命令重复的是cwconst<esc>这一串命令,它能够帮你将需要8次输入的命令简化到只需要敲击一次键盘。

3. 什么才算是修改操作?

如果你查看点命令的定义的话(:h .),文档中说点命令会重复上一个修改操作,那么什么才算是一个修改操作呢?

当你使用普通模式下的命令来更新(添加,修改或者删除)当前缓冲区中的内容时,你就是在执行一个修改操作了。其中的例外是使用命令行命令进行的修改(以开头的命令),这些命令不算作修改操作。

在第一个例子中,你看到的cwconst<esc>就是一个修改操作。现在假设你有以下这么一个句子:

pancake, potatoes, fruit-juice,

我们来删除从这行开始的位置到第一个逗号出现的位置。你可以使用df,来完成这个操作,使用.来重复两次直到你将整个句子删除。

让我们再来试试另一个例子:

pancake, potatoes, fruit-juice,

这一次你只需要删除所有的逗号,不包括逗号前面的词。我们可以使用f,来找到第一个逗号,再使用x来删除光标下的字符。然后使用用.来重复两次,很简单对不对?等等!这样做行不通(只会重复删除光标下的一个字符,而不是删除逗号)!为什么会这样呢?

在Vim里,修改操作是不包括移动操作(motions)的,因为动作不会更新缓冲区的内容。当你运行f,x,你实际上是在执行两个独立的操作:f,命令只移动光标,而x更新缓冲区的内容,只有后者算作修改动作。和之前例子中的df,进行一下对比的话,你会发现df,中的f,告诉删除操作d哪里需要删除,是整个删除命令df,的一部分。

让我们想想办法完成这个任务。在你运行f,并执行x来删除第一个逗号后,使用;来继续匹配f的下一个目标(下一个逗号)。之后再使用.来重复修改操作,删除光标下的字符。重复; . ; .直到所有的逗号都被删除。完整的命令即为f,x;.;.

再来试试下一个例子:

pancake
potatoes
fruit-juice

我们的目标是给每一行的结尾加上逗号。从第一行开始,我们执行命令A,<esc>j来给结尾加上逗号并移动到下一行。现在我们知道了j是不算作修改操作的,只有A,算作修改操作。你可以使用j . j .来移动并重复修改操作。完整的命令是A,<esc>j.j.

从你按下输入命令(A)开始到你退出输入模式()之间的所有输入都算作是一整个修改操作。Vim不仅允许你控制需要添加的文本的内容,还允许你控制在什么位置添加文本。你可以在选择在这些位置进行输入:光标位置前(i),光标位置之后(a),在下方插入一行(o),在上方插入一行(O),在当前行的末尾(A),或者在当前行的开始位置(I)。如果你想复习一下相关内容的话,可以看看输入模式(Insert Mode)这一章节。

4. 重复多行修改操作

假设你有如下的文本:

let one = "1";
let two = "2";
let three = "3";
const foo = "bar";
let four = "4";
let five = "5";
let six = "6";
let seven = "7";
let eight = "8";
let nine = "9";

你的目标是删除除了含有"foo"那一行以外的所有行。首先,使用d2j删除前三行。之后跳过"foo"这一行,在其下一行使用点命令两次来删除剩下的六行。完整的命令是d2jj..

这里的修改操作是d2j2j不是一个移动操作,而是整个删除命令的一部分。

我们再来看看下一个例子:

zlet zzone = "1";
zlet zztwo = "2";
zlet zzthree = "3";
let four = "4";

我们的目标是删除所有的'z'。首先,在块可视化模式下使用Ctrl-vjj来选中前三行的第一个'z'字母。如果你对块可视化模式不熟悉的话也不用担心,我会在下一章节中进行介绍。在选中前三行的第一个'z'后,使用d来删除它们。接着用w移动到下一个z字母上,使用..重复两次之前选中加删除的动作。完整的命令为Ctrl-vjjdw..

你删除一列上的三个’z‘的操作(Ctrl-vjjd)被看做一整个修改操作。可视化模式中的选择操作可以用来选中多行,作为修改动作的一部分。

5. 在修改中包含移动操作

让我们来重新回顾一下本章中的第一个例子。这个例子中我们使用了/letcwconst<esc>紧接着n . n .将下面的文本中的'let'都替换成了'const'。

let one = "1";
let two = "2";
let three = "3";

其实还有更快的方法来完成整个操作。在删除的时候,并不使用w,而是使用gn

gn是向前搜索和上一个搜索的模式(本例中为/let)匹配的位置,并且自动对匹配的文本进行可视化模式下的选取的移动操作。想要对下一个匹配的位置进行替换的话,你不再需要先移动在重复修改操作(n . n .),而是简单地使用. .就能完成。你不需要再进行移动操作了,因为找到下一个匹配的位置并进行选中成为了修改操作的一部分了。完整的命令为/letdgn..

当你在编辑文本时,应该时刻关注像gn命令这种能一下子做好几件事的移动操作。

6. 聪明地学习点命令

点命令的强大之处在于使用仅仅1次键盘敲击代替好几次敲击。对于x这种只需一次敲击键盘就能完成的修改操作来说,点命令或许不会带来什么收益。但是如果你的上一个修改操作是像cgnconst<esc>这种复杂命令的话,使用点命令来替代就有非常可观的收益了。

在进行编辑时,思考一下你正将进行的操作是否是可以重复的。举个例子,如果我需要删除接下来的三个单词,是使用d3w更划算,还是dw再使用.两次更划算?之后还会不会再进行删除操作?如果是这样的话,使用dw好几次确实比d3w更加合理,因为dw更加有复用性。在编辑时应该养成“修改操作驱动”的观念。

点命令非常简单但又功能强大,帮助你开始自动化处理简单的任务。在后续的章节中,你将会学习到如何使用Vim的宏命令来自动化处理更多复杂的操作。但是首先,还是让我们来学习一下如何使用寄存器来存取文本吧。

Copyright © Kilvn 2021. all right reserved,powered by Gitbook最后更新时间: 2021-10-12 17:14:24

results matching ""

    No results matching ""