vim实用技巧10-15

Vim 的删除、复制与粘贴命令都会用到众多寄存器中的某一个。我们可以通过给命令加"{register} 前缀的方式指定要用的寄存器。若不指明,Vim 将缺省使用无名寄存器。

cut/copy/paste ----delete/yank/put

倘若我们没有指定要使用的寄存器,Vim 将缺省使用无名寄存器,它可以用双引号表示。

当我们使用y{motion} 命令时,要复制的文本不仅会被拷贝到无名寄存器中,而且也被拷贝到了复制专用寄存器中,后者可用数字0(参见 :h quote0 )加以引用 "0。

用小写字母引用有名寄存器,会覆盖该寄存器的原有内容,而换用大写字母的话,则会将新内容添加到该寄存器的原有内容之后。

黑洞寄存器是个有去无回的地方,可用下划线(参见 :h quote_ )引用它。如果我们运行 "_d{motion} 命令,Vim 将删除该文本且不保存任何副本。当我们只想删除文本却不想覆盖无名寄存器中的内容时,此命令很管用。

Vim 的加号寄存器与系统剪贴板等效,可用 + 号(参见 :h quote+ )引用。

Windows 与Mac OS X 操作系统并没有主剪贴板的概念,因此 "+ 寄存器与 "* 寄存器可以混用,它们都代表系统剪贴板。

表达式寄存器("=)

Vim 的寄存器通常被认为是保存一段文本的容器。然而,通过 = 号(参见:h quote=)引用的表达式寄存器却是个例外。当我们从表达式寄存器获取内容时,Vim 将跳到命令行模式,并显示提示符“=”。这时,我们可以输入一段Vim 脚本表达式并按 执行,如果返回的是字符串(或者可被强制转换成字符串的数据),Vim 将会使用它。

Vim 还提供了几组可被隐式赋值的寄存器。它们被称作只读寄存器。

[图片上传失败...(image-470926-1584626913204)]

在可视模式下使用p 命令时,Vim 将用我们指定的寄存器内容来替换高亮选区中的文本。

m{char} 命令负责设置标记,而 `{char} 命令将跳转到该标记。

面向行的复制或者删除操作(例如:dd、yy 或者dap),将创建面向行的寄存器;而面向字符的复制或者删除操作(例如:x、diw 或者das),则创建面向字符的寄存器。

在插入模式下,我们可以通过输入" 来插入无名寄存器的内容,或者输入0 来插入复制专用寄存器的内容。

Vim 提供的gp 和gP 命令也值得关注,因为它们同样可以将文本粘贴至在当前行之前或之后。不同的是,它们会把光标的位置移到被粘贴出来的文本结尾而不是开头。当复制多行文本时,gP 命令尤为管用。

p 与 P 命令对于粘贴多行文本区域非常重要,但是对于小段的、面向字符的文本来讲,使用{register} 映射项的方式会更直观。

'paste'选项允许我们手动通知Vim“要使用系统粘贴命令了”。当'paste'选项被启用后,Vim 将禁用所有插入模式下的映射项与缩写,并重置很多选项,其中就包括'autoindent'(有关的完整列表,请查阅:h 'paste' )。这样一来,我们就能安全地使用系统剪贴板进行粘贴操作了,绝无意外情况发生。

为避免切换'paste'选项,请使用加号寄存器进行粘贴。如果你运行的Vim 是已集成系统剪贴板的版本,就可以完全避免与'paste'选项打交道了。普通模式下的 "+p 命令用来粘贴加号寄存器中的内容,即系统剪贴板的镜像。更多细节,请参见系统剪贴板("+)与选择专用寄存器("*)。无论'paste'与'autocommand'选项激活与否,该命令都能保证位于剪贴板中的文本缩进不会乱套。

我们可以用宏把任意数目的按键操作录制到寄存器,用于之后的回放。宏很适合针对一系列相似的行、段落,甚至是文件,进行重复性的修改。宏允许我们把一段修改序列录制下来,用于之后的回放。

q 键既是“录制”按钮,也是“停止”按钮。为了录制我们的按键操作,一开始需要按q{register},从而指定一个用于保存宏的寄存器。当状态栏中出现“记录中”时,表示录制已经开始。此后,我们执行的每一条命令都将被宏捕获,直到我们再次按下q 键停下为止。

我们可以用@{register} 命令执行指定寄存器的内容(参见:h @ ),也可以用@@ 来重复最近调用过的宏。

黄金法则:在录制一个宏时,要确保每条命令都可被重复执行。

如果宏执行动作命令失败了,Vim 将中止执行宏的其余命令。这是一项功能,而不是漏洞。我们可以用动作命令进行简单测试,来判断该宏是否应该在当前上下文中继续执行。

在我们输入qa 时,Vim 将开始录制接下来的按键操作,并将它们保存到寄存器a中,这会覆盖该寄存器原有的内容。如果我们输入的是qA 的话,Vim 也会录制按键操作,但会把它们附加到寄存器a 原有的内容之后。

:argdo 命令允许我们对参数列表内的所有缓冲区执行一条Ex 命令。

"寄存器:取出寄存器中的文本内容进行文本操作。 @寄存器 :把寄存器中的文本内容当做命令进行执行。

通过使用元字符\c 与\C,可以覆盖Vim缺省的大小写敏感性设置。小写字母\c会让查找模式忽略大小写,而大写字母\C 则会强制区分大小写。若在某个查找模式中使用了两者中的某一个,‘ignorecase’的值将被这次查找忽略。

注意:这两个元字符可以出现在模式的任意位置。假设你已输入了完整的模式,却发现需要按区分大小写的方式进行查找。此时,你只需在模式的结尾加上\C ,该元字符就会作用于它前面的所有文本。

Vim 提供了一项额外设置,用于最大限度地推测我们是想用大写还是小写,这就是‘smartcase’选项。该选项被启用后,无论何时,只要我们在查找模式中输入了大写字母,‘ignorecase’设置就不再生效了。换句话说,如果我们的模式全是由小写字母组成的,就会按照忽略大小写的方式进行查找,但只要我们输入一个大写字母,查找方式就会变成区分大小写的了。

我们用到了3 类括号。方括号缺省具有特殊含义,因此不用转义。圆括号会按原义匹配字符(及),因此需要转义,使其具有特殊含义。花括号也一样需要转义,不过,我们只需为开括号转义,而与之对应的闭括号则不用,因为Vim 会推测我们的意图。圆括号的情况有所不同,无论开闭括号都必须转义。

我们可以利用 \v 模式开关来统一所有特殊符号的规则。该元字符将会激活very

magic 搜索模式,即假定除_、大小写字母以及数字0 到9 之外的所有字符都具有特殊含义。

字符# 没有特殊含义,因此可按原义匹配。还记得very magic搜索模式是把除_、字母和数字以外的所有字符都当作具有特殊含义的字符吗?看样子我们已经发现了该规则的一个特例。对于这个问题,Vim 的解释是任何还未具有特殊含义的字符都被“保留以备将来扩展时使用”(参见:h /\ )。换句话说,尽管# 目前不具有特殊含义,但不意味着将来的版本也会这样。万一将来 # 被赋予了特殊含义,我们必须要将其转义后,才可以匹配“#”字符本身。

我们可以使用原义开关\V,激活very nomagic 搜索模式。使用 "\V" 会使得其后的模式中只有反斜杠有特殊的意义。

作为通用法则,如果你想按正则表达式查找,就用模式开关\v,而如果你想按原义查找文本,就用原义开关\V。

不论模式中是否使用了圆括号,元字符 \0 永远会引用整个匹配。

在very magic 搜索模式下,用 <与> 符号表示单词定界符。这些就是所谓的零宽度元字符,它们本身不匹配任何字符,仅表示单词与围绕此单词的空白字符(或标点符号)之间的边界。

。\w 匹配单词类字符,包括字母、数字以及符号“_”,而\W 则用来匹配除单词类字符以外的其他字符。

。我们可以在分组圆括号前面加上% ,指示Vim 不要将括号内的内容赋给寄存器。

有时候,我们可能想指定一个范围较广的模式,但只对匹配结果的一部分感兴趣。Vim 中的元字符\zs 与\ze 可以帮助我们处理这种情况。

当我们谈论一个模式的时候,指的是在查找域输入的正则表达式(或者按原义匹配的文本);而匹配,是指在文档中被高亮显示的文本(假设已经启用'hlsearch'选项)。

元字符\zs 标志着一个匹配的起始,而元字符\ze 则用来界定匹配的结束。将二者相结合,我们可以定义一个特殊的模式,它们可以让我们定义一个模式匹配一个较大的文本范围,然后再收窄匹配范围。与单词定界符(前一节已介绍过)类似,\zs 与\ze均为零宽度元字符。

[图片上传失败...(image-bae3e4-1584626913204)]

:incsearch该设置会让Vim 根据已在查找域中输入的文本,预览第一处匹配。

当我们把查找域留空时,Vim 将重用上一次的查找模式。

:substitute 命令很复杂,除了要提供查找的模式以及替换字符串外,还要指定执行的范围。另外,作为可选项,我们还可以通过标志位来调整该命令的行为。

:[range]s[ubstitute]/{pattern}/{string}/[flags]

标志位n 会抑制正常的替换行为,即让 Vim 不执行替换操作,而只是报告本次substitute 命令匹配的个数。

标志位& 仅仅用于指示Vim 重用上一次substitute 命令所用过的标志位。

[图片上传失败...(image-a7cea5-1584626913203)]

在缺省情况下,substitute 命令仅仅作用于当前行,而且只会修改第一处匹配。因此,为了在整个文件的范围内修改每一处匹配,我们必须指定范围,并使用标志位 g 。

标志位c选项含义:

[图片上传失败...(image-2d1c37-1584626913203)]

将substitute 命令的查找域留空,意味着Vim 将会重用上次的查找模式。我们可以利用这一特点精简工作过程。

通过输入{register},我们可以将寄存器的内容插入到命令行。替换域中出现的= 将指示 Vim 执行一段表达式脚本。在Vim 脚本中,我们可以用@{register} 来引用某个寄存器的内容。

g&命令可以在整个文件范围内用同样的标志位、同样的替换字符串、同样的查找模式以及新的执行范围%,重复上一次substitute 命令。

:&& 命令,因为这两处& 符号的含义有所不同。前一个& 作为Ex 命令:& 的组成部分,用作重复上一次的:substitute 命令(参见:h :&),而第二个& 则会重用上一次:s 命令的标志位。

& 命令是:s 命令的同义词,用于重复上一次的替换操作。

在Vim 的命令行中,| 仅仅表示命令的分隔。

:global 命令结合了Ex 命令与Vim 的模式匹配这两方面能力。凭借该命令,我们可以在某个指定模式的所有匹配行上运行Ex 命令。就处理重复工作的效率而言,global 命令是除点范式以及宏之外,最为强大的Vim 工具之一。

:[range] global[!] /{pattern}/ [cmd]

在缺省情况下,:global 命令的作用范围是整个文件(%),这一点与其他大多数Ex 命令(包括 :delete、:substitute 以及:normal)有所不同,这些命令的缺省范围仅为当前行(.)。

{pattern} 域与查找历史相互关联。这意味着如果将该域留空的话,Vim会自动使用当前的查找模式。[cmd] 可以是除:global 命令之外的任何Ex 命令。如果我们不指定任何[cmd],Vim 将缺省使用:print。

还有,我们可以用:global! 或者:vglobal(v 表示invert)反转:global 命令的行为。这两条命令将指示Vim 在没有匹配到指定模式的行上执行[cmd]。

最后需要指出的是:global 命令在指定[range] 内的文本行上执行时通常分为两轮。第一轮,Vim 会在所有 [pattern] 的匹配行上做上标记。第二轮,再在所有已标记的文本行上执行[cmd] 。另外,由于[cmd] 的范围可单独设定,因此可在多行文本段内进行操作。

你可能感兴趣的:(vim实用技巧10-15)