注:本文为 “vim 寄存器” 相关文章合辑。
英文引文,机翻未校。
中文引文,略作重排。
未整理去重,如有内容异常,请看原文。
Registers
寄存器
Learning Vim registers is like learning algebra for the first time. You didn’t think you need it until you needed it.
学习 Vim 寄存器就像第一次学习代数一样。直到需要时,你才会意识到它的必要性。
You’ve probably used Vim registers when you yanked or deleted a text then pasted it with p
or P
. However, did you know that Vim has 10 different types of registers? Used correctly, Vim registers can save you from repetitive typing.
你可能在使用 p
或 P
粘贴文本时已经用过 Vim 寄存器了。但你可能不知道,Vim 有 10 种不同类型的寄存器。如果使用得当,Vim 寄存器可以帮你避免重复输入。
In this chapter, I will go over all Vim register types and how to use them efficiently.
在本章中,我将介绍所有类型的 Vim 寄存器及其高效使用方法。
The Ten Register Types
十种寄存器类型
Here are the 10 Vim register types:
以下是 10 种 Vim 寄存器类型:
序号 | 英文描述 | 中文描述 |
---|---|---|
1 | The unnamed register ("" ). |
无名寄存器 ("" )。 |
2 | The numbered registers ("0-9 ). |
编号寄存器 ("0-9 )。 |
3 | The small delete register ("- ). |
小删除寄存器 ("- )。 |
4 | The named registers ("a-z ). |
命名寄存器 ("a-z )。 |
5 | The read-only registers (": , ". , and "% ). |
只读寄存器 (": , ". , "% )。 |
6 | The alternate file register ("# ). |
备用文件寄存器 ("# )。 |
7 | The expression register ("= ). |
表达式寄存器 ("= ). |
8 | The selection registers ("* and "+ ). |
选择寄存器 ("* 和 "+ )。 |
9 | The black hole register ("_ ). |
黑洞寄存器 ("_ )。 |
10 | The last search pattern register ("/ ). |
最后搜索模式寄存器 ("/ )。 |
Register Operators
寄存器操作符
To use registers, you need to first store them with operators. Here are some operators that store values to registers:
要使用寄存器,你需要先用操作符将值存储到寄存器中。以下是一些可以将值存储到寄存器的操作符:
y Yank (copy) // 拉取(复制)
c Delete text and start insert mode // 删除文本并进入插入模式
d Delete text // 删除文本
There are more operators (like s
or x
), but the above are the useful ones. The rule of thumb is, if an operator can remove a text, it probably stores the text to registers.
还有更多操作符(如 s
或 x
),但上面这些是比较有用的。一般来说,如果一个操作符可以删除文本,它很可能会将文本存储到寄存器中。
To paste a text from registers, you can use:
要从寄存器中粘贴文本,可以使用:
p Paste the text after the cursor // 在光标后粘贴文本
P Paste the text before the cursor // 在光标前粘贴文本
Both p
and P
accept a count and a register symbol as arguments. For example, to paste ten times, do 10p
. To paste the text from register a, do "ap
. To paste the text from register a ten times, do 10"ap
. By the way, the p
actually technically stands for “put”, not “paste”, but I figure paste is a more conventional word.p
和 P
都接受计数和寄存器符号作为参数。例如,要粘贴十次,可以执行 10p
。要粘贴寄存器 a 中的文本,可以执行 "ap
。要将寄存器 a 中的文本粘贴十次,可以执行 10"ap
。顺便说一下,p
实际上技术上代表的是 “put”,而不是 “paste”,但我认为 “paste” 是一个更常用的词。
The general syntax to get the content from a specific register is "a
, where a
is the register symbol.
从特定寄存器中获取内容的通用语法是 "a
,其中 a
是寄存器符号。
Calling Registers From Insert Mode
从插入模式调用寄存器
Everything you learn in this chapter can also be executed in insert mode. To get the text from register a, normally you do "ap
. But if you are in insert mode, run Ctrl-R a
. The syntax to call registers from insert mode is:
你在本章学到的所有内容都可以在插入模式中执行。通常,要获取寄存器 a 中的文本,可以执行 "ap
。但如果处于插入模式,可以运行 Ctrl-R a
。从插入模式调用寄存器的语法是:
Ctrl-R a
Where a
is the register symbol. Now that you know how to store and retrieve registers, let’s dive in!
其中 a
是寄存器符号。现在你已经知道了如何存储和检索寄存器,让我们继续深入!
The Unnamed Register
无名寄存器
To get the text from the unnamed register, do ""p
. It stores the last text you yanked, changed, or deleted. If you do another yank, change, or delete, Vim will automatically replace the old text. The unnamed register is like a computer’s standard copy / paste operation.
要从无名寄存器中获取文本,可以执行 ""p
。它存储了你最后一次拉取、更改或删除的文本。如果你再次执行拉取、更改或删除操作,Vim 会自动替换旧文本。无名寄存器就像计算机的标准复制/粘贴操作一样。
By default, p
(or P
) is connected to the unnamed register (from now on I will refer to the unnamed register with p
instead of ""p
).
默认情况下,p
(或 P
)连接到无名寄存器(从现在开始,我将用 p
代替 ""p
来指代无名寄存器)。
The Numbered Registers
编号寄存器
Numbered registers automatically fill themselves up in ascending order. There are 2 different numbered registers: the yanked register (0
) and the numbered registers (1-9
). Let’s discuss the yanked register first.
编号寄存器会自动按升序填充。编号寄存器有两种:拉取寄存器 (0
) 和编号寄存器 (1-9
)。我们先来讨论拉取寄存器。
The Yanked Register
拉取寄存器
If you yank an entire line of text (yy
), Vim actually saves that text in two registers:
如果你拉取了一整行文本(yy
),Vim 实际上会将该文本保存到两个寄存器中:
-
The unnamed register (
p
).
无名寄存器 (p
) -
The yanked register (
"0p
).
拉取寄存器 ("0p
)
When you yank a different text, Vim will update both the yanked register and the unnamed register. Any other operations (like delete) will not be stored in register 0. This can be used to your advantage, because unless you do another yank, the yanked text will always be there, no matter how many changes and deletions you do.
当你拉取不同的文本时,Vim 会同时更新拉取寄存器和无名寄存器。其他操作(如删除)不会存储到寄存器 0 中。你可以利用这一点,因为除非你再次执行拉取操作,否则拉取的文本将始终存在,无论你进行了多少次更改和删除操作。
For example, if you:
例如,如果你:
-
Yank a line (
yy
)
拉取一行(yy
) -
Delete a line (
dd
)
删除一行(dd
) -
Delete another line (
dd
)
再删除一行(dd
)
The yanked register will have the text from step one.
拉取寄存器将包含第一步中的文本。
If you:
如果你:
-
Yank a line (
yy
)
拉取一行(yy
) -
Delete a line (
dd
)
删除一行(dd
) -
Yank another line (
yy
)
再拉取一行(yy
)
The yanked register will have the text from step three.
拉取寄存器将包含第三步中的文本。
One last tip, while in insert mode, you can quickly paste the text you just yanked using Ctrl-R 0
.
还有一个小提示,在插入模式下,你可以使用 Ctrl-R 0
快速粘贴刚刚拉取的文本。
The Non-zero Numbered Registers
非零编号寄存器
When you change or delete a text that is at least one line long, that text will be stored in the numbered registers 1-9 sorted by the most recent.
当你更改或删除至少有一行长的文本时,该文本将按最近使用顺序存储在编号寄存器 1-9 中。
For example, if you have these lines:
例如,如果你有以下几行:
line three
line two
line one
With your cursor on “line three”, delete them one by one with dd
. Once all lines are deleted, register 1 should contain “line one” (most recent), register two “line two” (second most recent), and register three “line three” (oldest). To get the content from register one, do "1p
.
将光标放在 “line three” 上,然后逐行使用 dd
删除它们。删除所有行后,寄存器 1 应该包含 “line one”(最近的),寄存器 2 包含 “line two”(第二近的),寄存器 3 包含 “line three”(最老的)。要从寄存器 1 中获取内容,可以执行 "1p
。
As a side note, these numbered registers are automatically incremented when using the dot command. If your numbered register one ("1
) contains “line one”, register two ("2
) “line two”, and register three ("3
) “line three”, you can paste them sequentially with this trick:
顺便说一下,使用点命令时,这些编号寄存器会自动递增。如果编号寄存器 1("1
)包含 “line one”,寄存器 2("2
)包含 “line two”,寄存器 3("3
)包含 “line three”,你可以使用以下技巧依次粘贴它们:
-
Do
"1P
to paste the content from the numbered register one ("1
).
执行"1P
粘贴编号寄存器 1("1
)中的内容 -
Do
.
to paste the content from the numbered register two ("2
).
执行.
粘贴编号寄存器 2("2
)中的内容 -
Do
.
to paste the content from the numbered register three ("3
).
执行.
粘贴编号寄存器 3("3
)中的内容
This trick works with any numbered register. If you started with "5P
, .
would do "6P
, .
again would do "7P
, and so on.
这个技巧适用于任何编号寄存器。如果你从 "5P
开始,.
将执行 "6P
,再次执行 .
将执行 "7P
,依此类推。
Small deletions like a word deletion (dw
) or word change (cw
) do not get stored in the numbered registers. They are stored in the small delete register ("-
), which I will discuss next.
小的删除操作,如删除单词(dw
)或更改单词(cw
),不会存储在编号寄存器中。它们会存储在小删除寄存器("-
)中,接下来我会讨论它。
The Small Delete Register
小删除寄存器
Changes or deletions less than one line are not stored in the numbered registers 0-9, but in the small delete register ("-
).
小于一行的更改或删除不会存储在编号寄存器 0-9 中,而是存储在小删除寄存器("-
)中。
For example:
例如:
-
Delete a word (
diw
)
删除一个单词(diw
) -
Delete a line (
dd
)
删除一行(dd
) -
Delete a line (
dd
)
再删除一行(dd
)
"-p
gives you the deleted word from step one."-p
会给出第一步中删除的单词
Another example:
另一个例子:
-
I delete a word (
diw
)
我删除了一个单词(diw
) -
I delete a line (
dd
)
我删除了一行(dd
) -
I delete a word (
diw
)
我又删除了一个单词(diw
)
"-p
gives you the deleted word from step three. "1p
gives you the deleted line from step two. Unfortunately, there is no way to retrieve the deleted word from step one because the small delete register only stores one item. However, if you want to preserve the text from step one, you can do it with the named registers."-p
会给出第三步中删除的单词。"1p
会给出第二步中删除的行。不幸的是,由于小删除寄存器只存储一个项目,因此无法检索第一步中删除的单词。然而,如果你想要保留第一步中的文本,可以使用命名寄存器。
The Named Register
命名寄存器
The named registers are Vim’s most versatile register. It can store yanked, changed, and deleted texts into registers a-z. Unlike the previous 3 register types you’ve seen which automatically stores texts into registers, you have to explicitly tell Vim to use the named register, giving you full control.
命名寄存器是 Vim 最灵活的寄存器。它可以将拉取、更改和删除的文本存储到寄存器 a-z 中。与前面提到的会自动将文本存储到寄存器中的三种寄存器类型不同,你需要明确告诉 Vim 使用命名寄存器,这让你拥有完全的控制权。
To yank a word into register a, you can do it with "ayiw
.
要将一个单词拉取到寄存器 a 中,可以执行 "ayiw
。
-
"a
tells Vim that the next action (delete / change / yank) will be stored in register a."a
告诉 Vim,下一个操作(删除/更改/拉取)将被存储在寄存器 a 中 -
yiw
yanks the word.yiw
拉取单词
To get the text from register a, run "ap
. You can use all twenty-six alphabetical characters to store twenty-six different texts with named registers.
要从寄存器 a 中获取文本,可以执行 "ap
。你可以使用所有 26 个字母字符来存储 26 种不同的文本。
Sometimes you may want to add to your existing named register. In this case, you can append your text instead of starting all over. To do that, you can use the uppercase version of that register. For example, suppose you have the word "Hello " already stored in register a. If you want to add “world” into register a, you can find the text “world” and yank it using A register ("Ayiw
).
有时你可能想在现有的命名寄存器中添加内容。在这种情况下,你可以追加文本,而不是重新开始。为此,你可以使用该寄存器的大写版本。例如,假设你已经在寄存器 a 中存储了单词 "Hello "。如果你想将 “world” 添加到寄存器 a 中,你可以找到文本 “world” 并使用寄存器 A("Ayiw
)将其拉取。
The Read-Only Registers
只读寄存器
Vim has three read-only registers: .
, :
, and %
. They are pretty simple to use:
Vim 有三个只读寄存器:.
、:
和 %
。它们的使用方法非常简单:
. Stores the last inserted text // 存储最后一次插入的文本
: Stores the last executed command-line // 存储最后执行的命令行
% Stores the name of current file // 存储当前文件的名称
If the last text you wrote was “Hello Vim”, running ".p
will print out the text “Hello Vim”. If you want to get the name of current file, run "%p
. If you run :s/foo/bar/g
command, running ":p
will print out the literal text “s/foo/bar/g”.
如果你最后一次输入的文本是 “Hello Vim”,执行 ".p
将打印出文本 “Hello Vim”。如果你想获取当前文件的名称,可以执行 "%p
。如果你执行了 :s/foo/bar/g
命令,执行 ":p
将打印出字面文本 “s/foo/bar/g”。
The Alternate File Register
备用文件寄存器
In Vim, #
usually represents the alternate file. An alternative file is the last file you opened. To insert the name of the alternate file, you can use "#p
.
在 Vim 中,#
通常表示备用文件。备用文件是你最后打开的文件。要插入备用文件的名称,可以使用 "#p
。
The Expression Register
表达式寄存器
Vim has an expression register, "=
, to evaluate expressions.
Vim 有一个表达式寄存器 "=
,用于计算表达式。
To evaluate mathematical expressions 1 + 1
, run:
要计算数学表达式 1 + 1
,可以执行:
"=1+1<Enter>p
Here, you are telling Vim that you are using the expression register with "=
. Your expression is (1 + 1
). You need to type p
to get the result. As mentioned earlier, you can also access the register from insert mode. To evaluate mathematical expression from insert mode, you can do:
在这里,你告诉 Vim 你正在使用表达式寄存器 "="
。你的表达式是(1 + 1
)。你需要输入 p
来获取结果。正如前面提到的,你也可以从插入模式访问寄存器。要从插入模式计算数学表达式,可以执行:
Ctrl-R =1+1
You can also get the values from any register via the expression register when appended with @
. If you wish to get the text from register a:
你还可以通过表达式寄存器(在后面加上 @
)获取任何寄存器中的值。如果你想获取寄存器 a 中的文本:
"=@a
Then press <Enter>
, then p
. Similarly, to get values from register a while in insert mode:
然后按 <Enter>
,再按 p
。同样,在插入模式下,要获取寄存器 a 中的值:
Ctrl-r =@a
Expression is a vast topic in Vim, so I will only cover the basics here. I will address expressions in more details in later Vimscript chapters.
表达式是 Vim 中的一个广泛主题,所以我在这里只介绍基础知识。我将在后续的 Vim 脚本章节中更详细地介绍表达式。
The Selection Registers
选择寄存器
Don’t you sometimes wish that you can copy a text from external programs and paste it locally in Vim, and vice versa? With Vim’s selection registers, you can. Vim has two selection registers: quotestar
("*
) and quoteplus
("+
). You can use them to access copied text from external programs.
你是否有时希望可以从外部程序复制文本并在 Vim 中本地粘贴,反之亦然?通过 Vim 的选择寄存器,你可以做到。Vim 有两个选择寄存器:quotestar
("*
)和 quoteplus
("+
)。你可以使用它们访问外部程序中复制的文本。
If you are on an external program (like Chrome browser) and you copy a block of text with Ctrl-C
(or Cmd-C
, depending on your OS), normally you wouldn’t be able to use p
to paste the text in Vim. However, both Vim’s "+
and "*
are connected to your clipboard, so you can actually paste the text with "+p
or "*p
. Conversely, if you yank a word from Vim with "+yiw
or "*yiw
, you can paste that text in the external program with Ctrl-V
(or Cmd-V
). Note that this only works if your Vim program comes with the +clipboard
option (to check it, run :version
).
如果你在外部程序(如 Chrome 浏览器)中,使用 Ctrl-C
(或根据你的操作系统可能是 Cmd-C
)复制了一块文本,通常你无法使用 p
在 Vim 中粘贴该文本。然而,Vim 的 "+
和 "*
都连接到你的剪贴板,因此你可以使用 "+p
或 "*p
粘贴文本。反之,如果你在 Vim 中使用 "+yiw
或 "*yiw
拉取一个单词,你可以使用 Ctrl-V
(或 Cmd-V
)在外部程序中粘贴该文本。请注意,这只有在你的 Vim 程序带有 +clipboard
选项时才有效(要检查它,请运行 :version
)。
You may wonder if "*
and "+
do the same thing, why does Vim have two different registers? Some machines use X11 window system. This system has 3 types of selections: primary, secondary, and clipboard. If your machine uses X11, Vim uses X11’s primary selection with the quotestar
("*
) register and X11’s clipboard selection with the quoteplus
("+
) register. This is only applicable if you have +xterm_clipboard
option available in your Vim build. If your Vim doesn’t have xterm_clipboard
, it’s not a big deal. It just means that both quotestar
and quoteplus
are interchangeable (mine doesn’t either).
你可能会好奇,如果 "*
和 "+
做的是同样的事情,为什么 Vim 有两个不同的寄存器呢?有些机器使用 X11 窗口系统。这个系统有 3 种选择类型:主选择、次选择和剪贴板。如果你的机器使用 X11,Vim 会使用 X11 的 主选择 与 quotestar
("*
)寄存器,以及 X11 的 剪贴板选择 与 quoteplus
("+
)寄存器。这只有在你的 Vim 构建中包含 +xterm_clipboard
选项时才适用。如果你的 Vim 没有 xterm_clipboard
,那也没关系。这仅仅意味着 quotestar
和 quoteplus
是可以互换的(我的 Vim 也没有)。
I find doing =*p
or =+p
to be cumbersome. To make Vim to paste copied text from the external program with just p
, you can add this in your vimrc:
我觉得执行 =*p
或 =+p
很麻烦。为了让 Vim 只用 p
就能粘贴外部程序中复制的文本,你可以在你的 vimrc
中添加以下内容:
set clipboard=unnamed
Now when I copy a text from an external program, I can paste it with the unnamed register, p
. I can also copy a text from Vim and paste it to an external program. If you have +xterm_clipboard
on, you may want to use both unnamed
and unnamedplus
clipboard options.
现在,当我从外部程序复制文本时,我可以使用无名寄存器 p
粘贴它。我也可以从 Vim 复制文本并粘贴到外部程序中。如果你启用了 +xterm_clipboard
,你可能想同时使用 unnamed
和 unnamedplus
剪贴板选项。
The Black Hole Register
黑洞寄存器
Each time you delete or change a text, that text is stored in Vim register automatically. There will be times when you don’t want to save anything into the register. How can you do that?
每次你删除或更改文本时,该文本都会自动存储在 Vim 寄存器中。有时候,你可能不想将任何内容保存到寄存器中。那该怎么办呢?
You can use the black hole register ("_
). To delete a line and not have Vim store the deleted line into any register, use "_dd
.
你可以使用黑洞寄存器("_
)。要删除一行且不让 Vim 将删除的行存储到任何寄存器中,可以使用 "_dd
。
The black hole register is like the /dev/null
of registers.
黑洞寄存器就像寄存器中的 /dev/null
。
The Last Search Pattern Register
最后搜索模式寄存器
To paste your last search (/
or ?
), you can use the last search pattern register ("/
). To paste the last search term, use "/p
.
要粘贴你的最后一次搜索(/
或 ?
),你可以使用最后搜索模式寄存器("/
)。要粘贴最后一次搜索的术语,可以使用 "/p
。
Viewing The Registers
查看寄存器
To view all your registers, use the :register
command. To view only registers "a, "1, and "-, use :register a 1 -
.
要查看所有寄存器,可以使用 :register
命令。要仅查看寄存器 “a”、“1” 和 “-”,可以使用 :register a 1 -
。
There is a plugin called vim-peekaboo that lets you to peek into the contents of the registers when you hit "
or @
in normal mode and Ctrl-R
in insert mode. I find this plugin very useful because most times, I can’t remember the content in my registers. Give it a try!
有一个名为 vim-peekaboo 的插件,它可以在你在普通模式下按下 "
或 @
,以及在插入模式下按下 Ctrl-R
时,让你查看寄存器的内容。我觉得这个插件非常有用,因为大多数时候,我记不住寄存器中的内容。你可以试试!
Executing A Register
执行寄存器
The named registers are not just for storing texts. They can also execute macros with @
. I will go over macros in the next chapter.
命名寄存器不仅用于存储文本,还可以通过 @
执行宏。我将在下一章介绍宏。
Keep in mind since macros are stored inside Vim registers, you can accidentally overwrite the stored text with macros. If you store the text “Hello Vim” in register a and you later record a macro in the same register (qa{macro-sequence}q
), that macro will overwrite your “Hello Vim” text stored earlier.
请注意,由于宏存储在 Vim 寄存器中,你可能会不小心用宏覆盖存储的文本。如果你在寄存器 a 中存储了文本 “Hello Vim”,然后在同一个寄存器中录制了一个宏(qa{macro-sequence}q
),那么这个宏将覆盖之前存储的 “Hello Vim” 文本。
Clearing A Register
清空寄存器
Technically, there is no need to clear any register because the next text that you store under the same register name will overwrite it. However, you can quickly clear any named register by recording an empty macro. For example, if you run qaq
, Vim will record an empty macro in the register a.
从技术上讲,没有清除任何寄存器的必要,因为存储在相同寄存器名称下的下一个文本将覆盖它。然而,你可以通过录制一个空宏来快速清除任何命名寄存器。例如,如果你运行 qaq
,Vim 将在寄存器 a 中记录一个空宏。
Another alternative is to run the command :call setreg('a', 'hello register a')
where a is the register a and “hello register a” is the text that you want to store.
另一个选择是运行命令 :call setreg('a', 'hello register a')
,其中 a 是寄存器 a,而 “hello register a” 是你想要存储的文本。
One more way to clear register is to set the content of "a register to an empty string with the expression :let @a = ''
.
清除寄存器的另一种方法是使用表达式 :let @a = ''
将寄存器 “a” 的内容设置为空字符串。
Putting The Content Of A Register
粘贴寄存器的内容
You can use the :put
command to paste the content of any one register. For example, if you run :put a
, Vim will print the content of register a below the current line. This behaves much like "ap
, with the difference that the normal mode command p
prints the register content after the cursor and the command :put
prints the register content at newline.
你可以使用 :put
命令粘贴任何一个寄存器的内容。例如,如果你运行 :put a
,Vim 将在当前行下方打印寄存器 a 的内容。这与 "ap
的行为非常相似,不同之处在于普通模式命令 p
在光标后打印寄存器内容,而命令 :put
在新行打印寄存器内容。
Since :put
is a command-line command, you can pass it an address. :10put a
will paste text from register a to below line 10.
由于 :put
是一个命令行命令,你可以给它传递一个地址。:10put a
将把寄存器 a 中的文本粘贴到第 10 行下方。
One cool trick to pass :put
with the black hole register ("_
). Since the black hole register does not store any text, :put _
will insert a blank line instead. You can combine this with the global command to insert multiple blank lines. For example, to insert blank lines below all lines that contain the text “end”, run :g/end/put _
. You will learn about the global command later.
一个很酷的技巧是将 :put
与黑洞寄存器("_
)一起使用。由于黑洞寄存器不存储任何文本,:put _
将插入一个空行。你可以将它与全局命令结合起来插入多个空行。例如,要将空行插入到包含文本 “end” 的所有行下方,可以运行 :g/end/put _
。你稍后会学到全局命令。
Learning Registers The Smart Way
聪明地学习寄存器
You made it to the end. Congratulations! If you are feeling overwhelmed by the sheer information, you are not alone. When I first started learning about Vim registers, there were way too much information to take at once.
你已经到了最后。恭喜!如果你觉得信息量太大,你并不孤单。当我第一次开始学习 Vim 寄存器时,信息量实在太大,无法一次吸收。
I don’t think you should memorize all the registers immediately. To become productive, you can start by using only these 3 registers:
我认为你不需要立即记住所有的寄存器。为了提高工作效率,你可以先从使用以下 3 个寄存器开始:
-
The unnamed register (
""
).
无名寄存器 (""
) -
The named registers (
"a-z
).
命名寄存器 ("a-z
) -
The numbered registers (
"0-9
).
编号寄存器 ("0-9
)
Since the unnamed register defaults to p
and P
, you only have to learn two registers: the named registers and the numbered registers. Gradually learn more registers when you need them. Take your time.
由于无名寄存器默认对应 p
和 P
,你只需要学习两个寄存器:命名寄存器和编号寄存器。当你需要时,逐渐学习更多的寄存器。不要着急。
The average human has a limited short-term memory capacity, about 5 - 7 items at once. That is why in my everyday editing, I only use about 5 - 7 named registers. There is no way I can remember all twenty-six in my head. I normally start with register a, then b, ascending the alphabetical order. Try it and experiment around to see what technique works best for you.
普通人短期记忆的容量有限,大约一次能记住 5 - 7 个项目。这就是为什么在我的日常编辑中,我只使用大约 5 - 7 个命名寄存器。我没办法把全部 26 个都记在脑子里。我通常从寄存器 a 开始,然后是 b,按字母顺序依次往上。你可以试试看,多试验一下,看看哪种方法最适合你。
Vim registers are powerful. Used strategically, it can save you from typing countless repeating texts.
Vim 寄存器非常强大。如果使用得当,它可以帮你避免输入无数重复的文本。
Advanced Vim registers
Posted on 2012-10-24
Registers in Vim are best thought of as scratch spaces for text, some of which are automatically filled by the editor in response to certain actions. Learning how to use registers fluently has a lot of subtle benefits, although it takes some getting used to because the syntax for using them is a little awkward.
Vim 中的寄存器最好被看作是文本的暂存空间,其中一些会根据某些操作由编辑器自动填充。学会熟练使用寄存器会带来很多微妙的好处,尽管一开始可能会觉得有些不习惯,因为使用它们的语法有点笨拙。
If you’re reasonably fluent with Vim by now, it’s likely you’re already familiar with the basic usage of the 26 named registers, corresponding to the letters of the alphabet. These are commonly used for recording macros; for example, to record a series of keystrokes into register a
, you might start recording with qa
, and finish with q
; your keystrokes could then be executed with @a
.
如果你对 Vim 已经相当熟悉,那么你可能已经了解了 26 个 命名寄存器 的基本用法,它们分别对应字母表中的字母。这些寄存器通常用于录制宏;例如,要将一系列按键记录到寄存器 a
中,你可以用 qa
开始录制,用 q
结束录制;然后可以用 @a
执行这些按键。
Similarly, we can store text from the buffer itself rather than commands in these registers, by prepending "a
to any command which uses a register, such as the c
, d
, and y
commands:
同样地,我们可以通过在使用寄存器的命令(如 c
、d
和 y
命令)前加上 "a
,将缓冲区中的文本而不是命令存储到这些寄存器中:
-
"ayy
— Read current line into registera
."ayy
— 将当前行读入寄存器a
-
"bP
— Paste contents of registerb
above current line."bP
— 将寄存器b
的内容粘贴到当前行上方 -
"cc3w
— Change three words, putting the previous three words into registerc
."cc3w
— 更改三个单词,将之前的三个单词放入寄存器c
Like many things in Vim, there’s a great deal more functionality to registers for those willing to explore.
就像 Vim 中的许多其他功能一样,寄存器还有许多值得探索的功能。
Note that here I’ll be specifically ignoring the *
, +
, and ~
registers; that’s another post about the generally unpleasant business of making Vim play nice with system clipboards. Instead, I’ll be focussing on stuff that only applies within a Vim session. All of this is documented in :help registers.
请注意,这里我将特别忽略 *
、+
和 ~
寄存器;那是一个关于如何让 Vim 与系统剪贴板友好相处的不愉快话题,会在另一篇文章中讨论。相反,我将专注于只在 Vim 会话中适用的内容。所有这些内容都在 :help registers
中有详细说明。
Capital registers
大写寄存器
Yanking and deleting text into registers normally replaces the previous contents of that register. In some cases it would be preferable to append to a register, for example while cherry-picking different lines from the file to be pasted elsewhere. This can be done by simply capitalizing the name of the register as it’s referenced:
通常情况下,将文本拉取或删除到寄存器中会 替换 该寄存器的先前内容。在某些情况下,将文本 追加 到寄存器会更有用,例如从文件中挑选不同的行以粘贴到其他地方。只需将寄存器名称大写即可实现这一点:
-
"ayy
— Replace the contents of registera
with the current line."ayy
— 用当前行 替换 寄存器a
的内容 -
"Ayy
— Append the current line to registera
."Ayy
— 将当前行 追加 到寄存器a
This works for any context in which an alphabetical register can be used. Similarly, to append to a macro already recorded in register a
, we can start recording with qA
to add more keystrokes to it.
这适用于任何可以使用字母寄存器的上下文。同样地,要向已经记录在寄存器 a
中的宏追加内容,可以用 qA
开始录制,以添加更多的按键。
Viewing register contents
查看寄存器内容
A good way to start getting a feel for how all the other registers work is to view a list of them with their contents during an editing session with :registers
. This will show the contents of any register used in the editing session. It might look something like this, a little inscrutable at first:
查看寄存器内容的一个好方法是在编辑会话中使用 :registers
查看它们的列表及其内容。这将显示在编辑会话中使用过的任何寄存器的内容。一开始可能会看起来有点难以理解,就像这样:
:registers
--- Registers ---
"" Note that much of it includes // 注意,其中大部分包括
"0 execut
"1 ^J^J
"2 16 Oct (2 days ago)^J^Jto Jeff, Alan ^JHi Jeff (cc Alan);^J^JPlease
"3 <?php^Jheader("Content-Type: text/plain; charset=utf-8");^J?>^J.^J
"4 ^J
"5 Business-+InternationalTrade-TelegraphicTransfers-ReceivingInternati
"6 ../^J
"7 diff = auto^J status = auto^J branch = auto^J interacti
"8 ^J[color]^J ui = auto^J diff = auto^J status = auto^J br
"9 ui = true^J
"a escrow
"b 03wdei^R=2012-^R"^M^[0j
"c a
"e dui{<80>kb^[^[
"g ^[gqqJgqqjkV>JgqqJV>^[Gkkkjohttp://tldp.org/LDP/abs/html/ ^[I[4]: ^[k
"h ^[^Wh:w^Mgg:w^M^L:w^Mjk/src^Mllhh
"j jjjkkkA Goo<80>kb<80>kb<80>kbThis one is good pio<80>kbped through a
"- Note that much of it includes // 注意,其中大部分包括
". OIt<80>kb<80>kb<80>kbIt might looks <80>kb<80>kb something like thi
": register
"% advanced-vim-registers.markdown
"/ Frij
The first column contains the name of the register, and the second its contents. The contents of any of these registers can be pasted into the buffer with "ap
, where a
is the name of any of them. Note that there are considerably more registers than just the named alphabetical ones mentioned above.
第一列是寄存器的名称,第二列是其内容。这些寄存器中的任何内容都可以用 "ap
粘贴到缓冲区中,其中 a
是它们中的任何一个的名称。请注意,寄存器的数量远远不止上面提到的字母命名的那些。
Unnamed register
无名寄存器
The unnamed register is special in that it’s always written to in operations, no matter whether you specified another register or not. Thus if you delete a line with dd
, the line’s contents are put into the unnamed register; if you delete it with "add
, the line’s contents are put into both the unnamed register and into register a
.
无名寄存器 的特殊之处在于,无论你是否指定了另一个寄存器,它都会在操作中被写入。因此,如果你用 dd
删除一行,该行的内容将被放入无名寄存器;如果你用 "add
删除它,该行的内容将被放入无名寄存器 和 寄存器 a
。
If you need to explicitly reference the contents of this register, you can use "
, meaning you’d reference it by tapping "
twice: ""
. One handy application for this is that you can yank text into the unnamed register and execute it directly as a macro with @"
.
如果你需要明确引用这个寄存器的内容,你可以使用 "
,也就是说,你可以通过连续按两次 "
来引用它:""
。一个方便的应用是,你可以将文本拉取到无名寄存器中,并直接用 @"
将其作为宏执行。
Man, and you thought Perl looked like line noise.
伙计,你以为 Perl 看起来像行噪声呢。(调侃 Perl 语言的语法复杂性,让人觉得它看起来像是一堆杂乱无章的字符。)
Black hole register
黑洞寄存器
Another simple register worth mentioning is the black hole register, referenced with "_
. This register is special in that everything written to it is discarded. It’s the /dev/null
of the Vim world; you can put your all into it, and it’ll never give anything back. A pretty toxic relationship.
另一个值得一提的简单寄存器是 黑洞寄存器,用 "_
引用。这个寄存器的特殊之处在于,写入它的所有内容都会被丢弃。它是 Vim 世界中的 /dev/null
;你可以把一切都放进去,但它永远不会给你任何回报。一种相当有毒的关系。
This may not seem immediately useful, but it does come in handy when running an operation that you don’t want to clobber the existing contents of the unnamed register. For example, if you deleted three lines into the unnamed register with 3dd
with the intent of pasting them elsewhere with p
, but you wanted to delete another line before doing so, you could do that with "_dd
; line gone, and no harm done.
这可能看起来不那么有用,但在执行一个操作时,如果你不想覆盖无名寄存器的现有内容,它就派上用场了。例如,如果你用 3dd
将三行内容删除到无名寄存器中,打算用 p
将它们粘贴到其他地方,但在那之前你想再删除一行,你可以用 "_dd
来做到这一点;行被删除了,而且不会造成任何伤害。
Numbered registers
编号寄存器
The read-only registers 0
through 9
are your “historical record” registers. The register 0
will always contain the most recently yanked text, but never deleted text; this is handy for performing a yank operation, at least one delete operation, and then pasting the text originally yanked with "0p
.
只读寄存器 0
到 9
是你的 “历史记录” 寄存器。寄存器 0
将始终包含最近 拉取的文本,但永远不会包含删除的文本;这对于执行一个拉取操作、至少一个删除操作,然后用 "0p
粘贴最初拉取的文本非常有用。
The registers 1
through 9
are for deleted text, with "1
referencing the most recently deleted text, "2
the text deleted before that, and so on up to "9
.
寄存器 1
到 9
用于 删除的文本,其中 "1
指向最近删除的文本,"2
指向之前删除的文本,依此类推,直到 "9
。
The small delete register
小删除寄存器
This read-only register, referenced by "-
, stores any text that you deleted or changed that was less than one line in length, unless you specifically did so into some other named register. So if you just deleted three characters with 3x
, you’ll find it in here.
这个只读寄存器,用 "-
引用,存储了你删除或更改的所有小于一行长度的文本,除非你特别将其存储到其他命名寄存器中。所以如果你刚刚用 3x
删除了三个字符,你会在这里找到它。
Last inserted text register
最后插入的文本寄存器
The read-only register ".
contains the text that you last inserted. Don’t make the mistake of using this to repeat an insert operation, though; just tap .
for that after you leave insert mode, or have the foresight to prepend a number to your insert operation; for example, 6i
.
只读寄存器 ".
包含你最后一次插入的文本。不过,不要用它来重复插入操作;离开插入模式后,只需按 .
就可以做到这一点,或者在插入操作前加上一个数字,例如 6i
。
Filename registers
文件名寄存器
The read-only register "%
contains the name of the current buffer’s file. Similarly, the "#
register contains the name of the alternate buffer’s file.
只读寄存器 "%
包含当前缓冲区文件的名称。同样,"#
寄存器包含备用缓冲区文件的名称。
Command registers
命令寄存器
The read-only register ":
contains the most recently executed :
command, such as :w
or :help
. This is likely only of interest to you if you’re wanting to paste your most recent command into your Vim buffer. For everything else, such as repeating or editing previous commands, you will almost certainly want to use the command window_.
只读寄存器 ":
包含最近执行的 :
命令,例如 :w
或 :help
。这可能只在你想要将最近的命令粘贴到 Vim 缓冲区时对你感兴趣。对于其他所有事情,比如重复或编辑之前的命令,你几乎肯定想使用命令窗口。
Search registers
搜索寄存器
The read-only register /
contains the most recent search pattern; this can be handy for inserting the search pattern on the command line, by pressing Ctrl-R
and then /
— very useful for performing substitutions using the last search pattern.
只读寄存器 /
包含最近的搜索模式;这可以通过按下 Ctrl-R
然后 /
将搜索模式插入到命令行中,非常有用,特别是当你想使用最后一个搜索模式进行替换操作时。
Expression register
表达式寄存器
Here’s the black sheep of the bunch. The expression register =
is used to treat the results of arbitrary expressions in register context. What that means in actual real words is that you can use it as a calculator, and the result is returned from the register.
这是这一群中的异类。表达式寄存器 =
用于在寄存器上下文中处理任意表达式的结果。用实际的话来说,你可以用它来当计算器,结果会从寄存器返回。
Whenever the expression register is referenced, the cursor is put on the command line to input an expression, such as 2+2
, which is ended with a carriage return.
每次引用表达式寄存器时,光标都会被置于命令行上输入一个表达式,例如 2+2
,然后以回车结束。
This means in normal mode you can type "=2+2<Enter>p
, and 4
will be placed after the cursor; in insert or command mode you can use Ctrl-R
then =2+2<Enter>
for the same result. If you don’t find this syntax as impossibly awkward as I do, then this may well suit you for quick inline calculations … personally, I’d drop to a shell and bust out bc
for this.
这意味着在普通模式下,你可以输入 "=2+2<Enter>p
,然后 4
会被放在光标后面;在插入模式或命令模式下,你可以使用 Ctrl-R
然后输入 =2+2<Enter>
,得到相同的结果。如果你不像我一样觉得这种语法不可能地笨拙,那么这可能很适合你进行快速的行内计算……我个人会切换到 shell 中,然后使用 bc
来完成这个操作。
Knowing your registers well isn’t as profound a productivity boost as squelching a few of the other Vim anti-patterns_, but it can certainly save you some of the annoyance of lost text.
熟悉寄存器并不像消除其他一些 Vim 反模式那样极大地提高生产力,但它确实可以节省一些因丢失文本而带来的烦恼。
This entry was posted in Vim, expression by Tom Ryder.
Registers: the Good, the Bad, and the Ugly Parts
寄存器:好的、坏的和丑陋的部分
Nov 25, 2013
To the newcomer, Vim’s way of doing things may seem strange, but with familiarity it becomes natural. Many of Vim’s features seemed odd to me at first, but when I got used to them I recognised that they had their own particular elegance. However, there’s one feature of Vim that still feels awkward to me: using registers for copy and paste.
对于新人来说,Vim 的做事方式可能看起来很奇怪,但熟悉后就会变得自然而然。起初,Vim 的许多特征对我来说似乎很奇怪,但当我习惯了它们时,我发现它们有自己独特的优雅。但是,Vim 的一个功能仍然让我感到尴尬:使用寄存器进行复制和粘贴。
The Good Parts
好的部分
There’s plenty to like about Vim’s registers. I’ve produced a series of 7 screencasts_ that go into depth about how registers can be used for copy and paste. As far as I’m concerned, that’s all good stuff. But registers aren’t only useful for copy and paste. We can also create and execute macros, by recording our keystrokes into a register then playing back those keystrokes later.
Vim 的寄存器有很多值得喜欢的地方。我制作了一系列 7 个截屏视频,深入探讨了如何使用寄存器进行复制和粘贴。就我而言,这都是好东西。但是寄存器不仅可用于复制和粘贴。我们还可以创建和执行宏,方法是将我们的击键记录到寄存器中,然后播放这些击键。
The fact that registers are multi-purpose means that after recording a macro we can easily make changes to it. For example, we could record our keystrokes into a register, then paste that register into the document, edit the keystrokes in place, then yank the modified version back into a register. (See Practical Vim_, tip 71: Edit the contents of a macro for a demonstration.) I like that flexibility.
寄存器是多用途的,这意味着在录制宏后,我们可以轻松地对其进行更改。例如,我们可以将击键记录到寄存器中,然后将该寄存器粘贴到文档中,就地编辑击键,然后将修改后的版本拉回寄存器中。
I also like how Vim exposes useful information through the search_ and read-only registers_: @/
contains the current search pattern, @:
contains the last Ex command, @.
contains the last inserted text, and @%
contains the filename of the current buffer.
我也喜欢 Vim 通过搜索和只读寄存器公开有用信息的方式:@/
包含当前搜索模式,@:
包含最后一个 Ex 命令,@.
包含最后插入的文本,@%
包含当前缓冲区的文件名。
The Bad Parts
坏的部分
The registers numbered "1
through "9
are a source of frustration for me. If you skim-read the documentation for Vim’s numbered registers_, they sound promising:
编号为 "1
到 "9
的寄存器对我来说是一个令人沮丧的根源。如果你略读一下 Vim 的编号寄存器的文档,它们听起来很有希望:
Vim shifts the previous contents of register 1 into register 2, 2 into 3, and so forth, losing the previous contents of register 9.
Vim 将寄存器 1 的先前内容移到寄存器 2 中,将 2 移到寄存器 3 中,以此类推,丢失寄存器 9 的先前内容。
It seems as though the registers numbered "1
- "9
provide something like a clipboard history, which sounds handy. This would be further enhanced by a little-known feature of the .
command: when used to repeat "1p
, the dot command increments the register number (see :help redo-register_):
编号为 "1
- "9
的寄存器似乎提供了类似于剪贴板历史记录的内容,这听起来很方便。.
命令的一个鲜为人知的功能将进一步增强这一点:当用于重复 "1p
时,点命令会增加寄存器号):
you can use a special feature of the repeat command
.
. It will increase the number of the register used. So if you first do"1P
, the following.
will result in a"2P
. Repeating this will result in all numbered registers being inserted.
你可以使用 repeat 命令.
的特殊功能。它将增加使用的寄存器的数量。因此,如果你先执行"1P
,接下来的.
将导致"2P
。重复此操作将导致插入所有编号的寄存器。
Not only does Vim maintain a sort of clipboard history, but it also provides a convenient method for iterating through the clipboard history. That sounds like a good thing, so why have I filed this under ‘The Bad Parts’?
Vim 不仅维护了一种剪贴板历史记录,而且还提供了一种遍历剪贴板历史记录的便捷方法。这听起来是一件好事,那么为什么我要把它归类到 “坏的部分” 下呢?
There’s a catch: Vim never writes yank operations to register "1
. Instead, yanked text is written to register "0
, which is isolated from the mechanism that propagates values through "1
to "9
. That means that the clipboard history is incomplete. Registers "1
- "9
only record deletions, not yanks.
这里有一个问题:Vim 从不向寄存器 "1
写入拉取操作。相反,被拉取的文本被写入寄存器 "0
,它与通过 "1
将值传播到 "9
的机制隔离。这意味着剪贴板历史记录是不完整的。寄存器 "1
- "9
仅记录删除,不记录拉取。
And when I say that registers "1
- "9
only record deletions, I have to add a further caveat: if the range of text being deleted spans less than one line, it will be written to "-
, the small delete register. That is, unless you prefix the delete operation with a named register. In that case, the text will be written to the named register and to register "1
, but not to "-
.
当我说寄存器 "1
- "9
仅记录删除时,我必须进一步补充一个警告:如果要删除的文本范围小于一行,它将被写入 "-
,即 小删除寄存器。也就是说,除非在删除操作前面加上命名寄存器。在这种情况下,文本将被写入命名寄存器和寄存器 "1
,但不会写入 "-
。
I’ve compiled a table showing which registers are populated by various combinations of yank/delete operations, over a characterwise/linewise range, with or without a named register (see this gist_ for details of how I compiled this information):
我编制了一个表格,显示了在字符/行范围内,有或没有命名寄存器,哪些寄存器由各种拉取/删除操作组合填充:
operation |
"" (default) |
"0 (yank) |
"1 (numbered) |
"a (named) |
"- (small delete) |
---|---|---|---|---|---|
yw |
X | X | - | - | - |
yy |
X | X | - | - | - |
"ayw |
X | - | - | X | - |
"ayy |
X | - | - | X | - |
dw |
X | - | - | - | X |
dd |
X | - | X | - | - |
"adw |
X | - | X | X | - |
"add |
X | - | X | X | - |
There are so many idiosyncrasies in this table that it’s hard to decide what’s a rule and what’s an exception! It’s needlessly complicated. If you’re considering committing this chart to memory, I would urge you not to bother.
这个表格中有太多的特质,很难决定什么是规则,什么是例外!这没有必要地复杂。如果你正在考虑将这张图表牢记在心,我强烈建议你不要打扰。
The Ugly Parts
丑陋的部分
Vim uses non-standard terminology to describe cut, copy, and paste operations. As I’ve noted before_: ‘put’ and ‘paste’ are easily interchangeable, and the word ‘yank’ becomes synonymous with ‘copy’ when you get used to it, but Vim’s use of the word ‘delete’ is problematic.
Vim 使用非标准术语来描述剪切、复制和粘贴操作。正如我之前提到的:‘put’ 和 ‘paste’ 很容易互换,当你习惯了 ‘yank’ 这个词时,它就变成了 ‘copy’ 的同义词,但 Vim 对 ‘delete’ 这个词的使用是有问题的。
In most text editing contexts the word delete means remove. But Vim’s delete operation copies the text into a register, then removes it from the document. In other words, Vim’s delete operation behaves like the standard cut command. I find Vim’s terminology to be unhelpful, so I try to make a point of describing the d{motion}
command as “cut the specified text” (rather than “delete the specified text”). Likewise for x
, c
, s
, and so on.
在大多数文本编辑上下文中,单词 delete 的意思是 remove。但是 Vim 的 delete 操作将文本复制到寄存器中,然后将其从文档中删除。换句话说,Vim 的 delete 操作就像标准的 cut 命令。我发现 Vim 的术语没有帮助,所以我试图将 d{motion}
命令描述为 “cut the specified text”(而不是 “delete the specified text”)。x
、c
、