-
Notifications
You must be signed in to change notification settings - Fork 0
/
vim第七章之后笔记
286 lines (207 loc) · 12.7 KB
/
vim第七章之后笔记
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
对于水平方向的移动而言,
你也可以用面向单词的动作命令,或是用字符查找动作命令来更快地进行移动
区分实际行与屏幕行,理解实际行与屏幕行间的差别很重要,因为 Vim 提供了不同的动作命令来操作
这两者。 j 和 k 命令会根据实际行向下及向上移动,而 gj 和 gk 则是按屏幕行向下
j 向下移动一个实际行
gj 向下移动一个屏幕行
k 向上移动一个实际行
gk 向上移动一个屏幕行
0 移动到实际行的行首
g0 移动到屏幕行的行首
^ 移动到实际行的第一个非空白字符
g^ 移动到屏幕行的第一个非空白字符
$ 移动到实际行的行尾
g$ 移动到屏幕行的行尾
你可以留意到这样一个特点,即 j 、 k 、 0 和 $ 都用于操作实际行,而如果在这些
键前加上 g 前缀的话,就会让 Vim 对屏幕行进行操作
w 正向移动到下一单词的开头
b 反向移动到当前单词/上一单词的开头
e 正向移动到当前单词/下一单词的结尾
ge 反向移动到上一单词的结尾
把 ea 命令连在一起可被解读为“在当前单词结尾后添加
gea 命令当成“在上一单词结尾后添加”的命令
我们之前遇到过的每个面向单词的动作命令,都有一个面向字串的命令与其对
应,这当中包括 W 、 B 、 E 和 gE 。记住字串之间用空白字符分开而单词比字串多
例子:e.g. we're going too slow
f{char} 命令是在 Vim 中移动的最快方式之一。它会在光标位置与当前行行尾
之间查找指定的字符,如果找到了,就会把光标移到此字符上;如果未找到,则保持光标不动。用 ; 命令就可以重复该命令了
f{char} 正向移动到下一个 {char} 所在之处
F{char} 反向移动到上一个 {char} 所在之处
t{char} 正向移动到下一个 {char} 所在之处的前一个字符上
T{char} 反向移动到上一个 {char} 所在之处的后一个字符上
; 重复上次的字符查找命令
, 反转方向查找上次的字符查找命令
经典操作
{start} I've been expecting you, Mister Bond.
f, I've been expecting you, Mister Bond.
dt. I've been expecting you.
因此我们可以把 f,dt. 训练成手指的下意识动作
虽然字符查找命令( f{char 、 t{char} 等)执行起来方便快捷,但是它们具有一
定的局限性。这些命令一次只能查找一个字符,并且它们只能在当前行内查找
如果想查找一个以上的字符,或是移动到当前行之外的话,就需要使用查找命令/word
用 n 命令重复上次的查找命令,这样就可以跳到下个正确的匹配之处了。另外,如果按 n 键
的次数过多了,我们还可以用 N 命令再跳回来。
启用了 ‘hlsearch’ 功能,以便高亮匹配项
查找命令不仅限于在普通模式下使用,我们也可以在可视模式及操作符待决模式
中使用它,用来完成实际的工作。不用可视模式,学会把 d{motion} 操作符与查找动作结
合在一起使用,这是个很大的进步
用精确的文本对象选择选区:
a) 或 ab 一对圆括号 (parentheses)
i) 或 ib 圆括号 (parentheses) 内部
a} 或 aB 一对花括号 {braces}
i} 或 iB 花括号 {braces} 内部
a] 一对方括号 [brackets]
i] 方括号 [brackets] 内部
a> 一对尖括号 <angle brackets>
i> 尖括号 <angle brackets> 内部
a' 一对单引号 'single quotes'
i' 单引号 'single quotes' 内部
a" 一对双引号 "double quotes"
i" 双引号 "double quotes" 内部
a` 一对反引号 `backticks`
i` 反引号 `backticks` 内部
at 一对 XML 标签 <xml>tags</xml>
XML 标签内部
Vim 的文本对象由两个字符组成,第一个字符永远是 i 或是 a 。我们一般说,
以 i 开头的文本对象会选择分隔符内部的文本,而以 a 开头的文本对象则会选择包
括分隔符在内的整个文本。为了便于记忆,可以把 i 想成“inside”,而把 a 想成
“around” 或“all”
可视模式适用于介绍文本对象,因为可以很容易看到发生的变化。然而,在操作
符待决模式中使用文本对象,才能真正展现出它们的强大能力。如把 cit 命令解读为“修
改标签内部的内容”。另外,我们也可以很容易地用 yit 命令拷贝标签内的文本,或
者是用 dit 删除这些文本。
Vim 的文本对象分为两类:一类是操作分隔符的文本对象,如 i) 、 i" 和 it ;另
一类用于操作文本块,如单词、句子和段落
iw 当前单词
aw 当前单词及一个空格
iW 当前字串
aW 当前字串及一个空格
is 当前句子
as 当前句子及一个空格
ip 当前段落
ap 当前段落及一个空行
一般来说, d{motion} 命令和 aw 、 as 和 ap 配合起来使用比较好,而 c{motion}
命令和 iw 及类似的文本对象一起用效果会更好。
设置位置标记,以便快速跳回
m{a-zA-Z} 命令会用选定的字母标记当前光标所在位置(小写位
置标记只在每个缓冲区里局部可见,而大写位置标记则全局可见)
`{mark} 命令则把光标移动到设置此位置标记时光标所在之处
mm 和 `m 命令是一对便于使用的命令。Vim 会自动帮
我们设置一些位置标记,这些标记用起来非常方便
`` 当前文件中上次跳转动作之前的位置
`. 上次修改的地方
`^ 上次插入的地方
`[ 上次修改或复制的起始位置
`] 上次修改或复制的结束位置
`< 上次高亮选区的起始位置
`> 上次高亮选区的结束位置
% 命令允许我们在一组开、闭括号间跳转(参见 :h %),它可作用于 ()、{}
以及[]
在做修改之前,要先执行一次 % 命令。在执行 % 命令时,Vim 会
自动为发生跳转的地方设置一个位置标记,而后我们就可以按 `` 跳回那里
Vim 会记录跳转前后的位置,并提供了一些命令让我们能够沿原路返回,<C-o> 命令像后退按钮一样,而与之互补的 <C-i> 命令则像是前进按钮。这两条命令允许我们对 Vim 的跳转列表进行遍历
用 [count]G 命令直接跳到指定的行号也会被当成一次跳转,但每次向上或向下
移动一行则不算。面向句子的动作及面向段落的动作都算跳转,但面向字符及面向单
词的动作则不算。用一句话来概括,我们可以说大范围的动作命令可能会被当成跳转,
但小范围的动作命令则只能算移动。
[count]G 跳转到指定的行号
/pattern<CR>/ ? pattern<CR>/n/N 跳转到下一个/上一个模式出现之处
% 跳转到匹配的括号所在之处
(/) 跳转到上一句/下一句的开头
{/} 跳转到上一段/下一段的开头
H/M/L 跳到屏幕最上方/正中间/最下方
gf 跳转到光标下的文件名
<C-]> 跳转到光标下关键字的定义之处
’{mark}/`{mark} 跳转到一个位置标记
xp ,可被用于“调换光标之后的两个字符
ddp ,可被用于“调换当前行和它的下一行
Vim 不使用单一的剪贴板进行剪切、复制与粘贴操作,而是为这些操作提供了多
组寄存器。当使用删除、复制与粘贴命令时,我们可以明确指定它们中的某一个进行
操作。
Vim 的删除、复制与粘贴命令都会用到众多寄存器中的某一个。我们可以通过给
命令加 "{register} 前缀的方式指定要用的寄存器。若不指明,Vim 将缺省使用无
名寄存器。
剪切(cut)、复制(copy)与粘贴(paste),这些都是众所周知的术语,而且
大多数桌面软件和操作系统都支持这3类操作。Vim 当然也提供这些功能,只不
过使用的是另外的术语 delete、yank 与 put。
Vim 的 delete 命令也与标准剪切操作的作用一致。也就是说,该命令会先把
指定文本复制到寄存器后再从文档中删掉
你也许好奇,Vim 中真正删除文本的操作是什么。也就是说,我们怎样才能
删除文本而不把其内容复制到任何寄存器?答案是使用名为“黑洞”的特殊寄存
器,顾名思义,放到这里的文本真地是有去无回了。用下划线符号(参见 :h
quote_ )可以引用黑洞寄存器。因此, "_d{motion} 会执行真正的删除操作
如果我们想把当前单词复制到寄存器 a 中,可
执行 "ayiw ,或者,可以用 "bdd ,把当前整行文本剪切至寄存器 b中我们既可以输入 "ap 粘贴来自寄存器 a 的单词,也可使用 "bp 命令粘贴来自寄存器 b的一整行文本,两者互不干扰。
除了普通模式的命令外,Vim 也提供用于删除、复制与粘贴操作的 Ex 命令。例
如,我们可以执行 :delete c ,把当前行剪切到寄存器 c ,然后再执行 :put c 命令
将其粘贴至当前光标所在行之下。相比普通模式的命令而言,这些操作看似繁琐,但
如果将它们与其他 Ex 命令结合起来使用,或者用于 Vim 脚本编程,将会更方便。例
如,技巧 99 就为我们展示了 :yank 命令怎样和 :global 命令一起使用的场景
倘若我们没有指定要使用的寄存器,Vim 将缺省使用无名寄存器,它可以用双引
号表示(参见 :h quote_quote )。为了显式地引用该寄存器,我们得使用两个双引
号。例如, ""p ,它完全等同于 p 命令
x 、 s 、 d{motion} 、 c{motion} 与 y{motion} 命令(以及它们对应的大写命令)
都会覆盖无名寄存器中的内容
当我们使用 y{motion} 命令时,要复制的文本不仅会被拷贝到无名寄存器中,而
且也被拷贝到了复制专用寄存器中,后者可用数字 0(参见 :h quote0 )加以引用。
复制专用寄存器,顾名思义,仅当使用 y{motion} 命令时才会被赋值。换句话讲,
使用 x 、 s 、 c{motion} 以及 d{motion} 命令均不会覆盖该寄存器。如果我们复制了
一些文本,可以确信该文本会一直保存于寄存器 0 中,直到我们复制其他文本时才会
被覆盖。复制专用寄存器是稳定的,而无名寄存器是易变的。
Vim 提供了一组以 26 个英文字母(参见 :h quote_alpha )命名的有名寄存器。这意
味着我们可以剪切( "ad{motion} )
、复制( "ay{motion} )或者粘贴( "ap )多达 26 段文本
用小写字母引用有名寄存器,会覆盖该寄存器的原有内容,而换用大写字母的话,
则会将新内容添加到该寄存器的原有内容之后
"_diw 彻底删除
系统剪贴板("+)与选择专用寄存器("*)
Vim 的加号寄存器与系统剪贴板等效
如果我们在外部程序中用剪切或复制命令获取了文本,就可以通过 "+p 命令(或
在插入模式下用 <C-r>+ )将其粘贴到 Vim 内部
Vim 的粘贴命令在可视模式下使用
把命令序列录制成宏
q 键既是“录制”按钮,也是“停止”按钮。为了录制我们的按键操作,一开始
需要按 q{register} ,从而指定一个用于保存宏的寄存器。当状态栏中出现“记录中”
时,表示录制已经开始。此后,我们执行的每一条命令都将被宏捕获,直到我们再次
按下 q 键停下为止
这里的寄存器无须之前加双引号
:reg 寄存器 查看寄存器内容
我们可以用 @{register} 命令执行指定寄存器的内容(参见 :h @
@@ 来重复最近调用过的宏
黄金法则:在录制一个宏时,要确保每条命令都可被重复执行
我推荐你用查找命令定位,或者用文本对象。总之,请用好 Vim 提供的所有动作
命令,尽量使你的宏兼具灵活性与可重复性。还有一点别忘了,在录制宏的过程中,
禁止使用鼠标。
假设宏保存在寄存器 a 中。这一次,我们不再执行 10 次 @a ,而是改用次数作为
前缀执行宏 1 0 @a
人们很自然地想到 11;. 应该能完成这项工作,但实际上它不管用。因为 Vim 会
先运行 11 次 ; 命令,再运行 1 次 . 命令。类似地,如果我们运行 ;11. 的话,错误
会更明显,因为它会指示 Vim 先调用 1 次 ; ,再调用 11 次 . 。而我们的真正目的是
要运行 11 次 ;. 。
通过录制一个最简单的宏,我们可以模拟执行 11 次的 ;. ,即 qq;.q 。首先, qq
将指示 Vim 录制后续的按键操作并将它们保存至寄存器 q 中。然后,我们再输入命
令 ;. 。最后,我们按下 q 键结束宏的录制。现在可以加上次数 11 执行这个宏 11@q ,
即执行 11 次 ;.
~反转当前字母大小写
以并行方式执行宏
按键操作 缓冲区内容
qa 1. one
0f.r)w~ 1) One
q 1) One
jVG 1) One
2. two
//break up
3. three
4. four
:'<,'>normal @a 1) One
2) Two
//break up
3) Three
4) Four
:normal @a 命令指示 Vim 在高亮选区中的每一行上执行这个宏。像上次一样,
宏在前两行执行成功了,但在第 3 行被中止了,但这次它并没有停在那儿,而是继续
完成了任务。
qA 用于在录取好的宏中添加命令 q结束
如果宏在每次执行时都能插入一个可变的数值,这将会很有用处。在本节中,我
们将学习一种技术,它会在录制宏的时候使某个数字递增,这样一来,就可以在连续
的文本上插入数字 1 到 5。