小改动¶
本章介绍几种修正和移动文本的方法,这包括三种修改文本的基本方法: 操作符-动作,可视模式以及文本对象。
操作符与动作¶
dw 命令删除一个单词。你可能认出来了, w 是词移动命令。实际上, d 命令后面可以跟任何“动作” (motion) 命令,它会删除从当前位置到光标移动到的目标位置的全部内容。
例如 4w 命令能够向后移动四个单词。所以 d4w 命令删除 4 个单词。
To err is human. To really foul up you need a computer.
------------------>
d4w
To err is human. you need a computer.
dw 只删除从当前光标位置到目标光标位置的前一个字符。如果你用 de 命令删除字符到单词结尾,这时会删掉整个单词(包括最后一个字符):
To err is human. you need a computer.
------->
d2e
To err is human. a computer.
删除时是否包括光标所在的字符取决于你使用的移动命令。当不包括这个字符时,称为“非包含的”(exclusive),而包括这个字符时,称为“包含的”(inclusive)。
$ 命令移动到行尾。所以, d$ 命令从当前的位置一直删除到本行行尾。这是一个“包含的”命令,所以,这行的最后一个字符也会被删除:
To err is human. a computer.
------------>
d$
To err is human
以上定义了一个命令组合模式: 操作符-动作 。你首先输入一个操作符命令,例如, d 就是一个删除操作符。然后你输入一个动作命令,例如 4l 或者 w 。这种方法使你可以在任何你能越过的文本上执行各种操作。
修改文本¶
另一个操作符命令是 c ,表示修改 change。它的作用方式与 d 操作符相似,只是完成后会切换到插入模式。例如, cw 修改一个词,更精确的说:它删除一个词,并切换到插入模式。
To err is human
------->
c2wbe<Esc>
To be human
这里 c2wbe<Esc> 包括如下操作:
- c 修改操作符
- 2w 移动两个单词的距离(与操作符组合起来,它删除两个单词并进入插入模式)
- be 插入 be 这个单词
- <Esc> 切换回普通模式
注解
如果留意观察会发现一个奇怪的地方: human 前面的空格没有被删除。 c 操作符在很多地方都和 d 一样,但有一个例外, cw 实际上像 ce 一样,删除到单词尾,这样单词后面的空格就不包括在内了。这要追溯到使用 Vi 的旧日子。由于很多人已经习惯了这种方式,这个不一致之处就留在 Vim 里了。
更多的修改命令¶
像 dd 可以删除一行一样, cc 修改一整行,但它会保留这一行的缩进(前导空格)。
d$ 删除到行尾; c$ 则修改到行尾。这相当于先用 d$ 删除一行再用 a 启动插入模式,以便加入新的文字。
快捷键¶
有些 操作符-动作 命令由于经常被使用,所以被设置为单字符命令:
x表示dl(删除当前光标下的字符)X表示dh(删除光标左边的字符)D表示d$(删除到行尾)C表示c$(修改到行尾)s表示cl(修改一个字符)S表示cc(修改一整行)
在什么地方加入计数前缀¶
命令 3dw 和 d3w 都是删除三个单词。如果非要寻根问底,那么: 3dw 表示删除一个单词执行 3 次,而 d3w 表示删除三个单词执行 1 次。这是一个没有分别的分别。实际上可以放两个计数前缀,例如, 3d2w 删除两个单词执行 3 次,共计六个单词。
替换单个字符¶
r 命令不是操作符。它只是等你输入一个字符然后用这个字符替换当前光标上的字符。可以用 cl 命令或者 s 命令完成相同的功能,但 r 命令不需要使用 <Esc> 退出插入状态:
there is somerhing grong here
rT rt rw
There is something wrong here
There is something wrong here
5rx
There is something xxxxx here
要用换行符替换一个字符可以用命令 r<Enter> 。这会删除一个字符并插入一个换行符。在这里使用计数前缀会删除多个字符但只插入一个换行符: 4r<Enter> 用一个换行符替换四个字符。
重复一个修改¶
. 是 Vim 中一个非常简单而有用的命令,它重复最后一次的修改操作。例如,在编辑一个 HTML 文件时,想删除所有的 <b> 标签。你把光标移到第一个 "<" 上,然后用 df> 命令删除 <b>。然后你就可以移到 </b> 的 "<" 上面用 . 命令删除它。
To <b>generate</b> a table of <b>contents
f< 找第一个 < --->
df> 删除到 > -->
f< 找下一个 < --------->
. 重复 df> --->
f< 找下一个 < ------------->
. 重复 df > -->
. 命令可以重复任何除 u (撤销), CTRL-R (重做) 和冒号命令外的修改。
可视模式¶
要删除一些简单的东西,用 "操作符-动作" 命令可以完成得很好。但很多情况下,并不容易确定用什么命令可以移到想修改的地方。这时候,就需要可视模式了。
可以用 v 命令启动可视模式,它会从光标位置开始选择,然后移动光标到需要选择的地方。可视模式会高亮显示选中的字符,最后执行一下 "操作符" 命令即可。
例如,要从一个单词的一半删除到下一个单词的一半:
This is an examination sample of visual mode
---------->
velllld
This is an example of visual mode
这样做的时候,不需要算向后移动多少个字符,可以在删除前清楚得看到选择了哪些字符。
如果中途改变了主意,按下 <Esc> 键就能退出可视模式。
按行选择¶
如果想对整行做操作,可以使用 V 命令来启动可视模式。你会发现在你作任何移动之前,整行都被高亮显示了。左右移动不会有任何效果。而通过上下移动,你可以一次选择多行。
例如,用 Vjj 可以选中三行:
+------------------------+
| text more text |
>> | more text more text | |
选中的行 >> | text text text | | Vjj
>> | text more | ↓
| more text more |
+------------------------+
列块选择¶
如果要处理一个矩形块内的文本,可以使用 CTRL-V 启动可视模式。这在处理表格时非常有用。
name Q1 Q2 Q3
pierre 123 455 234
john 0 90 39
steve 392 63 334
要删除中间 "Q2" 这一栏,把光标移动到 "Q2" 的 "Q" 上面。按 CTRL-V 启动列块可视模式。现在用 3j 向下移动三行,然后用 w 移到下一个单词。你可以看到最后一栏的第一个字符也被包括进来了。要去掉它,用 h 命令即可。现在按 d ,中间一栏就被删除了。
移动到另一端¶
如果你在可视模式下选中了一些文字,然后你又发现你需要改变被选择的文字的另一端,用 o 命令即可(o 表示 other end),光标会移动到被选中文字的另一端,现在你可以移动光标去改变选中文字的开始点了。再按 o 光标还会回到另一端。
当使用列块可视模式的时候,你会有四个角, o 只是把你移到对角上。而用 O 则能移到同一行的另一个角上。
注解
o 和 O 在可视模式下与在普通模式下的作用有很大的不同;在普通模式下,它们的作用是在光标后或前加入新的一行。
移动文本¶
当你用 d x 或者其它命令删除文本的时候,这些文字会被存起来。你可以用 p 命令重新粘贴出来(p 表示 put,放置)。
看一个删除一行并粘贴的例子(相当于剪切一行然后粘贴)。首先,在要删除的行上输入 dd 删除一整行,然后移动到你要重新插入这行的地方输入 p ,这样这一行就会被插入到光标下方。
由于删除的是一整行, p 命令把该行插入到光标下方。如果删除的是一行的一部分(例如一个单词), p 命令会把它插入到光标的后面。
Some more boring try text to out commands.
---->
dw
Some more boring text to out commands.
-------->
welp
Some more boring text to try out commands.
关于粘贴的更多知识¶
P 命令像 p 一样也是插入字符,但插入点在光标前面。当你用 dd 删除一行, P 会把它插入到光标所在行的前一行。而当你用 dw 删除一个单词, P 会把它插入到光标前面。
你可以执行这个命令多次,每次会插入相同的文本。
粘贴命令接受计数前缀,被插入的文本就会被粘贴指定的次数。所以 dd 后加一个 3p 会把删除行的三个拷贝插入到文本中。
交换两个字符¶
经常发生这样的情况,当你输入字符的时候,你的手指比脑子转得快(或者相反)。这
样的结果是你经常把 "the" 敲成 "teh"。这时,只要把光标移到 "teh" 的 "e" 上,然后执行 xp 命令即可。这个工作过程是: x 删除一个字符,保存到寄存器。 p 把这个被保存的字符插入到光标的后面,也就是在 "h" 的后面了。
teh th the
x p
拷贝文本¶
y 命令可以把文字拷贝到寄存器中。然后用 p 命令粘贴到别处。
由于 c 已经被用于表示 change 了,所以拷贝(copy)就不能再用 c 了。Vim 把拷贝命令称为 "yanking" 是为了更容易记住 y 这个键。
由于 y 是一个操作符,所以 yw 命令就是拷贝一个单词了。要拷贝两个单词,就可以用 y2w 。例如:
let sqr = LongVariable *
-------------->
y2w
let sqr = LongVariable *
p
let sqr = LongVariable * LongVariable
注解
yw 命令包括单词后面的空白字符。如果你不想要这个字符,改用 ye 命令。
yy 命令拷贝一整行,就像 dd 删除一整行一样。出乎意料地是, D 删除到行尾而 Y 却是拷贝一整行。要注意这个区别! y$ 拷贝到行尾。
文本对象¶
如果光标在一个单词的中间而又想删掉这个单词,在用 dw 删除单词前,必须先将光标移到这个单词的开始处。还有一个更简单的方法: daw 。
daw 的 d 是删除操作符, aw 是一个文本对象(提示: daw 就是 "Delete A Word"(删除一个单词)。确切地说,该单词后的空格字符也被删除掉了。
使用文本对象是 Vim 中执行修改的第三种方法。上边已经有提过 "操作符-动作" 和可视模式两种方法了。现在我们又有了 "操作符-文本对象"。
这种方法与 "操作符-动作" 很相似,但它不是操作于从当前位置到移动目标间的内容,而是对光标所在位置的 "文本对象" 进行操作。文本对象是作为一个整体来处理的,光标在对象中的位置无关紧要。
还可以在可视模式下使用文本对象。这样会选中一个文本对象,而且继续留在可视模式,你可以继续多次执行文本对象命令。例如,先用 "v" 启动可视模式,再用 "as" 就可以选中一个句子。现在重复执行 "as",就会继续选中更多的句子。最后你可以使用一个操作符去处理这些被选中的句子。
文本对象的选择有多种形式,如:"aw"、"as"、"is"、"iw" 等详见文本对象。
替换模式¶
R 命令启动替换模式。在这个模式下,你输入的每个字符都会覆盖当前光标上的字符。这会一直持续下去,直到按下 <Esc>。
在下面的例子中,你在 "text" 的第一个 "t" 上启动替换模式:
This is text.
Rinteresting.<Esc>
This is interesting.
你可能会注意到,这是用十二个字符替换一行中的五个字符。如果超出行的范围, R 命令自动进行行扩展,而不是替换到下一行。
你可以通过 <Insert> 在插入模式和替换模式间切换。
但当你使用 <BS> (退格键) 进行修正时,你会发现原来被替换的字符又回来了。这就好像一个 "撤销" 命令一样。
一些常用的修改命令¶
~修改光标下字符的大小写,并移动到下一个字符。这不是一个操作符(除非设置了 'tildeop'),所以你不能连接一个动作命令。这个命令在可视模式下也有效,它会改变被选中的所有文本的大小写。I移到当前行的第一个非空字符并启动插入模式。A移动到行尾并启动插入模式。"*yy拷贝一行到系统剪贴板中"*p粘贴系统剪贴板中的内容