Linux Vim 寄存器 | 從基礎分類到高級應用

注:本文為 “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.
你可能在使用 pP 粘貼文本時已經用過 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 寄存器類型:

序號英文描述中文描述
1The unnamed register ("").無名寄存器 ("")。
2The numbered registers ("0-9).編號寄存器 ("0-9)。
3The small delete register ("-).小刪除寄存器 ("-)。
4The named registers ("a-z).命名寄存器 ("a-z)。
5The read-only registers (":, "., and "%).只讀寄存器 (":, "., "%)。
6The alternate file register ("#).備用文件寄存器 ("#)。
7The expression register ("=).表達式寄存器 ("=).
8The selection registers ("* and "+).選擇寄存器 ("*"+)。
9The black hole register ("_).黑洞寄存器 ("_)。
10The 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.
還有更多操作符(如 sx),但上面這些是比較有用的。一般來說,如果一個操作符可以刪除文本,它很可能會將文本存儲到寄存器中。

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.
pP 都接受計數和寄存器符號作為參數。例如,要粘貼十次,可以執行 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 實際上會將該文本保存到兩個寄存器中:

  1. The unnamed register (p).
    無名寄存器 (p)

  2. 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:
例如,如果你:

  1. Yank a line (yy)
    拉取一行(yy

  2. Delete a line (dd)
    刪除一行(dd

  3. Delete another line (dd)
    再刪除一行(dd

The yanked register will have the text from step one.
拉取寄存器將包含第一步中的文本。

If you:
如果你:

  1. Yank a line (yy)
    拉取一行(yy

  2. Delete a line (dd)
    刪除一行(dd

  3. 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:
例如:

  1. Delete a word (diw)
    刪除一個單詞(diw

  2. Delete a line (dd)
    刪除一行(dd

  3. Delete a line (dd)
    再刪除一行(dd

"-p gives you the deleted word from step one.
"-p 會給出第一步中刪除的單詞

Another example:
另一個例子:

  1. I delete a word (diw)
    我刪除了一個單詞(diw

  2. I delete a line (dd)
    我刪除了一行(dd

  3. 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,那也沒關系。這僅僅意味著 quotestarquoteplus 是可以互換的(我的 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,你可能想同時使用 unnamedunnamedplus 剪貼板選項。

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 個寄存器開始:

  1. The unnamed register ("").
    無名寄存器 ("")

  2. The named registers ("a-z).
    命名寄存器 ("a-z)

  3. 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.
由于無名寄存器默認對應 pP,你只需要學習兩個寄存器:命名寄存器和編號寄存器。當你需要時,逐漸學習更多的寄存器。不要著急。

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:
同樣地,我們可以通過在使用寄存器的命令(如 cdy 命令)前加上 "a,將緩沖區中的文本而不是命令存儲到這些寄存器中:

  • "ayy — Read current line into register a.

    "ayy — 將當前行讀入寄存器 a

  • "bP — Paste contents of register b above current line.

    "bP — 將寄存器 b 的內容粘貼到當前行上方

  • "cc3w — Change three words, putting the previous three words into register c.

    "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:
通常情況下,將文本拉取或刪除到寄存器中會 替換 該寄存器的先前內容。在某些情況下,將文本 追加 到寄存器會更有用,例如從文件中挑選不同的行以粘貼到其他地方。只需將寄存器名稱大寫即可實現這一點:

  • "ayyReplace the contents of register a with the current line.

    "ayy — 用當前行 替換 寄存器 a 的內容

  • "AyyAppend the current line to register a.

    "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.
只讀寄存器 09 是你的 “歷史記錄” 寄存器。寄存器 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.
寄存器 19 用于 刪除的文本,其中 "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)
ywXX---
yyXX---
"aywX--X-
"ayyX--X-
dwX---X
ddX-X--
"adwX-XX-
"addX-XX-

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”)。xcs 等也是如此。

The fact that x, s, d, and c all cut by default makes it awkward to perform a true deletion. To really delete text (without writing to a register), we have to prefix each of these commands with "_, the blackhole register. That’s bizarre! More often than not, when I use Vim’s delete operation, I only want to remove the text from the document. I don’t want to write it to a register and I consider that to be an unfortunate side-effect.
xsdc 都默認被剪切,這使得執行真正的刪除變得很尷尬。要真正刪除文本(不寫入寄存器),我們必須為每個命令加上 "_,即黑洞寄存器。太奇怪了!通常,當我使用 Vim 的刪除操作時,我只想從文檔中刪除文本。我不想把它寫到寄存器上,我認為這是一個不幸的副作用。

On the other hand, I definitely want to write the text to a register when I use the yank command (after all, that’s the only thing it does!). It’s frustrating that the yank command writes to "0, overwriting my previous yank. Whereas the delete command writes text that I may not even want to keep to "1, preserving the previous eight deletions in registers "2 - "9.
另一方面,當我使用 yank 命令時,我肯定想將文本寫入寄存器(畢竟,這是它唯一能做的事情!)。令人沮喪的是,yank 命令寫入 "0,覆蓋了我之前的 yank。而 delete 命令寫入我甚至可能不想保留到 "1 的文本,將前八次刪除保留在寄存器 "2 - "9 中。

So what?

那又怎樣?

Cut is not a sensible default behaviour for a command named ‘delete’. The terminology is misleading, but the behaviour itself is also unfortunate. Vimcasts episode #52, Meet the yank register_, shows an example workflow where this behaviour acts as an impediment. It would be better if Vim provided two distinct commands: the delete operation would only remove text from the document, while the cut operation would remove text from the document and write it to a register. That Vim’s x, s, d, and c “delete operations” write text to a register is ugly.
對于名為 ‘delete’ 的命令來說,Cut 不是一個明智的默認行為。術語具有誤導性,但行為本身也是不幸的。Vimcasts 第 #52 集 Meet the yank register 展示了一個示例工作流,其中此行為充當障礙。如果 Vim 提供兩個不同的命令會更好:delete 操作只會從文檔中刪除文本,而 cut 操作將從文檔中刪除文本并將其寫入寄存器。Vim 的 xsdc 的 “delete operations” 將文本寫入寄存器是丑陋的。

I can’t find any redeeming features in the behaviour of Vim’s numbered registers, which makes me think they’re just plain bad. They get almost half-way to behaving as a proper clipboard history, but that’s not good enough. A half-cooked feature is a feature wasted.
我在 Vim 的編號寄存器的行為中找不到任何可贖回的功能,這讓我覺得它們簡直太糟糕了。它們幾乎已經完成了一半的行為,就像一個正確的剪貼板歷史記錄一樣,但這還不夠好。半生不熟的功能是浪費的功能。

I’ve learned to live with the good parts of Vim’s copy/paste feature set. The good parts are good enough to get by with, but they’re not as good as they could be. That frustrates me.
我已經學會了接受 Vim 的復制/粘貼功能集的優點。好的部分已經足夠好了,但它們并沒有達到應有的水平。這讓我很沮喪。

I have written my thoughts on how to fix Vim’s registers in the form of a README for cutlass.vim - a plugin that doesn’t yet exist. I’d also like to give a shout out to Steve Vermeulen, who has already implemented some of the same features (and many more features besides) in his vim-easyclip plugin, which you can install and use today.
我已經以 cutlass.vim 的 README 的形式寫下了我關于如何修復 Vim 寄存器的想法 - 一個尚不存在的插件。我還想感謝 Steve Vermeulen,他已經在他的 vim-easyclip 插件中實現了一些與我繪制的相同的功能(以及更多功能),你現在就可以安裝并使用。


vim 中寄存器使用和 vim 標記

rainysia 于 2012-07-06 13:24:36 發布

一、官方幫助手冊

: help registers
: help :registers

二、寄存器分類

  1. 無名(unnamed)寄存器 " ",緩存最后一次操作內容。
  2. 數字(numbered)寄存器 "0 "9,緩存最近操作內容,復制與刪除有別。 "0寄存器緩存最近一次復制的內容, "1 - "9緩存最近9次刪除內容。
  3. 行內刪除(small delete)寄存器 " -,緩存行內刪除內容。
  4. 具名(named)寄存器 "a "z "A - "Z,指定時可用。
  5. 只讀(read - only)寄存器 " : " . " % " #,分別緩存最近命令、最近插入文本、當前文件名、當前交替文件名。
  6. 表達式(expression)寄存器 " =,只讀,用于執行表達式命令。
  7. 選擇及拖拽(selection and drop)寄存器 " * " + " ~,存取GUI選擇文本,可用于與外部應用交互,使用前提為系統剪切板(clipboard)可用。
  8. 黑洞(black hole)寄存器 " _,不緩存操作內容(干凈刪除)。
  9. 模式寄存器(last search pattern) " /,緩存最近的搜索模式。

三、查看寄存器內容

  • : reg :查看所有寄存器內容。
  • : reg 寄存器名 :查看單個寄存器內容 。比如 : reg _: reg *: reg 1: reg 9: reg a等等。

數字寄存器,也是最常用的 從0 - 9 。如果不指定寄存器的名字,那么刪除的內容,vim 默認是存到 1 ,復制內容是存到 0 號寄存器。如果繼續刪除,那么原來 1 的內容就轉到 2 ,類推,當刪除超過 9 的時候,原先的 8 號數字寄存器就轉到 9 ,原先 9 的數字寄存器內容就會丟失。

實驗1

先在vim里面輸入1 - 0 10個數字,每個數字一行,接著從0 9 8 7 6 5 4 3 2依次 dd刪除,然后: reg查看寄存器,接著 yy復制數字1的這行,可以看見 "0寄存器的值是1 , "1 "9寄存器依次是2~0。

使用 p來粘貼,如果最近一次操作是復制,那么 p就會添加 "0寄存器的內容,如果最近一次操作是刪除那么就添加 "1寄存器的內容 ,如果要粘貼其它數字寄存器的內容,使用 "? p來粘貼,比如要粘貼 "2寄存器里面的,則在vim命令模式下輸入 "2 p就可以取出 "2寄存器里面的內容了。其他的寄存器都是通過 "? p來訪問使用的。

具名寄存器(字母寄存器)

也就是名稱是單個英文字母, "a "b "c,....,"z ,使用時,在復制或者刪除命令 y或者 d時,在前面加上字母寄存器的字母名稱就可以了,或者是直接在刪除或者復制命令后加上字母寄存器的字母。比如: y n就是復制當前行到 "n字母寄存器 ,: 5,10 y m復制5到10行內容到 "m字母寄存器 。

: pu! n :將字母寄存器 "n的內容粘貼到當前行之前 ,也可以使用 "mP效果一樣。
: p n :粘貼字母寄存器 "n的內容到當前行的下一行 ,也可以使用 "n p效果一樣。

(命令模式下 : y: d: pu分別是復制、刪除和粘貼 。一般模式下 "寄存器名 y “寄存器名 d "寄存器名 p代表著復制、刪除和粘貼 )

實驗 2

  • "a yy :就是復制當前行到 "a字母寄存器中。
  • "b 3yy :復制當前行和下面2行到 "b字母寄存器。
  • "a p :粘貼 "a字母寄存器的內容。
  • "c d2l :向右刪除2個字符并且把內容存到字母寄存器 "c中 。
  • "c p :粘貼 "c字母寄存器里面的內容。
  • "d 3dd :刪除當前行和下面2行并且把內容存到字母寄存器 "d中 。
  • "f df. :刪除當前位置到句號并且把內容存到字母寄存器 "f中。
  • "g d'c :刪除當前位置到標記c位置并且把內容存到字母寄存器 "g中。

同一個字母的大寫和小寫表示的是同一個寄存器,但是行為會不同,字母寄存器的名稱大寫時,當使用大寫的寄存器進行復制或者刪除文本時,原先的字母寄存器中的內容會被保留,剛刪除或復制的內容則附加到原來字母寄存器內容的后面。字母寄存器只有在指定時才被使用。

無名寄存器

" "保存最近一次復制或刪除的文本。就是 p命令默認使用的寄存器。

短刪除寄存器

" -(The small delete register)。事實上剛刪除的文本并不一定被送到數字寄存器,如果刪除的文本不含換行符(不足一整句)則文本被送至這個寄存器。如 x d2h這兩條命令刪除的文本都會被送到這個寄存器。注意下在這條命令雖然刪除了一整行的文本但因不含換行符所以也被送到這個寄存器 0d$

只讀寄存器

" : " . " % " #,它們分別用來保存最近一次在命令行窗口使用的命令、最近一次插入的文本、當前編輯的文件名、當前的替代文件名。

表達式寄存器

" =

選擇與拖放的寄存器

" * " + " ~,在Windows中這幾個寄存器就是剪貼板。在Linux中它們也是剪貼板——但這幾個寄存器是有所區別的。

黑洞寄存器

" _,刪除操作會影響現有數字寄存器的內容。前一個數字寄存器的值傳給后一個數字寄存器, "9的內容被丟棄,新刪除的文本則放入 "1。這至少有兩個直接的影響,一是 "9的內容被丟棄;二是寄存器中文本的位置都發生了變化。而復制操作會改變 "0的值。如果你不希望刪除或復制的操作影響數字寄存器的話就使用這個寄存器。使用這個寄存器進行刪除或復制的內容都會被丟棄——這還可以提高一點速度節省一點空間。

搜索式樣寄存器

" /,保存上一次搜索所使用的式樣。注意這也包括了 s命令中所使用的搜索式樣。

寄存器有26個字母寄存器可以使用 ;可以使用大寫字母將文本附加到已有內容后。如果在你關閉文件之前還沒想到這將這些內容貼在哪里也沒關系, 用: wviminfo my_viminfo命令。下一次編輯時輸入: rviminfo! my_viminfo或者在命令行用這個命令運行 gvim - i my_viminfo myfile: reg看寄存器的內容都在的。

四、寄存器是個變量——特殊的變量

只要在前面加上一個@號就可以用變量的方式訪問寄存器。所以,變量的操作也同樣適用于寄存器。

  • 給寄存器賦值
    let @e = "開始\\<CR>"
    let @E = "結束"
    echo @e
    開始
    結束
    
  • 將寄存器作為表達式的一部分
    let my_var = @a. @c
    
  • 清空寄存器
    " 注意:不能用unlet清除寄存器。
    : let @e = " "
    

在編輯窗口與命令窗口間交換內容

編輯窗口的文本可以放進寄存器。搜索式樣和上一條Ex命令被放進了只讀寄存器 " / " :

已知寄存器的內容可以在貼到編輯窗口。可以在命令窗口作為變量使用。那有沒有辦法在命令窗口插入寄存器的內容呢 ?有沒有辦法在搜索式樣中插入寄存器的內容呢 ?

比如,假設在寄存器e中保存著一個文件名 :“這是一個保存在寄存器中的很長的文件名.txt”。而我想使用: w命令保存一個當前編輯文件的副本——使用寄存器e中的那個文件名。如果使用: w @e的話,文件名將是“@e”而不是“這是一個保存在寄存器中的很長的文件名.txt”。這時該怎么辦呢 ?考慮到寄存器也是變量,我們可以使用寄存器的傳統辦法。

  1. 方法一 :使用: execute命令
    寫入以 "e為名的寄存器中 :
: exe "w ". @e
  1. 方法二 :使用Ctrl - R轉義
    搜索寄存器e的內容。<Ctrl - R>表示用戶在這里按了組合鍵Ctrl - R——不要直接輸入<Ctrl - R>這8個字符。
/ <Ctrl - R>e /

使用<Ctrl - R>的方式可適用于各種輸入的環境中 :在插入模式輸入時、在命令窗口輸入時、在搜索時。在插入模式時要輸入寄存器內容并不需要退回到一般模式再使用 p指令,可以直接按<Ctrl - R>e,當然e可以改成相應的寄存器名。在命令窗口與搜索時也是一樣 :按Ctrl - R輸入寄存器名。

提示 :除了一些不接受變量作為參數,不能使用寄存器名稱的情況外,還有一些情況也要求插入寄存器的內容。有時我們插入寄存器的內容而不使用寄存器變量是因為我們可能還需要手工對寄存器的內容進行一些編輯。

無名寄存器總是保存著最近一次復制或刪除的內容。不帶寄存器名地使用 p就可以添加該寄存器的內容到當前位置了。但是既然“無名”該怎么在命令窗口使用這個存器呢 ?又怎么插入無名寄存器的內容呢 ?答案是使用 @ ",插入也是一樣按Ctrl - R再按輸入 "就可以了。

現在總結一下 : " :保存了上一條Ex命令。 " /保存了上一條搜索式樣。字母寄存器及數字寄存器中可以保存編輯的文本。并且我們也可以在不同的環境中插入寄存器的內容。通過寄存器我們可以方便地在命令窗口編輯窗口以及搜索中交換內容。相對而言一般的變量就沒這么方便,你只能在命令行中使用變量也只能是命令行中給變量賦值。

在buffer之間及程序之間交換內容

寄存器是全局的變量。在Vim中打開的所有文件,共享這些寄存器。你可以在不同的文件之間交換內容。

通過寄存器 " * " +,Vim可以與其他程序交換信息。在Windows中這兩個寄存器是一樣的。在Linux中這兩個寄存器則有所不同。
: help gui - selections
: help x11 - selection

寄存器可以做為宏

跟一般的變量相比寄存器還有一個最大的特點就是寄存器本身可以做為宏使用。如果你有用過一般模式命令 q的話就會發現 q錄制的擊鍵序列就是存在寄存器中的,并且可以直接使用寄存器執行命令。現在做做實驗,新建一文檔隨便輸入幾行文字。輸入 :

qeggddq

上面這條命令錄制了一個宏并保存到寄存器e中。這個宏的作用是回到第一行并刪除該行。現在看一下寄存器的內容 :

: reg e

就是你剛才的鍵盤命令 ggdd。要運行剛錄制的鍵盤操作在一般模式輸入 @e就可以運行了,輸入 3@e會將前三行刪除。

當然你不一定要用 q來錄制宏——因為寄存器也是變量。

: let @e = "/刪除本行/^Mdd : w^M"
@e

上面的 ^M表示的是回車鍵。可不是輸入 ^再輸入 M,而是輸入Ctrl - V(Windows是Ctrl - Q)再按回車鍵這時就會出現 ^M表示這是一個回車鍵。常見的還有 ^\[表示的是<ESC>鍵。輸入的方法也是一樣按Ctrl - V再按Esc鍵。這樣輸入控制字符的方式是傳統的Vi方法。在Vim中也支持用按鍵名表示這些控制字符。比如<CR>表示回車鍵,所以上面的命令也可表示為 :

: let @e = "/刪除本行/\\<CR>dd : w\\<CR>"

這里一定要用雙引號,我們在“腳本”一篇中已經講到了,在單引號中的字串會被當成普通字串。后面這種表示控制字符的方式與 'cpoptions'的設置有關,雖然在默認情況下都是可行的但是建議使用第一種方式。不過為了更好的可讀性在教程中我們還是可能使用后面這種方式表示控制字符。

正因為寄存器可以直接執行所以 " :可以用來執行上一條在命令窗口使用的命令 :

:@:

記得最后要按回車執行。當然現在由于命令行的歷史功能這種用法沒有什么實用價值。

在重定向命令中使用

重定向命令(: redir)是一個較常用的技巧。所有的字母寄存器、 @ *、無名寄存器( @ ")都可以在重定向命令中使用。還是用個例子說明好了 :

假設你的小說家朋友寄了一本小說的初稿給你,但顯然他沒有整理文本的習慣——好消息是他這次竟然沒用Word寫。在你往下看之前你決定先將文檔做適當的整理。使用Vim作這種事當然是小菜一碟,只用了10分鐘你就將他的小說整理成一份格式整齊的文檔了。

第六章 為山九仞
===============小明是從不在午時之前離開被褥的,今天卻是個例外。他一夜沒睡不過他卻覺得精神比任何時候都好……< 省略800行 >……第七章 功虧一簣
===============小明已經很久沒像今天這樣開心了。從那時到現在已有二十年又一天了。對他來講二十年并不長,能在二十年又三天之內報仇已經是出乎自己意料了。何況對方是可是威巒鏢局的大當家。想到這里他的眼睛瞇得更小了……再過兩天……只要兩天!

但你發現這份初稿沒目錄,而你看小說的習慣是從目錄看起。于是你決定整理一份目錄。于是你用了寄存器 :

: let @a = " "
: g /^第.\\{1,3}章 /y A

這兩條命令將所有章的標題放到寄存器A中。你可以在需要目錄的地方 "a p。不過你還想在每章標題后加上該章對應的行號,你知道這時可以用: redir

: redir @a
: echo "目錄:"
: g /^第.\\{1,3}章 /echo getline(".") . "\\t\\t\\t" . line(".")
: redir END

現在你的寄存器a中有了一個帶行號的目錄了。只用了幾行命令你就漂亮地完成任務了,想到這這里你的眼睛瞇得更小了……

注 :這里用到的函數是我們在講折疊時說過的 getline("."),表示返回當前行。 line(".")則返回當前的行號。這兩個函數的詳細用法見文檔。通過對這個腳本進行擴充我們甚至可以讓它抓取含小節的目錄。

上面的例子演示了通過: redir用戶能對寄存器的內容進行進一步的加工而不只是簡單的摘錄,它增加了寄存器的使用范圍。這正是與redir之所以成為寄存器重要性質之一的重要原因。在Vim7.0之前的版本中不支持重定向內容到變量,所以寄存器成了唯一選擇。考慮到: redir是比較重要的命令,寄存器吃香也就不足為奇了。但在Vim7開始支持重定向內容到變量后,寄存器就沒那么重要了——當然如果你希望方便地將重定向的內容插入到文件中的話寄存器仍是理想之選。關于: redir的更多內容,將會另外解說。

表達式寄存器

雖說是寄存器但從各種角度來看這都是個冒牌的寄存器。它的主要作用是實時計算表達式的值。適用的場合 :在編輯輸入時、在命令窗口輸入時、在搜索時。使用的方式是按Ctrl - R再按等號(<C - R>=),接著輸入表達式,原來輸入的位置就會插入表達式的值。只要是合法的表達式都可以使用。我們知道字串可以做為合法的表達式,所以在插入模式下按Ctrl - R =然后輸入 "abc"(注意包括 ")當前位置就插入了abc。當然我們不會為了輸入字串而使用這個寄存器。現在寄存器a中保存著一個數字,你想在當前文檔中搜索該數字4倍的另一個數,你當然不想自己計算。這時使用表達式寄存器:/<Ctrl - R>=@a * 4<Enter>/<Enter> 。其中<Ctrl - R>不是讓你輸入這8個字符而是按組合鍵Ctrl - R,同理<Enter>表示這里按了回車。任何時候當你需要插入一個表達式的值時都可以使用這個寄存器。

如果在輸入=號后直接按回車沒有輸入表達式的話默認使用上一次使用的表達式。

在上一個例子中,如果你把剛才的目錄貼在文件的開頭(當然是開頭),會發現行號不準了因為所有的內容都被往下移了——第一行現在變成在目錄后面了。假設增加的目錄有25行(不知道有幾行?:se nu),現在文章的第一行(是空行)成了第26行。當然這樣問題難不倒你,讓表達式寄存器重新計算一下行號就行了——將原來的行號加上25。

注 :下面幾個控制字符的輸入方式:^I^R^M,分別表示的是Tab鍵、Ctrl - R、回車。它們的輸入方式是按Ctrl - V(或Ctrl - Q)再輸入各自所表示的鍵。

:1,25 norm $T^I"ty$:s/\[0 - 9\]\\+$/^R = @t + 25^M/^M
  • :1,25 norm:在1到25行之間(目錄區)執行一般模式命令。
  • $T^I:移到行末,將光標定位到最后一個制表符后(也就是第一個數字的位置)。
  • "ty$:將數字復制到寄存器t中。
  • :s/\[0 - 9\]\\+$/:將行末的數字(每一章的行號)。
  • ^R =:插入表達式。
  • @t + 25:將寄存器t中的數字加上25。
  • ^M:插入回車結束表達式。
  • /^M:結束s命令并在插入回車鍵。
  • <Enter>:在全部輸入完成后別忘了按回車執行命令。

還有一個特殊的地方可以用上表達式寄存器(Vim文檔沒說這是一個表達式寄存器,但它的使用方式與表達式寄存器完全一樣),就是s命令。:s命令的命令格式為::s/lhs/rhs/,表示搜索lhs并替換為rhs。一個特殊用法就是當rhs的開頭為\\`=‘時,這rhs將被視為表達式。lhs將被替換為表達式的值。

  • :將當前行中的算術式'42x31'替換為算術式的結果。
:s/42x31/\\=42 * 31/

再回到剛才的例子中,現在我們可以用一種相對優雅的方式計算更新該目錄的行號:

:1,25s/\[0 - 9\]\\+$/\\=submatch(0)+25/

注 :submatch()只在:s命令rhs的表達式中使用。submatch(0)與原來的&在rhs的作用是一樣的。submatch(1)就相當于原來rhs中的\\1,依此類推。

創建標記

將光標移到某一行,使用ma命令進行標記。其中,m是標記命令,a是所做標記的名稱。

可以使用小寫字母a - z或大寫字母A - Z中的任意一個做為標記名稱。小寫字母的標記,僅用于當前緩沖區;而大寫字母的標記,則可以跨越不同的緩沖區。例如,你正在編輯File1,但仍然可以使用'A命令,移動到File2中創建的標記A。

跳轉標記

創建標記后,可以使用'a命令,移動到指定標記行的首個非空字符。這里'是單引號。也可以使用````a ```命令,移到所做標記時的光標位置。這里```````是反引號(也就是數字鍵1左邊的那一個)。

列示標記

利用:marks命令,可以列出所有標記。這其中也包括一些系統內置的特殊標記(Special marks):

標記說明
.最近編輯的位置
0 - 9最近使用的文件
最近插入的位置
'上一次跳轉前的位置
"上一次退出文件時的位置
[上一次修改的開始處
]上一次修改的結尾處
刪除標記

如果刪除了做過標記的文本行,那么所做的標記也就不存在了。我們不僅可以利用標記來快速移動,而且還可以使用標記來刪除文本,例如在某一行用ma做了標記,然后就可以使用d'a來刪掉這一行。當然,我們也可以使用y'a命令就可以來復制這一行了。

使用:delmarks a b c命令,可以刪除某個或多個標記;而:delmarks! 命令,則會刪除所有標記。

利用:help mark - motions命令,可以查看關于標記的更多幫助信息。

命令小結
命令說明
m創建標記
'移動到標記的文本行首
```````移動到標記的光標位置
:marks列示所有標記
:delmarks刪除指定標記
:delmarks!刪除所有標記

Vim 常規操作 —— 復制 _粘貼 _剪切 (深入 Vim 寄存器)

大娛樂家 cpy 于 2020-03-28 00:05:12 發布

閱讀這篇文章能學到什么?

這篇文章將從 Vim 寄存器的作用角度解答使用 vim 過程中進行復制、粘貼、剪切如何操作的問題。

1. Vim 寄存器

vim 有很多寄存器,我們進行的復制粘貼操作實際就是往這些寄存器寫或者讀取內容的操作,要想更好的使用復制粘貼功能,需要對這些寄存器有基本的了解。這些寄存器各有其功能,以我現在使用的 gvim_8.2.0318_x64_signed 舉例(不排除未來會有版本差異),它具有這么幾類寄存器:

  • 無名寄存器 ":緩存最近一次的內容,也是復制粘貼最常用的寄存器;
  • 編號寄存器 0~9:緩存最近操作內容。其中 0 號寄存器有別其他,它緩存最近一次復制的內容,1~9 緩存最近 9 次刪除的內容。
  • 命名寄存器 a~z 或 A~Z:指定名稱的寄存器,可以由用戶自由選擇內容緩存進去。要注意的是大小寫雖然對應同一個寄存器,但是功能有差異。
  • 只讀寄存器 .、:、%:分別緩存上次插入的文本、最近執行的 Ex 命令、當前文件名。
  • 表達式寄存器 =:實際上并不存在這么一個寄存器用來緩存文本,這是方便再使用寄存器的命令中使用表達式的一種方式。該寄存器是可讀寫的。它緩存的是表達式而不是表達式結果。
  • 輪換文件寄存器 #:內容為當前窗口輪換文件的名字(網上一些文章說將其也歸類為只讀寄存器是錯的,這個寄存器是可寫的)。
  • 選擇和拖拽寄存器 *、+、:用于與其他應用之間的內容傳遞交互,是只讀的。
  • 最近搜索模式寄存器 /:內容為最近搜索的模式。
  • 行內刪除寄存器 -:該寄存器保存刪除不到一行的內容,除非刻意指定了用其他寄存器。
  • 黑洞寄存器 _:將內容放入黑洞寄存器不會留緩存記錄。

你可以在 vim 中輸入指令 reg 查看它的寄存器:

在這里插入圖片描述

我們可以看到上面提到的一些寄存器并沒有顯示出來,但這并不代表它們不存在,比如選擇和拖拽寄存器的 + (又稱為系統寄存器),它需要你的vim支持 clipboard~ 寄存器需要vim支持 dnd 。而命名寄存器 a~zA~Z 是因為使用大寫時操作的依然是對應的小寫寄存器,而小寫寄存器只有在有內容時才會顯示,如果未使用則不會顯示。黑洞寄存器是實際并沒有用于存儲內容的寄存器,它表示的含義就是不將內容放入可以緩存的任何一個寄存器,所以也就能理解為什么沒有顯示該寄存器。

如何查看自己的vim是否支持clipboard和dnd呢?打開cmd,輸入vim --version如果能看到clipboard和dnd前面顯示了+則說明支持,如果是-則不支持。不持支的化你可能需要安裝支持的版本,或者自己編譯vim使其支持,clipboard一般都是支持的,而dnd一般用不到可以不必太在意。

2. Vim復制、粘貼、剪切最基本操作

在進一步學習Vim的寄存器之前我們先學習下Vim的幾種基本操作:

必備知識:Vim中y(yank縮寫,抽出的意思)鍵用于復制功能;p(past縮寫,放置的意思)鍵用于粘貼功能;d(delete縮寫,刪除的意思)鍵用于剪切功能,因為vim的刪除是會在緩存備份的,所以實際就是剪切功能。

  • 常用復制操作:

    • 復制選中的文本:可視模式下選中文本按后y

    • 復制n行:{n}yy{n}Yy{n}y {} 內參數n是可選的,n為從當前行往下數需要復制的行數,當n為1時可省略。

    • 復制到文件末或首:從當前行復制到文件首ygg,從當前行復制到文件尾yG

    • 復制到行首或尾:從光標位置(不包括光標當前所在的字符)復制到行首個字符y^,從光標位置(不包括光標當前所在的字符)復制到行第一列y0。從光標位置(包括光標當前所在的字符)復制到行末y$

  • 常用粘貼操作:

    • 將緩存內容粘貼到光標未知:普通模式下按p
  • 常用剪切操作:

    • 剪切選中的文本:可視模式下選中文本后按d

    • 剪切n行:{n}dd{n}Dd{n}dn為從當前行往下數需要剪切的行數,當n為1時可省略。

    • 剪切到文件末或首:從當前行剪切到文件首dgg,從當前行剪切到文件尾dG

    • 剪切到行首或尾:從光標位置(不包括光標當前所在的字符)剪切到行首個字符y^,從光標位置(不包括光標當前所在的字符)剪切到行第一列y0。從光標位置(包括光標當前所在的字符)剪切到行末y$

前面我們講到了Vim的多種寄存器可用于緩存內容,那上面這些復制、粘貼、剪切操作用到了哪些寄存器呢?

當沒有指定使用某個寄存器時,Vim都會按默認寄存器操作。比如y指令的復制操作默認是將內容緩存在了 " 無名寄存器種,所以粘貼時默認也是將無名寄存器的內容取出。剪切操作的的默認寄存器是 1~9 編號寄存器,這9個寄存器構成了一個“隊列”,1號是隊尾存放最新剪切掉的內容,當有更新的內容被剪切時小編號內容往大編號移動,最新內容放1號寄存器,超過9號之后就舍去。

用法示例:

使用yy復制整行,觀察 " 無名寄存器:

yy 復制整行

在這里插入圖片描述

觀察 " 寄存器

在這里插入圖片描述

使用dd刪除 10 行,觀察 1~9 編號寄存器的值:

dd 剪切 10 行文本

在這里插入圖片描述

觀察 1~9 編號寄存器

在這里插入圖片描述

3. 如何指定使用某個寄存器

  • 復制操作

    選中要復制的內容,在普通模式下鍵入指令: "{x}y, {} 內的值是可選的,x代表指定要使用的寄存器。

    舉例:要將選中的文本緩存到 a 寄存器則需鍵入指令: "ay

  • 粘貼操作

    將光標移動要要粘貼的未知,在普通模式下鍵入指令: "{x}p,同樣 {} 內的值是可選的,x代表指定要使用的寄存器。

    舉例:要粘貼 a 寄存器的內容則需鍵入指令: "ap

  • 剪切操作

    vim的刪除其實是剪切,刪除的同時默認會把內容放進相關的緩存(編號寄存器)。選中要剪切的內容,在普通模式下鍵入指令: "{x}d。

    舉例:要將選中的文本剪切到 + 系統寄存器則需鍵入指令: "+d

注意:以上的x值并不是指定任意寄存器都能操作成功,比如復制往只讀寄存器里緩存內容。剪切操作會按編號寄存器的順序從1到9傳遞緩存內容,不能自己打亂。等等。

4. 各寄存器詳細講解

4.1 " 無名寄存器

當使用y相關指令且未指定寄存器時,內容會被填充到無名寄存器中。當使用p相關指令且未指定寄存器時進行粘貼默認取出無名寄存器內容。類似的還有dcsx等和復制或刪除相關的指令,在未指定寄存器情況下默認都是使用無名寄存器。無名寄存器用于緩存最近一次進行的復制或剪切內容,即使這定了其他寄存器,無名寄存器也都會被填充最近一次的復制或剪切內容,除非指定的是黑洞寄存器。

用法示例:

使用yy復制文本到 a~zA~Z 命名寄存器,觀察 " 無名寄存器內容是否也被修改:

使用命令"ay復制整行到a寄存器,觀察 " 寄存器和 a 寄存器值

在這里插入圖片描述

從上圖可以看出 " 寄存器和 a 寄存器值都發生改變緩存了一份復制內容。

4.2 0~9 編號寄存器

這些寄存器用來存放復制和剪切命令的文本。其中 0 號寄存器用于存放最近復制的文本,而 1~9 號用于存放最近剪切的文本(如果文本少于一行時緩存在行內刪除寄存器)。每進行一次剪切操作,Vim會把前一次的寄存器 1 中的內容轉存到寄存器 22 又到 3 ,依此類推,到 9 之后就舍棄。也可以指定緩存的寄存器,緩存的內容會被放到指定的寄存器和 1 號寄存器種有

注意:指定寄存器進行剪切時,會先將內容緩存到指定的寄存器,然后又會在 1 號寄存器進行緩存,這是有先后順序的。比如往 a 寄存器剪切,則內容緩存到 a 寄存器和 1 號寄存器種,但是往 2 號寄存器剪切,內容被緩存到 3 號寄存器和 1 號寄存器,因為緩存 1 號寄存器時編號寄存器內容發生了一次移動。最后,黑洞寄存器依舊是個例外,往黑洞寄存器剪切不會保存內容,即使是 1 號寄存器。

用法示例:

使用"bd指令剪切一行內容到b寄存器,觀察 b 寄存器和 1 寄存器值

在這里插入圖片描述

從圖中可以看出,我們指定寄存器b剪切了一行文本,這行文本的內容總共被緩存到了三個地方, 1 號寄存器、 b 寄存器、 " 無名寄存器。回顧一下前面的無名寄存器,它會自動緩存最近一次的復制或剪切內容,所以就能理解為什么這里進行指定寄存器的剪切操作會緩存到無名寄存器里。

0 號寄存器用于存放最近復制的文本,你可能會發現很不多時候它和 " 無名寄存器的值是相同的,比如對一行文本用yy進行復制。

用法示例:

對一行文本用yy指令進行復制,觀察 " 無名寄存器和 0 號寄存器值:

在這里插入圖片描述

繼續看,對一行文本用dd進行剪切,觀察 " 無名寄存器和 0 號寄存器值:

在這里插入圖片描述

通過以上對比可知, " 無名寄存器緩存最近一次復制或剪切的內容, 0 號寄存器緩存最近一次復制的內容,而 1~9 號寄存器用于緩存最近9此的剪切內容。所以 " 無名寄存器的值要么等于 0 號寄存器,要么等于 1 號寄存器。

4.3 a~zA~Z 命名寄存器

編號寄存器Vim是不會對其主動操作的,他們是給使用者在編輯過程中自由使用,靈活的使用他們將會使得你的代碼編輯最少的敲打重復內容以及調整代碼塊的位置。這些寄存器在無內容時使用:reg指令不會顯示。你可能已經注意到了大小寫的問題, aA 是否時兩個不同的寄存器?我要告訴你他們都是 a 寄存器,但是產生的效果不同。

用法示例:

對一行文本用"ay指令進行復制,重復兩次該操作,觀察 a 寄存器值:

在這里插入圖片描述

可以看到重復兩次操作, a 寄存器也只能保存最新一次的內容。

對一行文本用"Ay指令進行復制,重復兩次該操作,觀察 a 寄存器值:

在這里插入圖片描述

可以看到重復兩次操作, a 寄存器保存了多次復制的內容。

所以命名寄存器的大小寫指的都是小寫寄存器進行存儲,但是當使用大寫時會把內容進行追加,不會清楚之前保存的內容。利用好大寫的命名寄存器可以拼接出我們想要的內容。

注意:其他寄存器Vim對其都有默認的操作,將需要內容保存到其他寄存器會很不安全,因為很可能會Vim自動覆蓋,而命名寄存器擁有足夠的數量且由用戶操作,所以命名寄存器會是我們常用的寄存器。

4.4 . : % 只讀寄存器

這些寄存器都是只讀的,有其特殊含義所以只能由Vim寫。
% 被用于存放當前文件的文件名。

: 緩存最近執行過的命令行,需要注意的是只有當命令中至少有一個字符是鍵入的,該寄存器才會對指令進行緩存,如果命令行完全來自映射并不會緩存這些指令。這個寄存器需要你的Vim支持 cmdline_hist 特性。

. 在這里插入代碼片,寄存器被用于存放最近插入的文本,進入插入模式后輸入的內容會被緩存進這個寄存器里,但是不會緩存通過粘貼途徑放置的文本。

用法示例:

使用echo @%命令輸出 % 寄存器的值。"%p粘貼出 % 寄存器的值:

在這里插入圖片描述

可以看到 % 寄存器內的值就是當前文件名

用法示例:

使用:echo "nihao"命令執行一遍字符串輸出,然后使用:@:重復執行一次最近執行過的命令。使用":p命令將最近執行的命令內容粘貼出來:

注意Vim的寄存器都可以前面加上@將其當變量使用其值,比如@%和@:。

在這里插入圖片描述

用法示例:

使用".p指令粘貼最近一次插入的文本:

在這里插入圖片描述

插入一段文本后觀察 . 寄存器的值:

在這里插入圖片描述

可以看到 . 寄存器將插入文本過程中輸入的文本內容和一些退格和換行等信息也保存了,所以粘貼其內容的時候會是完全一樣的文本。

注意 . 寄存器和 . 指令不同,Vim重.指令可以將最近的一些操作重復執行,而 . 寄存器是用來緩存最近插入的文本的。一個是指令一個是寄存器,不要搞混了。

4.5 = 表達式寄存器

你可以在插入模式按鍵ctrl r =將會等待你輸入表達式,會在光標處輸出表達式的結果(結果自動轉換為字符串類型。在普通模式和可視模式下"=同樣可執行表達式,不過表達式的結果只有在插入模式下才會輸出在光標處。最近使用的表達式會被寫入緩存到表達式寄存器(實際并不是一個寄存器,輸入表達式時你可以在命令行按上下鍵選擇最近使用過的多條表達式,默認顯示最新的表達式)。

用法示例:

使用ctrl r =指令在插入模式下計算表達式并輸出值:

在這里插入圖片描述

使用指令:reg查看表達式內容:

在這里插入圖片描述

注意:如果你無法修改 = 表達式寄存器的值,那很有可能是因為該寄存器被你的插件占用了,比如在插件Neardtree處于打開狀態下,該寄存器就會被該插件一直占用,但是不影響插入模式下輸出表達式的計算結果。

4.6 # 輪換文件寄存器

這個寄存器也是在沒有值時:reg指令下并不會顯示它。它的值為當前窗口輪換文件的名字,你可以簡單的理解為“上一次打開的文件的相對路徑(這個相對路徑不是指相對當前文件,是相對Vim的當前所處目錄”,為什么要叫輪換文件寄存器呢?因為可以使用指令ctrl ^在當前文件和上一次文件之間來回切換。

用法示例:

使用"#p指令粘貼 # 輪換文件寄存器值:

在這里插入圖片描述

使用reg查看 # 輪換文件寄存器值:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ejVpipfI-1585324490702)在這里插入圖片描述

4.7 *、+、~ 選擇和拖拽寄存器

~ 寄存器是只讀的,它緩存最近一次拖放操作放下的文本。比如你從其他地方鼠標選中一段文本將其直接拖入Vim界面,這時候這些文本就會被緩存到 ~ 寄存器里。需要你的vim支持 dnd 才可使用此寄存器。 + 寄存器就是我們常說的系統寄存器,用于和外界內容的拷進拷出。在MS-Windows上, *+ 寄存器是等價的,而在X11系統上有區別。

4,8 / 最近搜索模式寄存器

將最近的搜索模式緩存入該寄存器,實際不止緩存一條內容,它可以緩存最近使用過的搜索模式,普通模式下按/后可通過鼠標上下鍵選擇。

用法示例:

使用/nihao指令進行模式搜索后,使用"/p指令粘貼最近使用過的模式匹配內容:

在這里插入圖片描述

使用:reg指令查看 / 最近模糊模式寄存器

在這里插入圖片描述

4.9 - 行內刪除寄存器

在行內進行刪除時(刪除的內容未達到一行),內容默認保存到 - 行內寄存器下。如果指定緩存在別的寄存器下時,內容只會被緩存到指定的寄存器,不會改變 - 行內寄存器的值。

用法示例:

使用指令"ad"刪除行內一段文本后,使用指令:reg查看寄存器值變化:

在這里插入圖片描述

刪除的行內內容放入指定寄存器a,且 - 行內寄存器值并未改變。當然 " 無名寄存器的值也會被改變。

4.10 _ 黑洞寄存器

將內容指定放入 _ 黑洞寄存器就意味著不放入任何其他寄存器。當你想徹底刪除某些內容而不影響其他寄存器時就可以指定其放入 _ 黑洞寄存器。

用法示例:

使用指令"_d刪除一行文本”1010101010“,觀察各個寄存器值變化:

在這里插入圖片描述

可以看到,指定放入 _ 黑洞寄存器的內容不會改變其他任何寄存器的值。


via:

  • Registers | Learn Vim
    https://learnvim.irian.to/basics/registers

  • Advanced Vim registers | Arabesque
    https://blog.sanctum.geek.nz/advanced-vim-registers/

  • Registers: the Good, the Bad, and the Ugly Parts
    http://vimcasts.org/blog/2013/11/registers-the-good-the-bad-and-the-ugly-parts/

  • vim 中寄存器使用和 vim 標記。_vim 寄存器清除 - CSDN 博客
    https://blog.csdn.net/rainysia/article/details/7721691

  • Vim 常規操作 —— 復制_粘貼_剪切 (深入 Vim 寄存器)_vim 粘貼 - CSDN 博客
    https://blog.csdn.net/qq_42475711/article/details/105153213

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72940.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72940.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72940.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Java/數據結構】隊列(Quque)

本博客將介紹隊列的相關知識&#xff0c;包括基于數組的普通隊列&#xff0c;基于鏈表的普通隊列&#xff0c;基于數組的雙端隊列&#xff0c;基于鏈表的雙端隊列&#xff0c;但不包括優先級隊列&#xff08;PriorityQueue&#xff09;&#xff0c;此數據結構將單獨發一篇博客&…

[數據結構]排序之 歸并排序(有詳細的遞歸圖解)

一、非遞歸 基本思想&#xff1a; 歸并排序&#xff08; MERGE-SORT &#xff09;是建立在歸并操作上的一種有效的排序算法 , 該算法是采用分治法&#xff08; Divide andConquer&#xff09;的一個非常典型的應用。將已有序的子序列合并&#xff0c;得到完全有序的序列&#x…

docker安裝向量數據庫Milvus及可視化工具 Attu

前置條件 1.安裝了docker 2.服務器網絡正常&#xff0c;可以連接到容器下載地址 3.服務器磁盤空間正常&#xff0c;docker磁盤占用過大&#xff0c;請參考docker容量占用過大解決辦法 一、下載yml文件 可在文章資源下載或者自行下載&#xff1a;下載yml 下載這個單機版本的…

科技云報到:AI Agent打了個響指,商業齒輪加速轉動

科技云報到原創。 3月16日&#xff0c;百度旗下文心大模型4.5和文心大模型X1正式發布。目前&#xff0c;兩款模型已在文心一言官網上線&#xff0c;免費向用戶開放。 同時&#xff0c;文心大模型4.5已上線百度智能云千帆大模型平臺&#xff0c;企業用戶和開發者登錄即可調用AP…

CSS 用于圖片的樣式屬性

CSS 設置圖像樣式 CSS中用于圖片的樣式屬性主要包括以下幾個方面&#xff1a; ?邊框和背景?&#xff1a; ?border?&#xff1a;可以設置圖片的邊框樣式、寬度和顏色。例如&#xff0c;img { border: 1px solid #ddd; } 會給圖片添加1像素的實線邊框&#xff0c;顏色為灰色…

EasyExcel--導入和導出Excel的方法

原文網址&#xff1a;EasyExcel--導入和導出Excel的方法_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹SpringBoot整合EasyExcel導入和導出Excel的方法。 使用 Excel導入 實體類 Data public class OrderImportBO {ExcelProperty("訂單號")NotBlank(message "…

金融級安全加速:群聯SD-WAN如何兼顧防御與低延遲?

一、SD-WAN的核心價值 1. 傳統回源痛點 暴露風險&#xff1a;公網回源可能泄露源站IP&#xff0c;易遭針對性攻擊。延遲抖動&#xff1a;跨國業務因網絡擁堵導致延遲波動&#xff08;如金融交易超時&#xff09;。 2. 群聯方案優勢 加密專線&#xff1a;通過IPSec/SSL VPN建…

Apache Tomcat漏洞公開發布僅30小時后即遭利用

近日&#xff0c;Apache Tomcat曝出一項安全漏洞&#xff0c;在公開發布概念驗證&#xff08;PoC&#xff09;僅30小時后&#xff0c;該漏洞即遭到攻擊者利用。這一漏洞編號為CVE-2025-24813&#xff0c;主要影響以下版本&#xff1a; 1. Apache Tomcat 11.0.0-M1 至 11.0.2 …

計算機體系結構作業2

1 P108 有一條動態多功能流水線由5段組成(如圖3.35所示),加法用1、3、4、5段,乘法用1、2、5段,第2段的時間為2△t,其余各段的時間均為△t,而且流水線的輸出可以直接返回輸入端或暫存于相應的流水寄存器中。若在該流水線上計算 ∑ i 4 ( A i B i ) \sum_i^4(A_iB_i) ∑i4?(Ai…

python-leetcode 60.分割回文串

題目&#xff1a; 給定一個字符串S,請將S分割成一些子串&#xff0c;使每個子串都是回文串&#xff0c;返回S所有可能的分割方案 方法一&#xff1a;回溯深度優先搜索 1. 主要思想 使用 深度優先搜索&#xff08;DFS&#xff09; 遍歷 s 的所有可能劃分方式。使用 回溯&…

Java EE 進階:MyBatis

MyBatis是一個優秀的持久化框架&#xff0c;用于簡化JDBC的開發。 持久層就是持久化訪問的層&#xff0c;就是數據訪問層&#xff08;Dao&#xff09;&#xff0c;用于訪問數據庫的。 MyBatis使用的準備工作 創建項目&#xff0c;導入mybatis的啟動依賴&#xff0c;mysql的驅…

Go語言的基礎類型

一基礎數據類型 一、布爾型&#xff08;Bool&#xff09; 定義&#xff1a;表示邏輯真 / 假&#xff0c;僅有兩個值&#xff1a;true 和 false內存占用&#xff1a;1 字節使用場景&#xff1a;條件判斷、邏輯運算 二、數值型&#xff08;Numeric&#xff09; 1. 整數類型&…

【愚公系列】《高效使用DeepSeek》019-外語學習

??【技術大咖愚公搬代碼:全棧專家的成長之路,你關注的寶藏博主在這里!】?? ??開發者圈持續輸出高質量干貨的"愚公精神"踐行者——全網百萬開發者都在追更的頂級技術博主! ?? 江湖人稱"愚公搬代碼",用七年如一日的精神深耕技術領域,以"…

發布第四代液晶電視,TCL引領全新美學境界

在不斷革新的消費電子領域中&#xff0c;電視行業在視覺體驗上正面臨重要的美學挑戰。如何打破全面屏時代的物理束縛&#xff0c;將家居空間提升到“視覺無界”的層次&#xff0c;以及如何讓尖端技術更好地服務于影像沉浸感&#xff0c;成為行業關注的焦點。 3月10日&#xff…

劍指 Offer II 113. 課程順序

comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20113.%20%E8%AF%BE%E7%A8%8B%E9%A1%BA%E5%BA%8F/README.md 劍指 Offer II 113. 課程順序 題目描述 現在總共有 numCourses 門課需要選&#xff0c;記為 0 到 n…

【C++】STL庫面試常問點

STL庫 什么是STL庫 C標準模板庫&#xff08;Standard Template Libiary&#xff09;基于泛型編程&#xff08;模板&#xff09;&#xff0c;實現常見的數據結構和算法&#xff0c;提升代碼的復用性和效率。 STL庫有哪些組件 STL庫由以下組件構成&#xff1a; ● 容器&#xf…

【問題解決】Postman 測試報錯 406

現象 Tomcat 日志 org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.logException Resolved org.springframework.web.HttpMediaTypeNotAcceptableException: No acceptable representation HTTP狀態 406 - 不可接收 的報錯&#xff0c;核心原因 客…

第3節:AWK的特點和優勢

1 第3節&#xff1a;AWK的特點和優勢 AWK是一種功能強大的文本處理工具&#xff0c;具有以下特點和優勢&#xff1a; 1.1.1 簡潔性 AWK的語法簡潔明了&#xff0c;對于簡單的數據處理任務&#xff0c;通常只需編寫簡短的命令即可完成。例如&#xff0c;要從一個文本文件中提…

Flutter 打包 ipa出現錯誤問題 exportArchive

一、錯誤信息: Encountered error while creating the IPA: error: exportArchive: "Runner.app" requires a provisioning profile with the Push Notifications feature. Try distributing the app in Xcode: open /project/your_app/build/ios/archive/Runner.…

STC89C52單片機學習——第28節: [12-2] AT24C02數據存儲秒表(定時器掃描按鍵數碼管)

寫這個文章是用來學習的,記錄一下我的學習過程。希望我能一直堅持下去,我只是一個小白,只是想好好學習,我知道這會很難&#xff0c;但我還是想去做&#xff01; 本文寫于&#xff1a;2025.03.20 51單片機學習——第28節: [12-2] AT24C02數據存儲&秒表&#xff08;定時器掃…