因为工作中需要用到Vim,所以本文简单记录下学习Vim编辑器的一些笔记和技巧。
Vimtutor
Vimtutor是Vim的一个简易教程,前前后后做了两遍,记录一下一些实用的快捷键吧。
快捷键 | 功能 |
---|---|
h/j/k/l | 左下上右 |
x | 删除光标处的字母 |
i | 切换至输入模式,在光标前输入 |
A | 切换至输入模式,在行尾输入 |
dw | 从光标处删除字符直到下个字开始 |
de | 从光标处删除字符直到该字尾 |
u | 撤销 |
U | 撤销一整行的操作,使该行恢复到最初 |
d& | 从光标处删除字符直到行尾 |
dd | 删除该行,其实也可以理解成剪切一行 |
y | 个人感觉类似复制 |
p | 个人感觉类似于粘贴 |
r+字符 | 用新的字符替换光标所在位置的字符 |
R | 替换多个字符 |
ce | 将一个字从光标处开始直到字尾的字符进行替换 |
ctrl+g | 显示当前位置在整个文档的位置占比 |
gg | 跳转到文档开头 |
G | 跳转到文档结尾,number+G就跳转到第number行 |
/+字符串 | 往下搜索某字符串,搜到后n是下一个,N是上一个,Ctrl+o回到原处 |
?+字符串 | 往上搜索某字符串,搜到后n是下一个,N是上一个,Ctrl+o回到原处 |
% | 寻找匹配的括号 |
%s/old/new/g | 全文替换,用new替换old |
!+外部命令 | !后可以输入外部shell命令,如ls |
o | 在光标下方新增一行并进入插入模式,如果是大写的O则是在光标上方新增一行 |
help+command | 打开help文档查看command命令的说明 |
很多命令的格式都是operation [number] motion
,比如d2w
就是删除两个字。
在Vim里使用了:
后,可以按ctrl+d
来查看可以使用的命令。
《Vim实用技巧》
一.Vim解决问题的方式
技巧1 结识.
命令
- 首先要明确什么是修改,一次修改的单位可以是字符、整行,甚至是整个文件。当进入插入模式的那一刻起,直到返回普通模式为止,Vim会记录每一个操作,这些所有的操作在返回普通模式后被统称为一次修改,按
.
键即可重新执行一次所有操作。
技巧2 不要自我重复
- 用
A
代替$a
- 有一些复合命令可以代替等效的长命令(这里还是得多用多记吧,不过这些命令的共同处是都会把普通模式切换到插入模式,本来以为这会让多次连续使用
.
命令出现问题,但试验之后好像没有?比如按下ko
会进入插入模式,但返回普通模式后按.
,虽然也换行了但是并没有进入插入模式。)
技巧3 以退为进
s
命令包含两个动作:删除光标处的字符,进入插入模式。f{char}
命令查找该行下一处指定字符出现的位置,如果找到就直接把光标移到该处。而;
命令可以重复上次的f{char}
命令。
技巧4 执行、重复、回退
- 类似于
u
可以回退.
的修改,,
也可以用来回退;
技巧5 查找并手动替换
*
命令可以查找当前光标所在单词
技巧6 结识.
范式
- 理想模式:一键移动,一键执行。(谨记!)
二、普通模式
技巧7 停顿时请移开画笔
- 就像画家只花一小部分时间真正画画一样,程序员也只花一小部分时间编写代码,绝大多数时间用来思考,这个时候就是普通模式。(其实用作家码字来比喻可能我更喜欢~)
技巧8 把撤销单元切成块
- 在插入模式中移动光标会重置修改状态,即相当于切回普通模式使用了
hjkl
,只是看起来没退出插入模式罢了。
技巧9 构造可重复的修改
- 当完成一个修改有多种方法的时候,可以考量不同方法的VimGolf,小者获胜,当VimGolf相同时则可以思考在不同的方法下,继续按
.
会各自有什么效果,选其中最有价值的那个,即将修改构造成了可重复性的修改。(真是太秀了,忍不住666)
技巧10 用次数做简单的算数运算
ctrl+a
表示+1,ctrl+x
表示-1
技巧11 能够重复,就别用次数
- 次数和
.
命令要斟酌着选择使用
技巧12 双剑合璧,天下无敌
- 操作符 + 动作命令 = 操作
- Vim语法只有一条额外规则,即当一个操作符命令被连续调用两次时,它会作用于当前行。
三、插入模式
技巧13 在插入模式下可即时更正错误
ctrl+h
删除前一个字符ctrl+w
删除前一个单词ctrl+u
删除至行首
技巧14 返回普通模式
可以使用Esc
或ctrl+[
来返回普通模式,还可以使用ctrl+o
切换到插入-普通模式。在插入-普通模式中,可以执行一次普通模式下的命令然后自动变回插入模式。
技巧15 不离开插入模式,粘贴寄存器中的文本
- 看书上的描述,是可以把文本复制到寄存器中,然后再在指定位置把寄存器的文本粘贴出来。具体命令回头再看吧,也记不住。
技巧16 随时随地做运算
- 利用表达式寄存器我们可以做一些运算并把结果直接插入到文本中。输入
<ctrl+r>=
就可以访问该寄存器,然后输入表达式(如1+1)按回车就可以在光标处插入对应结果了(如2)。
技巧17 用字符编码插入非常用字符
- Vim可以用字符编码来插入任意字符,使用此功能可以很方便地输入键盘上找不到的符号,只要输入
<ctrl+v>{code}
即可。 - 另外如果想要知道光标处的字符的编码,按
ga
即可。
技巧18 用二合字母插入非常用字符
- 感觉和技巧17类似,只不过技巧17需要用编码不方便记忆,使用二合字母似乎好记忆一些(它这么说的,我也不敢说啥),命令
<ctrl+k>{char1}{char2}
。比如<ctrl+k>12
就可以输出分数1/2.
技巧19 用替换模式替换已有文本
R
命令进入替换模式,r
替换一个字符并返回普通模式。- 当有制表符的时候用
R
进入替换模式替换时,会用一个字符替换掉整个制表符所占长度的字符,从而缩减行的长度,这可能不是我们所希望的,这时候可以使用gR
命令进入虚拟替换模式来替换,就不会有这样的问题。
四、可视模式
Vim具有三种不同的可视模式,分别用于操作字符文本、行文本或块文本。
技巧20 深入理解可视模式
- 在普通模式中,先触发修改命令再选中作用范围,但是在可视模式中是先选中选区,然后再触发命令。注意次序是颠倒的。
技巧21 选择高亮选区
v
切换到面向字符的可视模式,V
切换到面向行的可视模式,而<ctrl+v>
切换到面向列块的可视模式。gv
命令可以重新选择上次可视模式选择的区域。- 可视模式之间的切换也就是按对应的键就行了。
- 可视模式选择中可以利用
o
来切换选区的活动端。
技巧22 重复执行面向行的可视命令
- 合适的场景下可以使用
.
命令来重复之前面向行的可视命令。
技巧23 只要可能,最好用操作符命令而不是可视命令
- 如果想让
.
命令能够重复某些有用的工作的话,那么最好不要用可视模式,首选操作符命令。
技巧24 用面向列块的可视模式编辑表格数据
- 这个就是要多练了,熟悉命令就行。
技巧25 修改列文本
技巧26 在长短不一的高亮块后添加文本
- 从普通模式切换到插入模式时
i
和a
分别表示把光标置于当前字符之前或之后,但是在可视模式或操作符待决模式中,这两个命令被当做一个文本对象的组成部分,想要进入插入模式需要按I
或A
。
五、命令行模式
初时,先有ed,ed为ex之父,ex为vi之父,vi为vim之父。
技巧27 结识Vim的命令行模式
- 命令行模式会提示我们输入一条Ex命令、一个查找模式或一个表达式。
- Ex命令影响相比普通模式下的命令范围更广而且距离更远。
技巧28 在一行或多个连续行上执行命令
- 很多Ex命令可以用[rang]指定要操作的范围,可以用行号、位置标记或是查找模式来指定范围的开始位置及结束位置。
- 在Ex命令里,
.
代表当前行的地址,%
代表当前文件的所有行。'<
表示选区首行,'>
表示选区末行。 - 可以用模式指定范围,也可以用偏移(如+1、-1)对地址进行修正。
- 总而言之,定义范围的语法很灵活。
技巧29 使用:t
和:m
命令复制和移动行
- 重复上次的Ex命令非常简单,只需使用
@:
命令即可。
技巧30 在指定范围上执行普通模式命令
- 如果想在一系列连续行上执行一条普通模式命令,则可以使用
:normal
。 - 在执行普通模式命令之前,Vim会把光标移到行首,因此在执行命令时不需要担心光标的位置。
技巧31 重复上次的Ex命令
- 重复上次的Ex命令非常简单,只需使用
@:
命令即可。 bnext
可以在缓冲区列表项中正向移动,而bprevious
则是反向移动。
技巧32 自动补全Ex命令
- 如同在shell中一样,在命令行上也可以用
键自动补全命令。 <ctrl+d>
可以显示Vim可用的命令补全列表。
技巧33 把当前单词插入到命令行
- 在Vim的命令行下,
<ctrl+r><ctrl+w>
会复制光标下的单词并把它插入到命令行中。
技巧34 回溯历史命令
- 历史命令不仅仅是为当前编辑会话记录的,这些记录即使在退出Vim再重启之后仍然存在。
- 输入
q:
可以打开命令行窗口。在命令行窗口里可以用任何习以为常的动作命令进行移动,也可以在高亮选区上操作,或是切换到插入模式中。可以按:q
或者回车来关闭命令行窗口。具体要多练。 - 当我们在命令行窗口按回车时,该命令在活动窗口的上下文中执行。所谓活动窗口,指的是打开命令行窗口之前处于活动的那个窗口,要注意。
技巧35 运行Shell命令
- 不用离开Vim就可以方便地调用外部程序,还可以把缓冲区的内容当做标准输入发送给一个外部命令,或是把外部命令的标准输出导入到缓冲区中。
- 给命令加一个前缀
!
号就可以调用外部命令一次。 - 如果想要执行多次外部命令,则可以用
:shell
命令打开一个交互的shell,用exit
退出。 - 当然也可以用
<ctrl+z>
把Vim进程挂起,运行完shell命令之后再用jobs
和fg
命令切换回来。 - 可以用
:read !{cmd}
把外部命令的输出读入到当前缓冲区中。而:write !{cmd}
做相反的事,把缓冲区的内容作为外部命令的输入。但要注意的是在write中感叹号位置不同表示的含义有所不同,:write! sh
会把缓冲区内容写入到一个名为sh的文件中,叹号表示无论如何都覆盖。 :[range]!{filter}
可以实现某个范围内的过滤,意思是把该范围内的内容作为标准输入,处理之后再把结果输出到该范围之内。
六、管理多个文件
技巧36 用缓冲区列表管理打开的文件
- 在一次的编辑会话中,可以打开多个文件,用Vim的缓冲区列表可以对这些文件进行管理。
- Vim允许同时在多个缓冲区上工作,打开多个文件后可以用
:ls
命令查看所有被载入到内存中的缓冲区的列表,然后用:bnext
命令切换到列表中的下一个缓冲区,:bprev
切换到前一个,此外还有:bfirst
和:blast
两个命令也可以切换。 - 使用
:ls
命令时,#符号表示轮换文件,可以用<ctrl+^>
来切换到#所指文件。
技巧37 用参数列表将缓冲区分组
- 参数列表易于管理,适用于对一批文件进行分组,使其更容易访问。用
:argdo
命令可以在参数列表中的每个文件上执行一条Ex命令。 - 可以用
:args {argList}
来填充参数列表,argList也可以使用模式来指定,还可以使用反引号。比如args `cat .chapters` 就会先在shell中执行cat .chapters
命令,然后将该命令的输出作为args的参数。
技巧38 管理隐藏缓冲区
- 打开多个缓冲区后,如果修改了某个缓冲区,再使用
:bnext
时会提醒当前缓冲区中有未保存的改动,可以加上!
来强制切换,也可以保存后再切换。如果选择了强制切换,那么在退出时需要再次处理每个缓冲区,可以用qa!
摒弃所有改动,也可以用:wa!
把所有改动写入磁盘。 - 大多数情况下Vim提醒缓冲区改动未保存是一个好事,但是当涉及到
:argdo
或者:bufdo
等命令时则很不方便,所以在使用这些命令前可以启动hidden
选项,最后退出时再处理。
技巧39 将工作区切分成窗口
- Vim允许我们将工作区切分成多个若干窗口,在窗口里并排显示多个缓冲区。
<ctrl+w>s
水平切割窗口,<ctrl+w>v
垂直切割窗口。close
命令可以关闭活动窗口,only
命令可以只保留活动窗口而关闭其他窗口。
技巧40 用标签页将窗口分组
- 标签页的这部分看的不是特别明白,书中也没有给出好的例子。以后再说吧。
七、打开及保存文件
技巧41 用:edit
命令打开文件
- 在Vim中,可以用
:edit
命令通过文件的绝对或相对路径来打开文件。 %
符号代表活动缓冲区的完整文件路径,按Tab
键可以将其展开。%:h
则可以显示去掉文件名的活动缓冲区完整文件路径。
技巧42 使用:find
打开文件
- 这个技巧里讲的主要是配置path,然后就可以用
find
命令来打开文件了。
技巧43 使用netrw管理文件系统
- Vim还可以查看目录,netrw就是它自带的文件管理器插件。
- 可以用
:edit {path}
打开文件管理器窗口。此外,:Explore
命令也可以打开文件管理器窗口,并显示活动缓冲区所在的目录。 - 可以与分割窗口协同工作
技巧44 把文件保存到不存在的目录中
- 当用
:edit {file}
命令打开未存在的目录中的未存在文件时,不能直接保存,需要先创建该目录,可以用:!mkdir %:h
命令。
技巧45 以超级用户权限保存文件
- 这个就不管了,感觉不太会用到,记一下书中用到的命令好了
:w !sudo tee % > /dev/null
。
八、用动作命令在文档中移动
- 可以通过
:h motion.txt
获得完整的动作命令列表
技巧46 让手指保持在本位行上
- 用
hjkl
移动,戒掉使用光标键的习惯,可以在vimrc里添加对应的辅助设置,p102
技巧47 区分实际行与屏幕行
- 所谓实际行说的是真正的行,屏幕行则是因为屏幕宽度限制而出现的行
hjkl0$
命令都是针对实际行的,前缀加g
就能对应命令改为针对屏幕行的。
技巧48 基于单词移动
wbe
是基于单词的移动动作,对应的WBE
则是针对子串的移动动作。
技巧49 对字符进行查找
f{char}
是在Vim里移动最快的方式之一,它会在光标与行尾之间搜寻指定的字符,找到了就移过去。;
可以重复上一次的f{char}
命令,,
可以反向跳。t{char}
正向移动到下一个{char}所在之处的前一个字符上,T{char
反向移动到char的后一个字符上。- 使用这些命令的时候,要学会找到频率少的单词,这样才能提高移动效率。
技巧50 通过查找进行移动
- 用
/
来进行查找并移动光标 - 还可以将操作文本的动作和查找结合在一起。
技巧51 用精确的文本对象选择选区
- 文本对象允许操作括号、被引用的文本、XML标签以及其他文本中的常见结构。
- Vim的文本对象由两个字符组成,第一个字符永远是
i
或者a
。以i
开头的文本对象会选择分隔符内部的文本,而以a
开头的文本对象则会选择包括分隔符在内的整个文本。具体可以用到的时候再说吧。
技巧52 删除周边,修改内部
- 除了被括号或引号括起来的分隔符文本对象,还有另外一种范围文本对象,可以操作一个单词、一个子串、一个句子、一个段落。具体命令可以看书p117
技巧53 设置位置标记,以便快速跳回
- 可以用
m{a-zA-Z}
标记当前光标所在位置,然后用`{a-zA-Z}命令跳回来。
技巧54 在匹配括号间跳转
%
命令可以在成对的括号间跳转- Vim在发布时携带一个名为matchit的插件,可以用来在配对的关键字之间跳转,还有个Surround.vim的插件,可以很容易地给选中的文本加分隔符。
九 在文件间跳转
技巧55 遍历跳转列表
- 可以用
jumps
查看跳转列表的内容 - 大于等于句子级别的动作命令会被当做跳转,小范围的动作命令则只是移动。
技巧56 遍历改变列表
- 每当对文档做出修改后,Vim都会记录当时光标所在的位置。
changes
命令可以查看改变列表的内容。可以用g;
和g,
命令来反向或正向遍历改变列表。- `.总会跳到指向上次修改的地方。
- `^标记指向上次插入的地方。
技巧57 跳转到光标下的文件
- Vim会把文档中的文件名当成一个超链接,在进行了正确的配置之后,就可以用
gf
命令跳转到光标下的文件了。 - 跳转列表和改变列表允许我们原路返回,而
gf
和<ctrl+]>
则像虫洞,可以把我们从代码的一个地方传送到另一个文件地方。
技巧58 用全局位置标记在文件间快速跳转
m{A-Z}
可以设置一个全局标签,这对使用vimgrep等命令跳转到其他地方后想要再跳回来很有帮助,要养成在跳转前考虑是否需要全局标签的习惯。
十、复制与粘贴
- Vim的寄存器是一组用于保存文本的简单容器。它们既可以像剪贴板那样,剪切、复制和粘贴文本;也可以记录一系列按键操作,把它们录制成宏。
技巧59 用无名寄存器实现删除、复制与粘贴操作
- 在Vim的术语里,当提到剪切、复制与粘贴时,指的不是剪贴板而是寄存器。比如
xp
命令,先删除光标下的字符,然后粘贴到下一个字符之后,连起来的作用就是将光标下的字符和下一个字符交换位置。同理,ddp
命令可以用来交换两行的顺序。
技巧60 深入理解Vim寄存器
- Vim不使用单一的剪贴板进行剪切、复制和粘贴,而是为这些操作提供了多组寄存器。
- Vim的删除、复制和粘贴命令都会用到众多寄存器中的一个,可以通过给命令加
"{register}
前缀的方式指定要用的寄存器,若不指定则默认使用无名寄存器。 - 显式调用无名寄存器时要用
""
- 复制专用寄存器
"0
,要复制的文本不仅会被拷贝到无名寄存器中,而且也会被拷贝到复制专用寄存器中,仅当使用y{motion}
命令时才会被赋值。使用:reg "0
则可以查看该寄存器的内容。 - 有名寄存器(“a-“z)。用小写字母引用有名寄存器,会覆盖该寄存器的原有内容,而换用大写字母时,则会将新内容append到原内容后面。
- 黑洞寄存器(_ )可以真正删除文本,命令如
"_dd
可以删除整行而不复制到寄存器里去。黑洞寄存器是个有去无回的地方。 - 系统剪贴板
"+
,如果要从Vim复制文本到外部程序(反之亦然),则需要使用系统剪贴板。还有一个"*
表示X11主剪贴板,用鼠标中键操作(Win和MacOS没有)。 - 表达式寄存器
"=
,其他寄存器通常被认为是保存一段文本的容器,然后通过表达式寄存器是个例外。从表达式寄存器获取内容时,Vim将跳转到命令行模式,并显示提示符=
,这时可以输入一段Vim脚本表达式执行,将会返回结果。 - 还有几组可被隐式赋值的寄存器,只读。当前文件名
"%
。轮换文件名"#
。上次插入的文本".
。上次执行的Ex命令":
。上次查找的模式"/
。技术上讲/寄存器并非只读,可以用:let
命令赋值,但为方便仍归于此类。
技巧61 用寄存器的内容替换高亮选区的文本
- Vim的粘贴命令在可视模式下使用时,会体现出一些不同寻常的特性。在可视模式下使用p,将用我们指定的寄存器来替换高亮选区的文本。
- 使用p命令的时候,会先从寄存器里取出内容,然后把高亮选区的内容存入无名寄存器。
技巧62 把寄存器的内容粘贴出来
- 面向行的复制或删除操作将创建面向行的寄存器,而面向字符的复制或者删除操作则会创建面向字符的寄存器。
技巧63 与系统剪贴板进行交互
- 在Vim里使用系统粘贴版粘贴的时候往往缩进会出问题,为了解决这个问题,可以使用
:set paste
命令,然后切换到插入模式下进行粘贴,粘贴完再用:set paste!
切换回来。 - 可以用
:set pastetoggle=<F5>
来做个映射,以后按F5就可以切换paste。
十一、宏
- 可以用宏来把任意数目的按键操作录制到寄存器,用于之后的回放。
技巧64 宏的读取与执行
q
是录制宏的开始与结束。比如qa
会把接下来的一组命令保存在有名寄存器a里面。- 可以使用
reg a
来查看寄存器a的内容。 - 可以使用
@{register}
来调用对应寄存器里保存的宏,用@@
来重复上次调用过的宏命令。 - 在多次执行某个宏的时候有串行和并行两种方式,串行是一次一次执行,报错则停止,并行并不是真正的并行,只是说有一次执行出错的时候不会影响其他的宏。
技巧65 规范光标位置、直达目标以及中止宏
- 黄金法则:在录制一个宏时,要确保每条命令都可被重复执行。
- 一旦开始录制宏,就要问自己几个问题:我在哪?我从哪里来?我要去哪里?
- 规范光标的位置
- 用可重复的动作命令直达目标
- 当动作命令失败时,宏将中止。这种实现的好处在于在执行宏时,可以不顾忌执行的次数。
技巧66 加次数回放宏
- 对于次数不多的工作,可以用点范式,但它不能指定执行的次数。为了克服该限制,我们可以录制一个廉价的一次性的宏,然后再加次数进行回放。
- 不是每个宏都能用估算次数的方法调用。
技巧67 在连续的文本上重复修改
- 将下一个单词的首字母变为大写:
w~
- 以串行方式执行宏,类似于数字方法:
3@a
- 以并行方式执行宏,利用高亮选区,然后调用宏,在每一行上进行宏操作,这样就是并行方式,在书中的例子里,会比串行方式少一个j操作。p157
技巧68 给宏追加命令
q
后面跟大写字母,Vim会把后续的的按键操作附加到对应小写寄存器的内容后面。可以用这种方式来修正录制的宏的错误(但一般只能弥补结尾漏命令的情况)。
技巧69 在一组文件中执行宏
- 利用
argdo
一系列命令,串行就是在宏里面录制一个next命令,使命令得以串行执行下去,而并行就是对选择的所有文件执行同一个命令,就是这个意思吧……具体命令还是以后再说吧。
技巧70 用迭代求值的方式给列表编号
- 技巧10里提到过
<ctrl+a>
和<ctrl+x>
两个简单计算方式 - 通过使用
:let i=0
命令,可以创建一个名为i的变量,并给其赋值0。
技巧71 编辑宏的内容
- 为了修改宏的内容,可以先跳到文档最后,使用类似
:put a
的命令把某个寄存器中的值复制到文本里,然后对该文本进行就该,最后再把文本考回寄存器中,使用0
和"ay$
命令将该行命令整个重新复制到寄存器a中,之所以不用"add
是因为这会把该行最后的回车符也拷贝进寄存器,而这有时候会产生问题。
十一、按模式匹配及按原义匹配
技巧72 调整查找模式的大小写敏感性
- 既可以全局性地调整Vim查找功能的大小写敏感性,也可以在每次查找时进行局部调整。
- 如果启用
ignorecase
,Vim将不会区分大小写。 - 通过使用元字符\c或者\C则可以在本次查找中覆盖Vim的全局设置,\c忽略大小写,\C强制大小写。
- Vim还有一个更智能的大小写敏感性设置,就是
smartcase
,当该选项被启用时,只要在查找模式中输入了大写字母,ignorecase
设置就不再生效。换句话说,如果查找模式全是小写的,则忽略大小写,但只要有一个大写字母,就会区分大小写。
技巧73 按正则表达式查找时,使用\v模式开关
- 正则表达式学得不咋地,以后再看。
技巧74 按照原义查找文本时,使用\V原义开关
- 比如
/ \Va.k.a.
查找命令只会匹配a.k.a,不会再利用.的特殊含义去匹配类似backward的词。
技巧75 使用圆括号捕获子匹配
\_s
会匹配空白字符
技巧76 界定单词的边界
- 在very magic搜索模式下,用<和>符号表示单词定界符。
- 可以在圆括号前面加上%来匹配却不将其内容捕获保存给寄存器。
技巧77 界定匹配的边界
- 有时候我们想指定一个范围较广的模式,但只对匹配结果的一部分感兴趣。Vim中的元字符\zs和\ze可以帮助我们处理这种情况。
- 比如查找模式为:
/Practical \zsVim\ze
,则只有跟在Practical后面的Vim会被高亮查到。
技巧78 转义问题字符
- ‘\?/‘等字符需要手动转义,也可以使用vim自带的函数escape和getcmdtype,并借助表达式寄存器来解决,知道就行了。
- 在VIM脚本中,
.
操作符用来连接字符串。
十三、查找
技巧79 结识查找命令
- 如果只想在当前光标位置至文档结尾的范围内查找,而不想循环绕回去的话,可以关闭
wrapscan
选项。 - 如果不提供模式而直接查找,Vim将重用上一次查找的模式。
技巧80 高亮查找匹配
- 启用
hlsearch
选项可以高亮
技巧81 在执行查找前预览第一处匹配
incsearch
选项可以让Vim在真正执行查找命令前预览第一处匹配。- 该技巧也可以用来检查是否存在一处匹配。
- 快捷键
<ctrl+r><ctrl+w>
会根据当前预览的匹配结果对查找域进行自动补全。不过如果使用了元字符\v则该快捷键会有些瑕疵。
技巧82 统计当前模式的匹配个数
:%s///gn
可以统计次数,查找域用的是上次的查找模式,n会抑制正常的替换作用,改为简单的技术,所以替换域留空即可。
技巧83 将光标偏移到查找匹配的结尾
- 查找模式后面跟/e可以将光标偏移到匹配的结尾处。
技巧84 对完整的查找匹配进行操作
- 感觉就是在查找模式中利用\e、f{char}之类的标志位或命令选中完整的匹配。
技巧85 利用查找历史,迭代完成复杂的模式
q/
可以唤出命令历史。- 需要捕获引号括起来的内容的时候就记得可以用\1这种寄存器。
技巧86 查找当前高亮选区中的文本
- 这个目前可以忽略吧。
十四、替换
技巧87 结识substitute命令
- 基本的替换语法如下:
:[range]s[ubstitute]/{pattern}/{string}/[flags]
技巧88 在文件范围内查找并替换每一处匹配
- 缺省情况下,substitute命令只会作用于当前行且只修改第一处匹配。
- /g标志位可以使替换命令修改一整行的所有匹配,range域填%即可使其作用于所有每一行,两者结合就是全局替换。
技巧89 手动控制每一次替换操作
- /c标志位让我们可以控制每一次匹配的地方是否需要进行替换。
技巧90 重用上次的查找模式
- 将查找域留空,可以使Vim重用上次的查找模式。
- 需要注意,把查找域留空,会在命令历史中留下一项不完整的记录。这在有些时候会带来不便,因为查找模式的命令和替换操作的命令所保存的地方不一样。
技巧91 用寄存器的内容替换
- 如果某段文本已经在当前文档中出现过,我们可以先把它复制到寄存器,再通过传值或引用的方式将寄存器的内容应用到替换域。
- 假设我们已经复制了多行文本到寄存器0中,现在需要在替换域中使用这份内容,则可以使用
:%s//\=@0/g
。\=
表示Vim将执行一段表达式脚本。
技巧92 重复上一次的substitute命令
- 假如我们刚刚执行完一条替换命令,突然意识到了失误,应该加上%才对,这时可以使用
g&
,这条命令等价于:%s//~/&
,即可在整个文件的范围内重复该条命令。 - 总是可以指定一个新的范围,并使用
:&&
命令重新执行替换操作。 - &命令是:s命令的同义词,用于重复上一次的替换操作。但遗憾的是,不论上次使用的是什么标志位,&命令都将忽略他们。所以我们会用:&&,后一个&命令会保留标志位。
技巧93 使用子匹配重排CSV文件的字段
- 可以在查找模式中利用()捕获子匹配,并在替换域中引用它们。
技巧94 在替换过程中执行算术运算
- 替换域中的内容不一定非得是简单的字符串,我们可以执行一段Vim脚本表达式,然后用其结果充当字符串使用。
- 一般是先用正则表达式匹配我们要替换的区域,然后使用表达式寄存器,调用函数submatch(0)进行操作。
技巧95 交换两个或更多的单词
- 越来越复杂了,有点搞不定了。选择,替换。
技巧96 在多个文件中执行查找与替换
- Vim没有直接提供这样的功能,只能通过一些简单命令的组合,间接来实现这种功能。
- 有一种方法可以用
:argdo
命令,先打开所有文件,然后用该命令去替换。 - 但这会打开很多多余文件,还有一种方法,可以先选择匹配查找模式的文件,然后再在这些文件上执行命令。涉及到什么quickfix列表、copen命令,暂时不用管吧。
十五、global命令
技巧97 结识global命令
:global
命令结合了Ex命令和Vim的模式匹配两种功能,允许我们在某个指定模式的所有匹配行上执行Ex命令,语法如下:[range] global[!] /{pattern}/ [cmd]
- 缺省情况下,global命令的作用范围是整个文件。
- global!或者vglobal命令表示反转,会在没有匹配到模式的行上执行cmd命令。
技巧98 删除所有包含模式的文本行
- 将
:global
和:delete
命令一起组合使用,可快速剪裁文本。 - 用
:g/re/d
可以删除匹配的所有行,相反:v/re/d
可以删除不匹配的所有行。 - 其实grep命令即是
:g/re/p
,这样就能记住了。
技巧99 将TODO项收集至寄存器
- 和上条相似,将
:global
和:yank
一起组合使用,就可以把匹配项文本行收集到某个寄存器中。 :t
命令见技巧29,主要是把一些内容显示到文本结尾,不想影响寄存器内容的时候可以用。
技巧100 将CSS文件中所有规则的属性按照字母排序
:global
的广义模式:g/{start}/ .,{finish} [cmd]
,可以理解成从start开始,到finish结束的所有行进行指定的cmd操作。.
在这里表示当前行。
十六、通过ctags建立索引,并引用其浏览源代码
技巧101 结识ctags
- 例如在Ubuntu上,可以通过
sudo apt-get install exuberant-ctags
的方式安装该程序 - 标签文件的前几行由元数据组成,而后每一行文本均有关键字、文件名以及关键字在源代码中的位置这3项内容构成。关键字会按照字母顺序排列。
- 用模式定位关键字,而不是用行号。
- 用元数据标记关键字
技巧102 配置Vim使用ctags
:set tags?
可以查看ctags缺省配置- 通过
:!ctags -R
可以在Vim中直接调用生成tags文件。 - 还可以使用映射项以及
:autocmd BufWritePost * call system("ctags -R")
命令实现在每次保存文件时自动调用ctags。 - 还有一种策略可以实现在每次提交代码改动时自动更新代码库的索引,详见p239。
技巧103 使用Vim的标签跳转命令,浏览关键字的定义
<ctrl+]>
可以跳转到关键字的定义处。此时<ctrl+t>
会充当后退到原处的功能。g<ctrl+]>
可以在有多次匹配定义的时候让我们自行挑选需要跳转的地方。- 其实不必非得将光标移到关键字上才能进行标签跳转,也可以用Ex命令达到同样的目的,例如
:tag {keyward}
与:tjump {keyward}
分别等同于上述两个命令。
十七、编译代码,并通过Quickfix列表浏览错误信息
技巧104 不用离开Vim也能编译代码
- 在Vim中可以直接使用
:make
编译代码,不止会显示make命令的结果以外,还会解析每一行内容,对于每一条错误信息都会在quickfix列表中为其创建一项纪录,运行后会跳转到quickfix列表的第一项纪录。 - 如果不想跳转到第一项纪录,可以
:make!
。
技巧105 浏览Quickfix列表
- quickfix列表会保存一组针对单个或多个文件内容的位置信息,这些信息来自于
:make
、:grep
以及:vimgrep
。 - 对于每一条用于填充quickfix列表的命令,前面加个l都能操作对应的位置列表。位置列表可以理解成每个缓冲区的局部变量,而quickfix列表是全局变量。
:cnext
和:cprevios
两个命令用来操作最基本的quickfix列表前后移动。:copen
可以打开包含quickfix列表内容的窗口。
技巧106 回溯以前的Quickfix列表
- 更新quickfix列表时,Vim并不会覆盖之前的内容,而是将使用过的quickfix列表结果保存起来,方便回溯。
:colder
命令可以回溯quickfix列表之前的某个版本(Vim保存最近10个)。为了从旧的回到新一版的,则可以运行:cnewer
。
技巧107 定制外部编译器
- Vim的
:make
不仅限于调用外部的make程序,也可以调用任何安装在你机器上的编译器。 - 这节主要写了个例子,讲述如何在vim里配置别的编译器,没有细看
- 在Vim的术语中,编译器是指任何可以针对文档进行处理,并生成错误警告的外部程序。而
:make
命令指负责调用外部编译器,并对其输出进行解析,以此构建一个可供浏览的quickfix列表。 vim -u NONE -N file
十八 通过grep、vimgrep以及其他工具对整个工程进行查找
技巧108 不必离开Vim也能调用grep
- -n选项会在grep的结果中加入行号信息
- Vim中外部grep命令进行了封装,可以直接调用。Vim会解析grep的输出并根据输出创建一个quickfix列表,然后我们可以通过quickfix列表进行跳转,内部的grep命令会自动封装-n选项。如果要忽略大小写,需要手动加-i选项。
技巧109 定制grep
- Vim中的grep命令是外部grep程序的包装器,通过配置
grepprg
和grepformat
两个选项来对Vim查找的行为进行定制。 - 主要可以安装一个ack命令来用,暂时没有细看。
技巧110 使用Vim内部的grep
:vimgrep
命令允许我们使用Vim自带的正则表达式引擎,实现跨文件的查找功能。此命令可以缩写成:vim
。格式如:vim[grep][!] /{pattern}/[g][j] {file} ...
- 通配符
*
会匹配某个目录下的任意文件,而通配符**
会匹配指定目录以及所有子目录文件。##
会被扩展成参数列表中的所有文件。 - 如果模式域为空,则会匹配所有行。
- 如果想使用最近一次的查找模式,必须通过
<ctrl+r>/
将其直接粘贴到查找域才行。
十九 自动补全
技巧111 结识Vim的关键字自动补全
- Vim的自动补全功能可以在插入模式下被触发。
- 通过
<ctrl+p>
和<ctrl+n>
可以实现普通关键字自动补全,可以在插入模式下触发Vim的自动补全,还可以利用他们在补全列表里正向或反向寻找。 - 除了最常用的
<ctrl+p><ctrl+n>
两个命令外还有一些其他的补全命令,见表19-1,p263。
技巧112 与自动补全的弹出式菜单进行交互
- 有几个重要的快捷键记忆一下。
<ctrl+y>
确认使用当前选中的匹配行,<ctrl+e>
还原最早输入的文本,即退出自动补全。<ctrl+h>
从当前匹配项中删除一个字符,<ctrl+l>
从当前匹配项中增加一个字符。 - 建议浏览补全列表的时候不要用上下键,因为还需要按回车才能选中,而且手指得从本位行上移开。
- 连续输入
<ctrl+p><strl+n>
可以实现实时过滤补全列表,很好用。
技巧113 掌握关键字的来龙去脉
- 普通关键字自动补全会把来自多个来源的内容编入其补全列表,我们可以对生成补全列表项的来源加以限定。
:!ls
可以用来查看缓冲区列表。<ctrl+x><ctrl+i>
可以补全一些来自其他代码里的单词,就像include的一样。还有比如<ctrl+x><ctrl+]>
可以补全ctags生成的文件里的单词。总的来说,普通关键字补全是最全的,但如果嫌多想要特定来源的补全的话,就用<ctrl+x>
加特定的快捷键来实现,见表19-1。
技巧114 使用字典中的单词进行自动补全
<ctrl+x><ctrl+k>
可以实现自动补全某个字典单词功能。为了激活该功能,我们需要为Vim提供一份合适的单词列表,最简单的办法就是运行:set spell
激活Vim的拼写检查功能。
技巧115 自动补全整行文本
<ctrl+x><ctrl+l>
面向行自动补全。
技巧116 自动补全文件名
<ctrl+x><ctrl+f>
可以自动补全文件名。- Vim的文件名自动补全功能只能相对于工作目录的路径进行扩展,而不是相对于当前编辑文件的路径。
:cd -
可以在Vim中切换到之前的工作目录。
技巧117 根据上下文自动补全
<ctrl+x><ctrl+o>
实现该功能,全能补全。实际上,该功能由专用的文件类型插件实现,需要下载以下配置行:
1
2set nocompatible
filetype plugin on此外还需要安装一个为所用语言实现了全能补全功能的插件。
二十 利用Vim的拼写检查器,查找并更正拼写错误
技巧118 对你的工作进行拼写检查
- 使用
:set spell
可以对所有未在拼写文件中出现过的单词进行高亮标记。 - 可以使用
[s
和]s
命令在拼写错误的单词间进行跳转。当光标位于某个拼错的单词上时,可以使用z=
命令来获取Vim提供的更正建议列表。
技巧119 使用其他拼写字典
- 修改配置
spelllang
选项可以更改缺省的拼写字典,要注意的是这不是全局性的,永远只在本地缓冲区生效。这意味着可以在编辑两个或多个文档时采用不同的拼写字典。 - 可以使用spellfile.vim的插件安装其他所需的语言拼写字典,为了激活这个功能,需要在vimrc中添加两行,具体看p276吧。
技巧120 将单词添加到拼写文件中
- 我们可以自定义拼写文件里的词。
zg
命令可以把光标下的单词添加到拼写文件中,zw
则是相反功能,将单词从拼写文件中删除,zug
则是撤销光标所在单词执行过的zg
或者zw
。
技巧121 在插入模式下更正拼写错误
- 插入模式下使用
<ctrl+x>s
或者<ctrl+x><ctrl+s>
可以使用拼写自动补全功能。其中<ctrl+x>s
会有点特殊,它会使Vim从光标所在位置开始方向扫描,直到发现一处拼写错误为止,然后再根据更正建议创建单词列表并显示在弹出菜单里,适合写完一行修正这一行的所有错误时使用。
最后
- 动态改变Vim的设置项:以
ignorecase
为例,其可被缩写成ic
。
命令 | 效果 |
---|---|
:set ignorecase | 开启ignorecase |
:set noignorecase | 关闭ignorecase |
:set ignorecase! | 反转 |
:set ignorecase? | 获取当前设置的状态 |
:set ignorecase& | 恢复默认状态 |
- 在Vim里内使用
:edit $MYVIMRC
可以打开vimrc。 - 可以为特定类型的文件应用个性化设置。
【END】