Vim 中的寄存器
計算機中通常所說的寄存器 Register 一般指的是 CPU 中的寄存器,用來暫存 CPU 處理所需要的指令,數據等等。 Vim 中同樣也有寄存器的概念,使用的方式和概念也和 CPU 是非常類似的。
Vim 的寄存器可以看成 Vim 中額外用來存儲信息的區(qū)域,雖然看不見,但是如果使用 x, s, y, p 等等命令的時候都無意識的使用到了 Vim 的寄存器 (register).
本文轉載至github vim 寄存器
Vim 中每一個 register 都可以通過添加雙引號的方式來訪問,比如 "a 來訪問 a 寄存器。
可以通過選擇然后使用 y 來將內容放到寄存器中,比如 "ay 來將選擇的內容 yank 復制到 "a 寄存器。 可以使用 "ap 來粘貼 a 寄存器中的內容。
同樣可以再 Insert mode 下使用寄存器名字來插入。這會將寄存器內容粘貼進當前編輯位置。
可以使用 :reg 命令來查看所有寄存器及其內容,或者直接在后面添加寄存器名字來查看關心的內容 :reg a b c
:reg a b c
--- Registers ---
"a register a content
"b register b content
"c register c content
默認寄存器
Vim 有自己的 unnamed (無名寄存器)或者說默認寄存器,可以通過 "" 來訪問。任何被 d, c, s, x 刪除或者 y 復制的內容都會被存放在該寄存器中,使用 p 粘貼時也是中該寄存器中粘貼內容。直接使用 p 其實等效于 ""p 。
有名寄存器
Vim 提供 26 個英文字母命名的有名寄存器 (:h quote_alpha)。這就意味著可以
- 剪切
"ad{motion} - 復制
"ay{motion} - 粘貼
"apor"aP
多達 26 段文本。
數字寄存器
當使用 yank 復制一些內容,然后又執(zhí)行了 d 命令,會發(fā)現粘貼時,當時 yank 的內容被 d 命令中的內容替換了,這是 Vim 非常常見的一個問題,然而問題并不在 Vim,而是 Vim 把 yank 的內容 ,delete 的內容都放到了 unnamed register 中了,但是復制的內容并沒有丟失,并不需要再次回到想要復制的地方再次 yank 一遍。
這里就要介紹 Vim 的另外一種寄存器 —- 數字寄存器 numbered registers , 正如他的名字一樣,數字寄存器的名字就是 "0 到 "9 。
"0 寄存器永遠保存著 yank 的最新內容,其他寄存器保存這歷史 9 個內容,從 1 到 9 從新到老。如果復制了新的文字,永遠可以通過 "0p 來粘貼。
事實上不僅 yank 的內容在 "" 中,x, s,c{motion}, d{motion} 命令操作的內容都會在該寄存器中保存。
復制專用寄存器
正因為所有的 yank 內容都會自動被保存在 "0 寄存器中,所以數字寄存器 "0 也被稱為 yank register.
只讀寄存器
Vim 中有四個只讀寄存器 "., "%, ":, "# .
最后插入文本 last inserted text “.
最后插入的文字被保存在 ". 中,如果想要在其他地方使用剛剛輸入的文字,非常方便。
當前文件名 name of the current file “%
"% 保存 Vim 最早開始打開時,當前文件的完整路徑。最常用的組合就是將當前的路徑放到粘貼板
:let @+=@%
let 命令用來向寄存器寫入, "+是粘貼板寄存器,將 "% 內容寫入粘貼板
最后執(zhí)行的 Ex 命令 last Ex command “:
": 是最近執(zhí)行命令寄存器。如果最近保存過文件 :w ,那么 Ex 命令 w 會保存在寄存器中??梢允褂?@: 來執(zhí)行前一次命令。再比如使用替換命令替換了一行中的內容 :s/foo/bar ,那么將光標移動到另一行再次使用 @: 就能夠再次替換。
輪換文件名 name of the alternate file “#
"# 保存 alternative file 名字。大致可以理解為 Vim 中編輯的上一個文件,可以通過 :h alternate-file 來查看更多。當使用 Ctrl + ^來切換文件時,使用的就是這個寄存器保存的文件名。同樣可以使用 :e Ctrl-r # 來做同樣的事情。不常用。
表達式寄存器
"= 用來處理表達式結果,如果在 Insert Mode 使用 Crtl + r + =,然后輸入 2+2<Enter> ,結果 4 會顯示出來。也可以用來執(zhí)行外部命令,比如 Ctrl - r = 之后輸入 system('ls') <enter> 來顯示 ls 的結果。
搜索寄存器
"/ 這個寄存器保存最近搜索過的內容,包括 /, ?, *, # 的內容。比如說最近搜索過 /example ,想要替換成 another, 可以使用
:%s/<Ctrl-r/>/another/g
輸入 :%s/ 只有按下 Ctrl + r 再按 / 會自動插入寄存器保存的內容。
搜索寄存器也是可以寫的,可以使用 let 命令寫入:
:let @/="keywords"
寄存器和宏 Macro 的關系
或許很多不熟悉 Vim 寄存器的用戶曾經使用過 Vim 的 Macro, Vim 可以使用 Macro 來錄制一連串命令,然后重復。(可以使用 :h recording 來查看更多)。
Vim 使用寄存器來保存 Macro 的命令。比如使用 qw 來錄制 Macro ,寄存器 "w 會被用來記錄所有錄制的內容,所有的內容都有文本的形式存放。
更加 Cool 的事情就是,因為所有的內容都以文本的形式存在寄存器中,我們可以輕易的修改其中的內容,而不至于因為一個疏忽錄制錯誤,而重新錄制整個操作。
比如忘記了給文字最后添加分號,可以
:let @W='i;'
來修改錄制的內容,注意 W 是大寫,這是追加到寄存器的意思,插入 i; 進入插入模式并輸入 ; 。
再比如如果需要直接修改 register 的內容,可以使用
:let @w='<Ctrl-r w>
然后修改需要修改的內容,然后以 ' 結束。
另外一個 Cool 的事情就是,因為所有的命令都是以文本的形式保存的,所以可以輕易的將錄制的 macro 移動到另外的寄存器中,或者將錄制的 macro 分享給其他人。
比如將錄制在 w 寄存器中的內容復制給粘貼板寄存器,然后就能在其他 Vim 中使用。
黑洞寄存器
黑洞寄存器 "_ 放入該寄存器的內容都會被吞噬掉,不會有任何返回。所以不想污染 yank register 的時候可以手動的將內容導入到該寄存器中,比如數字 0 寄存器已經有了想要粘貼的內容,這時想要刪除一些內容,粘貼數字 0 寄存器中的內容,那么就可以:
"_diw
刪除該單詞,并將內容放到 black hole register 中,再使用
P
來粘貼即可。
系統(tǒng)粘貼板
系統(tǒng)粘貼板寄存器 "+ 當 Vim 要和外部程序或者系統(tǒng)交互時用那些 Vim 自身的寄存器就不管用了,Vim 的 plus register 指向的是系統(tǒng)粘貼板,用 "+ 來表示。
如果想要在 Vim 中粘貼系統(tǒng)剪貼板內容,那么需要使用 "+p (或者在插入模式下 <C-r>+ ).
反之如果要 yank 或者 delete 內容到粘貼板需要使用 "+
在 X11 系統(tǒng)中還有一個粘貼板,被稱為 primary, 所以 Vim 對應一類寄存器 "* ,一般被鼠標中間按鍵使用。
在 Windows 和 Mac OS 中沒有 primary clipboard 所以 "+ 和 "* 可以混用。
Vim 可以在編譯時選擇是否支持 X11 粘貼板,可以使用 :version 來查看 xterm_clipboard 查看是否支持。如果前綴是一個 - 減號,那么表示該版本的 Vim 不支持該特性。+ 加號表示支持特性。
將內容復制到指定寄存器
看到上面這么多寄存器,不免就要思考,不如想要把當前單詞復制到指定的寄存器中該怎么辦。其實非常簡單,在命令前加上寄存器的名字,比如要將單詞保存到寄存器 "a
"ayiw
或者復制該行到寄存器 b
"byy
如果要將寄存器內容粘貼到文本,可以
"ap
除了上面普通模式的命令,Vim 也有刪除、復制與粘貼的 Ex 命令,比如將當前行剪切到寄存器 c
:delete c
將寄存器內容粘貼到當前光標所在行
:put c
總結
Vim 中的寄存器一共分為 9 大類:
- The unnamed register
“” - 10 numbered registers
“0to“9 - The small delete register
“- - 26 named registers “a to
“zor“Ato“Z - four read-only registers
“:,“.,“%and“# - the expression register
“= - The selection and drop registers
“*,“+and“~ - The black hole register
“_ - Last search pattern register
“/
其中大部分的寄存器上文都有涉及,其中為涉及到的 selection and drop registers 和 GUI 中選取的內容有關系。
black hole register 是一個黑洞寄存器,當寫入 black hole register 時,nothing happens . 像黑洞一樣吞掉所有的輸入,可以用來在大量刪除文本時不影響任何寄存器。