使用VIM寄存器
1. 概述
Vim 是一种流行且功能强大的文本编辑器。它支持许多强大的功能,可以帮助我们高效地执行不同类型的文本编辑操作。
在本教程中,我们将仔细研究 Vim 寄存器。
2. Vim 寄存器介绍
2.1. 什么是 Vim 寄存器?
作为一个普通的 Vim 用户,我们可能没有听说过“Vim 寄存器”这个词。然而,很有可能,我们已经多次使用过寄存器,只是我们没有意识到而已。
让我们看一个我们已经用过很多次的寄存器用法的例子:复制和粘贴。
我们知道在 Vim 中我们可以复制/抽取 ( y ) 一些文本并将其粘贴 ( p ) 在其他地方。在我们执行 copy/yank 命令后,复制的文本被存储在一个寄存器中(未命名的寄存器*“”*)。稍后,当我们执行粘贴命令时,未命名寄存器的内容将被读取并粘贴。
Vim 寄存器是内存中的空间,Vim 用来存储一些文本或操作细节。这些空间中的每一个都有一个标识符,以便以后可以访问它。
**当我们想引用一个 Vim 寄存器时,我们使用双引号和寄存器名。*例如, “a表示Vim 寄存器 a和”:表示Vim 寄存器 :*。
事实上,寄存器在 Vim 中无处不在。让我们看一些 Vim 寄存器的常见用法示例:
- 当我们删除文本时——例如,使用x命令——删除的文本存储在未命名的寄存器“”中
- 一旦我们在 Vim 中执行了一个Ex命令(:Command),寄存器*“:*保存命令
- 当我们通过*/somePattern搜索文本时,搜索模式存储在“/*寄存器
2.2. 在Normal模式下获取Vim 寄存器的内容
在 Vim Normal模式下,我们可以使用“ xp . 如果我们不给寄存器,未命名寄存器*“”*的内容将被粘贴。让我们看一个简单的例子来理解如何粘贴寄存器的内容。
让我们打开 Vim 编辑器并输入一行文本:
Vim is a powerful editor.
首先,在Normal模式下,我们将光标移到最后一个单词“ editor ”上,然后按yaw将单词 editor 拉入未命名的寄存器*“”*。
接下来,我们将光标移动到一个空行并按p键而不给出寄存器名称。我们将看到粘贴的文本“ editor ”。
然后,我们执行一条命令,通过键入*:s/powerful/wonderful/[enter]将“* powerful ”替换为“ wonderful ” 。之后,命令存储在*“:”*寄存器中。
因此,我们可以使用*“:p”*来粘贴这个寄存器的内容。
让我们通过一个快速演示看看p命令的用法:
2.3. 在Insert模式下获取Vim 寄存器的内容
如果我们想在Insert模式下获取寄存器的内容,我们可以按Ctrl-r
,然后按寄存器的名称。
比如我们想在插入模式下有*“:”*的内容,我们按“ *Ctrl-r”*和“ : ” 。
同样,让我们看看如何在演示中执行此操作:
2.4. 在命令模式下获取Vim 寄存器的内容
此外,我们可以使用:registers(或简称*:reg*)命令来检查 Vim 寄存器的值。**
如果我们不提供任何寄存器名称,则*:reg*命令将列出所有寄存器及其内容和内容类型(如果已写入寄存器):
:reg
Type Name Content
c "" editor
c "0 editor
l "1 ...
b "2 ...
b "3 ^J ^J ^J
b "4 3. ^J7. ^J9. ^J10.
...
c ": s/powerful/wonderful/
在上面的输出中,Type列表示内容的类型。它可能包含三个不同的值:
- c – 字符文本
- l – linewise 文本
- b – 块状文本
它引用了 Vim 中的三种文本选择类型。当我们粘贴一个寄存器的内容时,会根据内容类型不同控制换行符。
我们还可以将寄存器名称传递给*:reg*命令并告诉它列出某些寄存器:
:reg 0 : "
Type Name Content
c "" editor
c "0 editor
c ": s/powerful/wonderful/
2.5. Vim 寄存器的类型
到目前为止,我们已经看到了未命名寄存器*“”和寄存器“:*保存最后执行的命令的示例。它们是两种不同的寄存器类型。
Vim 有十种不同类型的寄存器:
- 未命名寄存器“”
- 26 个命名寄存器*“a到”z*(或*“A到”Z)*
- 小删除寄存器*“-*
- 10 个编号寄存器*“0到”9*
- 选择和放置寄存器*“*”、“+”和“~”*
- 三个只读寄存器*“:* , “., and “%
- 备用文件寄存器*“#*
- 表达式寄存器*“=*
- 最后搜索模式寄存器*“/*
- 黑洞寄存器*“_*
在本教程中,我们将详细解释所有这些。
此外,我们将通过示例学习如何使用这些寄存器。
3. 未命名寄存器*“”*
当我们使用命令d、D、x、X、s、S、c、C或通过y或Y抽出文本时,Vim 将填充未命名寄存器。
未命名寄存器经常使用。一个常见的场景是快速复制和粘贴操作,就像我们使用普通的系统剪贴板一样。
但是,**剪贴板和未命名寄存器之间有很大的区别。剪贴板不会自动保存删除的文本,但 Vim 未命名寄存器会。**有时,这可能是个问题。
一个例子可以帮助我们快速理解问题。假设我们在 Vim 缓冲区中有一些文本:
correct: (right-text)
wrong: (wrong-text)
wrong: (another wrong text)
wrong: (wrong again)
我们试图做的是将以“ wrong: ”开头的行中的所有“ (….) ”替换为“ (right-text) ”。
它看起来像是一个简单的复制粘贴任务。我们可以通过普通模式*ya(*命令抽取“ (right-text) ” ,然后删除我们想要替换为da(的每个“ (…) ” ,并使用 p 粘贴抽取的文本 。
接下来我们通过一个小demo看看能不能这样实现。在演示中,我们将在提取和删除文本后执行*:reg ”*命令以监视内容:
如演示所示,在我们执行 *da(*之后,未命名寄存器的内容已更改为删除的文本“ (wrong-text) ”。因此,我们丢失了被抽取的值。
我们可能会认为,如果寄存器的内容不自动更新就好了,这样我们就可以始终获取抽取的文本,就像我们使用普通剪贴板一样。
实际上,Vim 寄存器能做的远不止这些。现在是时候看看 26 个命名寄存器了。
4. 命名寄存器
Vim 有 26 个命名寄存器“a/A 到*”z/Z*。只有当我们告诉它这样做时,Vim 才会填充或更新这些寄存器的内容。**也就是说,我们在 Vim 中有 26 个剪贴板!
4.1. 26个剪贴板
现在,我们可以使用命名寄存器轻松解决上一节中的问题。我们可以做的是,当我们抽取文本时,我们按*“aya(”将文本保存在寄存器“a”中。 同样,当我们想在删除后粘贴时,我们告诉 Vim 使用**“a”寄存器粘贴内容“ap*。
让我们看看它是如何完成的:
此外,我们可以在不同的命名寄存器中提取不同的文本,然后从我们想要的寄存器中粘贴:
正如上面的演示所示,它非常方便,就像我们使用多个剪贴板一样。我们不必来回复制不同的文本。
4.2. “a-”Z 与“a-”Z
我们可以使用小写或大写字母来引用命名寄存器。例如,*“a”和“A”*指的是同一个寄存器。因此,我们有 26 个命名寄存器而不是 52 个。
然而,即使一个小写字母及其对应的大写字母指的是同一个寄存器,它们在使用时的行为也不同。当我们使用小写寄存器名称将文本写入命名寄存器时,Vim 将覆盖该寄存器中的现有内容。但是,如果我们使用大写的寄存器名称,Vim 会将新内容附加到给定的寄存器中。
下面通过一个demo看看使用小写寄存器和大写寄存器的区别:
正如我们在演示中看到的那样,如果我们使用大写寄存器抽取文本,例如*“Byiw”,该词将附加到“b”*。
命名寄存器非常方便。然而,我们应该记住,*即使我们使用命名寄存器来保存删除或抽取的文本——例如,“adiw或”ayiw——*未命名寄存器也会被填充。**也就是说,未命名寄存器将具有与命名寄存器相同的内容。
5. 小删除寄存器*“-*
我们已经了解到,无论我们是否指定命名寄存器,未命名寄存器都会自动被删除和抽取的文本填充。
Vim 还有一个类似于无名寄存器的寄存器:小删除寄存器*“-.* 顾名思义,小删寄存器会自动保存“小删”。如果删除的文本少于一行,Vim 将其视为小删除。
与未命名寄存器不同,**“-寄存器不会被抽取的文本填充。
此外,*如果我们为删除命令指定一个命名寄存器,删除的文本也不会保存在“-*寄存器”**中,即使是一个小的删除。
和往常一样,让我们看一个demo,快速了解小删除寄存器:
如演示所示,只有当我们删除少于一行并且没有指定命名寄存器时,*“-”寄存器才会被删除的文本填充。然而,未命名的寄存器“”*总是被填充。
6. 编号寄存器
Vim 还提供了十个编号的寄存器*“0-* ” 9,它从 yank 和 delete 命令中填充这些编号的寄存器。
最近抽取的文本将填充“0”寄存器,除非我们在 yank 命令中指定另一个寄存器,例如:“ayaw。
然而,编号寄存器“1”包含被最近的删除或更改命令删除的文本。
仅当满足两个要求时,*“1”*寄存器才会自动填充:
- 删除命令不得指定另一个寄存器。例如命令*“adaw不去”1*寄存器删除的词
- 更改或删除的文本不少于一行(否则使用“-”寄存器)
到目前为止,我们讨论了*“0和”1*,还有*“2* – ”9。这八个寄存器维护着一个删除历史。每次成功更改或删除,Vim 将寄存器“1”的先前内容移入寄存器“2”,“2”移至“3”,依此类推,而寄存器“9”的先前内容将被丢弃。
和往常一样,让我们通过一个演示看看编号的寄存器是如何填充的:
7. 选择和丢弃寄存器
7.1. 选择寄存器:“\和”+*
到目前为止,我们已经讨论了很多类型的 Vim 寄存器。我们知道我们可以使用 Vim 寄存器复制和粘贴文本。此外,Vim 寄存器提供了使用多个剪贴板的可能性。当我们编辑文本时,它非常方便。
然而,我们目前学习的 Vim 寄存器与常规系统剪贴板之间仍然存在一个很大的区别:使用这些 Vim 寄存器,我们只能在 Vim 中进行复制和粘贴。
有时,我们确实希望 Vim 与系统剪贴板对话。例如,我们可能想从网页中复制文本并粘贴到 Vim 中进行编辑,或者我们可能需要在 Vim 中复制一些文本并粘贴到另一个应用程序中。
这也是文本编辑器的一个非常基本的功能。作为一个强大的编辑器,Vim 当然也可以与系统剪贴板对话。选择寄存器是连接 Vim 和系统剪贴板的桥梁。Vim 有两个选择寄存器:“*和”+。
7.2. 操作系统和选择寄存器
如果我们在 Windows 系统上运行 Vim,“*”和“+”寄存器之间没有区别。两个寄存器都将与系统剪贴板通信。
例如,普通模式命令*“+yaw”(或“*yaw* ”)会将光标下的单词复制到系统剪贴板,而*“+p”(或“*p* ”)会将系统剪贴板中的值粘贴到 Vim。
但是,当我们的 Vim 在带有 X11 的 *nix 系统上运行时,*“+”和“*”*是不同的。
当我们使用*"+寄存器时,Vim 仍然会与系统剪贴板通信,类似于它在 Windows 系统下的工作方式。然而,“*”*寄存器将与 X Window 主选择对话, 它通常通过鼠标选择存储并通过鼠标中键单击读取。
接下来我们看一个demo来了解Vim选择寄存器是如何读写系统剪贴板和X Window选择的:
最后,我们应该记住,Vim 必须使用+clipboard特性编译以支持系统剪贴板访问。此外,为了使用“*”与 X Windows 选择对话, 应该启用+x11-selection功能。**
Vim 在大多数现代发行版的包存储库中启用了上述功能。因此,很有可能,我们的 Vim 也启用了这些功能。
毕竟,我们可以在 Vim 中执行:version*命令来检查当前 Vim 是否启用了所需的功能。*
7.3. 删除寄存器*“~*
拖放寄存器 “~”存储上次拖放操作中拖放的文本。该寄存器仅适用于GVim。
一个简短的演示将直接解释这个寄存器:
要使用放置寄存器,GVim 必须用+dnd*特性编译。*
8. 三个只读寄存器*“:* , “., and “%
实际上,*“:”*对我们来说并不新鲜。它包含最近执行的命令。我们已经看到一个演示将最后执行的命令粘贴到之前的演示中。
**“%”寄存器包含当前文件的名称,而“.寄存器保存最后插入的文本。
下面通过一个demo来展示这三个寄存器的用法:
**“: , *”.,和“%”*是只读的 Vim 寄存器。**它们的内容由 Vim 自动设置。我们只能读取它们的值。
9. 备用文件寄存器*“#*
在讲alternate file register之前,首先我们需要了解什么是Vim中的alternate file。
我们可以在 Vim 中打开多个文件。每个文件都在 Vim 缓冲区中打开。:ls命令将列出当前窗口中的所有缓冲区。
假设我们在 Vim 中打开两个文件file1和file2并开始编辑file1。稍后,我们要对file2进行一些更改,因此我们切换到file2缓冲区。
此时,当前文件为 file2,而同一 Vim 窗口中最后编辑的文件为file1。
**我们称同一个 Vim 窗口中最后编辑的文件或缓冲区为替代文件或缓冲区。**因此,在此示例中,file1是备用文件。
如果我们从file2切换回file1,则file1再次成为当前文件,而file2成为备用文件。
*“#*寄存器存储备用文件。
一如既往,让我们通过一个演示来了解 Vim 备用文件和*“#*注册”。
在演示中,我们将在单个 Vim 窗口中打开两个文件并在它们之间切换,然后列出*“%”和“#”*寄存器的内容:
在演示中,我们使用命令*:buf [buferNo]在缓冲区之间切换。**如果我们想在普通模式下快速切换当前文件和备用文件,可以按Ctrl-^*。**
10. 表达式寄存器*“=*
我们已经看到了不同类型的 Vim 寄存器。通常,寄存器存储一些文本。然而,我们要看的下一个寄存器是一个特殊的寄存器。它是表达式寄存器*“=*。
**“= 存储一个 Vim 表达式。Vim 可以计算表达式并将结果返回给我们。**当我们想在编辑时评估某些表达式时,它非常方便。
*“=”*的常见用法是:
- 在Normal模式下,我们可以按*“=AnExpression”设置寄存器,使用命令:put =*打印结果
- 在插入模式下,我们可以按Ctrl-R=AnExpression,回车后,AnExpression的结果将被插入到光标位置
让我们看看这些用法:
11. 上次搜索模式寄存器*“/*
在 Vim 中,我们可以通过多种方式搜索文本。例如,我们可以使用*/pattern命令进行向前搜索,使用?pattern*进行向后搜索,或者按 * 和 # 向前和向后搜索当前单词。
Vim 将最近的搜索模式存储在搜索模式寄存器 “/ . 当我们按n或N导航到下一个或上一个事件时,将使用“/”的内容:
***“/是一个非只读寄存器。但是,我们不能提取或删除文本并将其保存到“/寄存器。*当我们应用搜索时,它会自动设置。如果我们想手动更改它的内容,如演示中所示,我们可以使用命令:let @/=‘newPattern’。
12. 黑洞寄存器*“_*
到目前为止,我们已经讨论了大多数类型的 Vim 寄存器。我们了解到,当我们更改、删除或抽取文本时,某些寄存器会自动更新——例如,未命名的寄存器*“”。然而,有时,我们希望在不更改任何寄存器的情况下更改或删除文本,包括""*。
黑洞寄存器*“_”*是实现这一目标的关键。顾名思义,当向黑洞寄存器写入文本时,什么也没有发生。如果我们读取该寄存器的内容,则不会返回任何内容。
因此,我们可以在删除或更改命令中指定这个寄存器,让“黑洞”吞噬更改或删除的文本。例如,要用黑洞寄存器删除当前单词,我们可以使用*“_daw*。
让我们看一个演示来了解使用和不使用黑洞寄存器删除之间的区别:
正如演示所示, “**当我们想要在不干扰普通寄存器的情况下更改或删除文本时,*_***是一个不错的选择。