vim实用技巧5-9
在命令行模式中执行的命令又被称做 Ex 命令。
[图片上传失败...(image-ded974-1584542711673)]
[图片上传失败...(image-7fc0f4-1584542711673)]
很多 Ex 命令可以用[range] 指定要操作的范围。我们可以用行号、位置标记或是查找模式来指定范围的开始位置及结束位置。
用地址指定一个范围(行号)--用高亮选区指定范围----用模式指定范围
符号. 代表当前行的地址。
符号% 也有特殊含义,它代表当前文件中的所有行。
选中一块高亮选区,如果现在按下: 键,命令行上就会预先填充一个范围:'<,'>。这个范围看起来有点晦涩难懂,不过你可以简单地把它理解为一个代表高亮选区的范围。符号'< 是代表高亮选区首行的位置标记,而'> 则代表高亮选区的最后一行。这些位置标记即使在退出可视模式后仍然存在。如果你尝试在普通模式下直接运行:'<,'>p,它会始终回显上一次高亮选区所选中的内容。
用偏移对地址进行修正。偏移的一般形式是这样的::{address}+n 如果 n 被省略,那么缺省偏移量为1。{address} 可以是一个行号、一个位置标记,或是一个查找模式。
:copy 命令(及其简写形式:t)让我们可以把一行或多行从文档的一部分复制到另一部分,而:move 命令则可以让我们把一行或多行移到文档的其他地方。
copy 命令的格式如下 :[range]copy {address} :copy --:co --:t :move ---:m
如果想在一系列连续行上执行一条普通模式命令,我们可以用:normal 命令。虽然用:normal 命令可以执行任意的普通模式命令,但是我发现当它和 Vim的重复命令结合在一起时,最为强大,既可以用:normal . 应对简单的重复性工作,也可以用:normal @q 应对较复杂的任务。
:normal 命令让我们可以把具有强大表现力的 Vim 普通模式命令与具有大范围影响力的 Ex 命令结合在一起。
. 命令可以重复上次的普通模式命令。然而,如果想重复上次的 Ex 命令的话,我们得使用@: 才行。: 寄存器总是保存着最后执行的命令行命令(参见:h quote_: )。在运行过一次@: 后,后面就可以用@@ 命令来重复它。
<C-d> 命令会让Vim 显示可用的补全列表。
在很多场景中,Vim 的 Tab 补全都能做出正确的选择。如果我们输入了一个以文件路径作为参数的命令(如:edit 或:write),那么<Tab> 会用当前工作目录中的目录或文件名进行补全。在:tag 命令中,它会自动补全标签名;而在:set 及:help命令中,它可以对 Vim 的每一个设置选项进行补全。
在 Vim 的命令行下, <C-r><C-w> 映射项会复制光标下的单词并把它插入到命令行中。<C-r><C-w> 用于插入光标下的单词,而如果想插入光标下的字串的话,我们可以用<C-r><C-a>。
Vim 缺省会记录最后20 条命令,对内存越发便宜的现代计算机来说,保存更多历史命令只是小菜一碟,因此我们可以修改‘history’ 选项,以提高其保存的上限。
Vim 不仅会记录 Ex 命令的历史,它也会为查找命令单独保存一份历史记录。在按/ 调出查找提示符后,用<Up> 和<Down> 键就可以正向或反向遍历之前的查找记录。从本质上讲,查找提示符只是命令行模式的另一种形式。
q:命令行窗口。命令行窗口就像是一个常规的 Vim 缓冲区,只不过它的每行内容都对应着命令历史中的一个条目。我们可以用k 及j 键在历史中向前或向后移动,也可以用 Vim 的查找功能查找某一行。在按下<CR> 键时,将会把当前行的内容当成Ex 命令加以执行。
当命令行窗口处于打开状态时,它会始终拥有焦点。这意味着,除非关闭命令行窗口,否则我们无法切换到其他窗口。要想关闭命令行窗口,我们可以执行:q 命令(就像关闭普通 Vim 窗口那样),或是按<CR> 。
打开命令行窗口的几种方式
[图片上传失败...(image-8d7dd2-1584542711673)]
我们不用离开 Vim 就能方便地调用外部程序。更棒的是,我们还可以把缓冲区的内容作为标准输入发送给一个外部命令,或是把外部命令的标准输出导入到缓冲区里。
:!{cmd} 这种语法适用于执行一次性命令,但是如果想在 shell 中执行几条命令要怎么做?对这种情况,可以执行 Vim 的:shell 命令来启动一个交互的 shell 会话。用exit 命令可以退出此 shell 并返回 Vim。
:read !{cmd} 命令让我们把命令的标准输出重定向到缓冲区。正如你所期望的一样,:write !{cmd} 做相反的事。它把缓冲区内容作为指定{cmd} 的标准输入。:write !sh 命令的作用是在shell 中执行当前缓冲区中的每行内容。
[图片上传失败...(image-ee4182-1584542711673)]
在一次编辑会话中,可以打开多个文件。用Vim 的缓冲区列表可以对这些文件进行管理。
% 符号指明哪个缓冲区在当前窗口中可见,而# 符号则代表轮换文件。按<C-^>可以在当前文件和轮换文件间快速切换。我们可以用4 条命令来遍历缓冲区列表。:bprev 和:bnext 在列表中反向或正向移动,每次移动一项;而:bfirst 和:blast 则分别跳到列表的开头和结尾。
:ls 列表的开头有一个数字,它是在缓冲区创建时由 Vim 自动分配的编号。我们可以用:buffer N 命令直接凭编号跳转到一个缓冲区(参见:h :b ),或是用更直观的:buffer {bufname} 格式实现同样的功能。{bufname} 只需包含文件路径中足以唯一标识此缓冲区的字符即可。如果输入的字符串匹配了不止一个缓冲区列表中的条目,此时可以用 Tab 补全的方式在这些条目中选择。
删除一个缓冲区并不会影响缓冲区所关联的文件,而只是简单地把该文件在内存中的映像删掉。
参数列表易于管理,适用于对一批文件进行分组,使其更容易访问。用:argdo命令可以在参数列表中的每个文件上执行一条 Ex 命令。
实际上,我们可以在任意时刻改变参数列表的内容,就是说:args 列表并不一定反映启动Vim 时所传的参数。千万别被表面的名字给唬住了!
填充参数列表 :args {arglist} {arglist} 可以包括文件名、通配符,甚至是一条 shell 命令的输出结果。
用文件名指定文件:填充参数列表最简单的方式是逐一指定文件的名字。
用 Glob 模式指定文件:通配符是一个占位标记,它代表了可用于文件或目录名称的字符。* 符号用于匹配0 个或多个字符,但它的范围仅局限于指定的目录,而不会递归其子目录(参见:hwildcard );** 通配符也匹配0 个或多个字符,但它可以递归进入指定目录的子目录。
[图片上传失败...(image-316214-1584542711673)]
用反引号结构指定文件。
Vim 对被修改过的缓冲区会给予特殊对待,以防未加保存就意外退出。
如果想退出 Vim 而不想对未保存的修改进行检查,可以执行:qall! 命令;如果想保存所有有改动的缓冲区而无需逐个检查,可以用:wall 命令。
[图片上传失败...(image-bd7523-1584542711673)]
在Vim 术语中,窗口是缓冲区的显示区域(参见:h window )。我们既可以打开多个窗口,在这些窗口中显示同一个缓冲区,也可以在每个窗口里载入不同的缓冲区。Vim 的窗口管理系统很灵活,我们可以根据工作的需要来调整工作区。
Vim 在启动时只会打开单个窗口。用<C-w>s 命令可以水平切分此窗口,使之成为两个高度相同的窗口;或者可以用<C-w>v 命令对其进行垂直切分,这样会产生两个宽度相同的窗口。这两条命令可以重复任意多次,结果就会把工作区一次次地切分为更小的窗口,就像细胞分裂那样。
每次执行完<C-w>s 和<C-w>v 命令后,新生成的两个窗口都会显示与原窗口相同的缓冲区。
[图片上传失败...(image-8c9d5c-1584542711673)]
[图片上传失败...(image-c2bd22-1584542711673)]
[图片上传失败...(image-71755a-1584542711673)]
[图片上传失败...(image-9ed4a6-1584542711673)]
在 Vim 中,标签页是可以容纳一系列窗口的容器。
:lcd {path} 命令让我们可以设置当前窗口的本地工作目录。如果我们创建了一个新标签页,并用:lcd 命令切换到另一个目录,那么就可以把每个标签页限制在不同的工程范围内。注意::lcd 只影响当前窗口,而非当前标签页。如果一个标签页包含了两个或更多的窗口,我们可以用:windo lcd {path} 命令为所有这些窗口设置本地工作目录。
用:tabedit {filename} 命令可以打开一个新的标签页, 如果省略了{filename} 参数的话,那么 Vim 会创建一个新标签页,里面包含一个空缓冲区。
如果当前标签页中包含了不止一个窗口,我们可以用<C-w>T 命令把当前窗口移到一个新标签页中。
:tabclose 命令来关闭当前标签页,无论其中有多少个窗口。如果想关闭除当前标签页外的所有其他标签页,可以用:tabonly 命令。
用:tabmove [N] 命令可以重新排列标签页。当[N] 为0 时,当前标签页会被移到开头;如果省略了[N],当前标签页会被移到结尾。
[图片上传失败...(image-9da5d7-1584542711673)]
[图片上传失败...(image-7c4a9c-1584542711673)]
:edit %<Tab> % 符号代表活动缓冲区的完整文件路径(参见:h cmdline-special ),按<Tab>键会将其展开,使之显示为活动缓冲区的完整文件路径。
:edit %:h<Tab> :h 修饰符会去除文件名,但保留路径中的其他部分。
当‘wildmenu’ 选项被启用时,Vim 会提供一个补全导航列表。调整‘wildmode’ 选项可以自定义补全行为。
我们可以用:edit {path} 命令打开文件管理器窗口,只是在执行此命令时要以目录名(而不是文件名)作为{path} 参数。
如果想在文件管理器里打开当前文件所在的目录,可以输入:edit %:h。
要想返回上级目录,可以使用 - 键,或是把光标移到 .. 条目上再按<CR>。
(<C-g> 命令用于显示当前文件的文件名及状态。[图片上传失败...(image-1b57fe-1584542711673)]
动作命令:motion
与许多文本编辑器不同,Vim 会区分实际行与屏幕行。当‘wrap’ 设置被启用时(缺省启用),每个超出窗口宽度的文本行都会被回绕显示,以保证没有文本显示不出来。这样一来,文件中的一行也许会被显示为屏幕上的若干行。
j 和k 命令会根据实际行向下及向上移动,而gj 和gk 则是按屏幕行向下及向上移动。
[图片上传失败...(image-63034-1584542711673)]
你可以留意到这样一个特点,即j、k、0 和$ 都用于操作实际行,而如果在这些键前加上g 前缀的话,就会让 Vim 对屏幕行进行操作。
单词与字串之间的区别 :w W | b B | e E | ge gE
f{char} 命令是在 Vim 中移动的最快方式之一。它会在光标位置与当前行行尾之间查找指定的字符,如果找到了,就会把光标移到此字符上;如果未找到,则保持光标不动。
[图片上传失败...(image-14775e-1584542711673)]
[图片上传失败...(image-72dd7a-1584542711673)]
[图片上传失败...(image-624e2e-1584542711673)]
文本对象就是基于结构定义的文本区域。
Vim 的文本对象由两个字符组成,第一个字符永远是i 或是a。我们一般说,以i 开头的文本对象会选择分隔符内部的文本,而以a 开头的文本对象则会选择包括分隔符在内的整个文本。为了便于记忆,可以把i 想成“inside”,而把a 想成“around” 或“all”。
[图片上传失败...(image-57de31-1584542711673)] 可视模式适用于介绍文本对象,因为可以很容易看到发生的变化。然而,在操作符待决模式中使用文本对象,才能真正展现出它们的强大能力。
文本对象自身并不是动作命令,我们不能用它们在文档中移动。但是我们却可以在可视模式及操作符待决模式中使用文本对象。记住:每当在命令语法里看到{motion} 时,你也可以在这个地方使用文本对象,常见的例子包括d{motion}、c{motion}和y{motion}。
文本对象通常是成对出现的,一个用于操作对象内部的文本,而另一个则操作对象周围的文本。Vim 的文本对象分为两类:一类是操作分隔符的文本对象,如i)、i" 和it;另一类用于操作文本块,如单词、句子和段落。
[图片上传失败...(image-3fd9ca-1584542711673)]
我把第一类标注为“分隔符文本对象”,因为它们以配对的符号作为开始和结束。单词、句子以及段落则以文本结构的范围进行界定,因此我把这一类称为“范围文本对象”。
Vim 的位置标记允许我们快速跳转到文档中感兴趣的地方。我们可以手动设置位置标记,不过 Vim 也会自动帮我们记录某些感兴趣的位置点。m{a-zA-Z} 命令会用选定的字母标记当前光标所在位置(参见:h m )。小写位置标记只在每个缓冲区里局部可见,而大写位置标记则全局可见。
Vim 提供了两条普通模式命令,可以用它们跳转到一个位置标记上(注意,这两条命令看起来很像)。\‘{mark} 命令跳到位置标记所在行,并把光标置于该行第一个非空白字符上;而`{mark} 命令则把光标移动到设置此位置标记时光标所在之处,也就是说,它同时恢复行、列的位置。
我们可以为每个缓冲区设置最多26 个小写位置标记。字母表中的每个字母都对应着一个位置标记。
[图片上传失败...(image-ad1bba-1584542711673)]
Vim 提供了一个动作命令,让我们可以在开、闭括号间跳转。% 命令允许我们在一组开、闭括号间跳转(参见:h % ),它可作用于 ()、{}以及[]。
对修改配对的括号时此处的窍门是在做修改之前,要先执行一次% 命令。在执行% 命令时,Vim 会自动为发生跳转的地方设置一个位置标记,而后我们就可以按`` 跳回那里。
Vim 会记录跳转前后的位置,并提供了一些命令让我们能够沿原路返回。
<C-o> 命令像后退按钮一样,而与之互补的<C-i> 命令则像是前进按钮。这两条命令允许我们对 Vim 的跳转列表进行遍历。
任何改变当前窗口中活动文件的命令,都可以被称为跳转命令。Vim 会把执行跳转命令之前和之后的光标位置,记录到跳转列表中。
用[count]G 命令直接跳到指定的行号也会被当成一次跳转,但每次向上或向下移动一行则不算。面向句子的动作及面向段落的动作都算跳转,但面向字符及面向单词的动作则不算。用一句话来概括,我们可以说大范围的动作命令可能会被当成跳转,但小范围的动作命令则只能算移动。
[图片上传失败...(image-9f4aa7-1584542711673)]
<C-o> 和<C-i> 命令本身不会被当成动作命令。也就是说,我们既不能用它们扩大可视模式的选区,也不能在操作符待决模式中使用它们。我个人更倾向于把跳转列表当成一条“面包屑小径”①,它记录了我们在编辑会话中所访问过的文件,用它就可以很容易地沿原路返回。
Vim 可以同时维护多份跳转列表。实际上,每个单独的窗口都拥有一份自己的跳转列表。如果你正在使用分割窗口或多标签页,那么<C-o> 和<C-i> 命令会始终在当前活动窗口的跳转列表范围内进行跳转。
Vim 会在编辑会话期间维护一张表,里面记载我们对每个缓冲区所做的修改,此表就是所谓的改变列表(:changes)
Vim 会为编辑会话中的每个单独缓冲区维护一个改变列表,而与之不同的是,每个窗口都会创建一个单独的跳转列表。
Vim 会把文档中的文件名当成一个超链接。在进行了正确的配置后,我们就可以用gf 命令跳转到光标下的文件了。
每次用gf 命令时,Vim 都会在跳转列表中增添一条记录,因此我们总是可以用<C-o> 命令返回原处。
这正是'path' 选项的用处 (参见:h 'path' ),我们可以把它配置成一个以逗号分隔的目录列表。当使用gf 命令时,Vim 会检查'path' 目录列表中的每个目录,看该目录中是否包含一个匹配光标下文本的文件名。'path' 设置也会用于:find 命令。
'suffixesadd' 和'path' 选项可以针对每个缓冲区进行设置,因此对不同的文件类型可以设置不同的值。
跳转列表和改变列表如同“面包屑小径”一样,它们允许我们沿原路返回。而gf 和<C-]> 命令则像是“虫洞”,它把我们从代码的一个地方传送到另一个地方。
m{letter} 命令允许我们在当前光标位置创建一个位置标记(参见:h m )。小写字母会创建局部于缓冲区的标记,而大写字母则创建全局标记。设置好标记后,就可以用{letter} 命令使光标快速回到标记所在之处(参见:h
)。