原文链接:Vim registers: The basics and beyond

Vim 寄存器是那种可能知道你学了才会觉得需要的东西。而在你学了之后,寄存器就成了工作流中必不可少,难以抛弃的东西。尽管如此,还是有很多人用 vim 多年却还不知道怎么恰当地使用寄存器。跟上我,你不会成为他们中的一员。

如果你不知道我在说什么

你可以把寄存器想象成 vim 用来存储一些文本的内存空间。这些空间中的每一块都有一个标识符,以便后续取用。寄存器和你把一些文本复制到剪贴板中大体一样,不同的是 vim 有多个空间,存储不同的文本。

基础用法

寄存器通过在名字前加双引号来引用。例如,我们可以通过 "r 来访问在 r 寄存器中的内容。

"ry 来把选中的文本添加到 r 寄存器中。y 代表复制(yank)选中的文本,添加到 "r 寄存器。想要粘贴这个寄存器中的内容,使用 "rp,逻辑是一样的:pasting 这个寄存器中的内容。

你也可以在插入模式和命令模式中用 <ctrl>r 加寄存器的名字来访问寄存器,例如 <ctrl>rr。这个命令会把 r 寄存器的内容直接输入到文本缓冲区。

你也可以用 :reg 命令来查看所有的寄存器,或者用 :reg a b c 筛选你想要的寄存器。

:reg a b c
--- Registers ---
"a   register a content
"b   register b content
"c   register c content

匿名寄存器

Vim 有一个匿名的(或者说默认的)寄存器,可以通过 "" 来访问。任何删除(通过 dcsx)或者复制(y)的文本都会被放在这里。当没有显式指出某一个寄存器的时候,p 也会从这里粘贴。在这里,p 就相当于 ""p

再也不会丢掉复制的文本

你肯定遇到过这件事。我们复制一些文本,删除一些别的,然后,当我们想要粘贴的时候,那些复制的文本已经不在了。Vim 用你删除的文本替换了寄存器中的内容,你不得不再一次去复制。

就像我前面提到的,vim 会替换默认寄存器中的内容,但是,当然我们并没有真的丢失复制的文本,vim 要是有那么蠢,也不会活到现在了不是吗?

Vim 内置了从 "0"9数字寄存器"0 里一直都是最近复制的文本,另外 9 个里面是最近删除的,"1 是最新的,"9 是最老的。所以如果你复制了一段文本,你一直都可以用 "0p 访问到。

只读寄存器

有四个只读寄存器:"."%":"#

最后被插入的文本在 ".,这个当你在不同的地方输入相同的文本的时候很好用,不用再一次复制和粘贴。

"% 有当前文件的路径,从 vim 第一次打开的地方开始。我经常用它来把当前文件复制到剪贴板,所以我可以在外部使用(例如在另外一个终端里执行一些脚本)。你可以用 :let @+=@% 来实现这个。let 用来写入寄存器,"+ 代表剪贴板寄存器,所以我们其实就是把文件路径写到了剪贴板里。

": 是最近一次执行的命令的寄存器。如有你用 :w 保存当前文本缓冲区中的内容,那么 w就会在这个寄存器里。用 @: 可以再一次执行这个命令。例如,如果你在某一行里执行了替换的命令。比如 :s/foo/bar,你可以去另外一行,用 @: 再执行一次。

"# 是替换文件的名字,你可以把它想象成最近一次编辑的文件(其实比这个复杂,如果你想了解更多可以去 :h alternate-file)。Vim 在你使用 <ctrl>^ 的时候通过这个来切换文件,你也可以用 :e ctl-r # 来实现一样的事情。我很少用这个,希望你比我更有创造力。

表达式和搜索寄存器

表达式寄存器("=)用来处理表达式的结果。这个用例子来解释更简单一些。在插入模式中,如果你输入 <ctrl>r=,你会在命令行里看到一个等号 =。然后如果你输入 2+2<enter>,会输出 4。这个可以用来执行所有命令,甚至是外部命令。

再举一个例子,如果你输入 <ctrl>r= 然后在命令行里输入system('ls')<enter>ls 命令输出的内容就会被粘贴到你的文本缓冲区。

搜索寄存器,就像你想象的那样,存储的是你最近一次用 /?* 或者 # 搜索的内容。例如,如果你刚刚搜索过 /Nietzsche,现在你想用其他一些东西代替,你用不着重新输入一遍 “Nietzsche”,用 :%s/<ctrl>r//mustache/g 就可以了。

你可能已经熟悉 vim 的宏了。这是一种记录一组可以多次执行的动作的方法(如果需要更多信息,:h recording)。你可能不知道的是,vim 使用寄存器来存储这些操作。因此,如果你使用 qw 来记录宏,那么寄存器 "w 就会用纯文本存下你所做的所有事情。

关于这个的很酷的事情是,由于它只是一个普通的寄存器,因此你可以根据需要对其进行操作。你有多少次忘了宏录制中间的步骤,而不得不重新做一次?好吧,修复这个就像编辑寄存器一样简单。

例如,如果您忘记在 w 宏的末尾添加分号,则只需执行 :let @w='i;' 即可。注意到大写的 W 了吗?这就是我们将值附加到寄存器的方法:使用大写名称。因此,这里我们添加命令 i; 到寄存器,即进入插入模式(i)并添加分号。

如果需要在寄存器的中间进行编辑,只需执行 :let @w='<ctrl>rw,更改所需内容,然后最后关闭引号即可。好了,你再也不用把一个宏打上十遍才录对了。

另一个很酷的事情是,由于它只是寄存器中的纯文本,因此你可以轻松地移动宏,在其他 vim 中应用它,或与其他人共享它。想想看,如果剪贴板中有该寄存器,那么就可以使用 @+ 执行它("+ 是剪贴板寄存器)。尝试一下,只需在任何地方写“ivim is awesome”,把它复制到剪贴板中,然后在 vim 缓冲区中执行 @+ 就可以了。多酷啊。

总结

理解寄存器怎么工作很简单,尽管你也不会每五分钟就用一次,寄存器确实能让你避免一些麻烦,比如丢掉复制的文本,或者重新录一遍宏。我只介绍了我用得最多的东西,但是还有很多其他的。如果你对寄存器还想了解更多,你绝对应该用 :h registers 去看简短而且很容易跟上的的文档。


Cygra
24 声望3 粉丝