我們在講到的時候,內文提到了一個
按照 vim help 上面的說明,vim 提供的 registers(暫存器)有下列幾種:
- The unnamed register “”
- 10 numbered registers “0 to “9
- The small delete register “-
- 26 named registers “a to “z or “A to “Z
- four read-only registers “:, “., “% and “#
- the expression register “=
- The selection and drop registers “*, “+ and “~
- The black hole register “_
- Last search pattern register “/
雖然看上去有九種之多,但經常會用的並不多。
在 vim 裡面,為了方便使用者可以少打點之前已經打過的字串,或是因為某些理由,設置了因應不同需求的暫存空間,而且這些暫存空間其實都是有它的意義存在。舉例來說,像前面說的
Register 0:
讓我們來想像一個情境:
當你會使用選擇模式(visual mode)或是用 yank的方式(vy)把該區域貼上,當你要用的時候,很自然地你會使用 p 這個指令把你要的東西貼上。
但是往往在編輯的時候,打錯一些東西,你就刪除 了某些字或行。真糟,如果你再用 p ,那麼貼上的就是你剛剛刪掉的那些字或行。如果我要用剛剛 yank 或是進 visual mode 所 copy 的東西怎麼辦?難道還要再一次?真麻煩…
別耽心, register 0 就是幫你把最近一次做 yank 動作所存進去的東西。所以如果你還要用到剛剛才 yank 的東西,那你只要按下
“0p
就代表要貼上最近一次 yank 的東西。
Registers [1-9] :
那 “[1-9]這些這些暫存器的功能又和 0 不一樣。[1-9]他們之間的關係是當你刪了某些字行的時候,這個被刪的字或行,會進入 “1 這個 register ,當你又刪了的時候,這次被刪的東西的會進入 “1 ,那原來在 “1 的東西就會被放到 “2 去。依此類推。那這個有什麼用呢?因為我怎麼可能會去記我第幾次刪掉的東西會是什麼?沒關係,這裡有個小指令,可以讓你看到那些 register 裡面到底放了什麼?
:di
這就會把所有 register 到底放些什麼東西秀出來給你看。如果你懶得去 :di 一個個看的話,也有別的方法,就是直接貼出來看:
“1p
你會想,這很直覺啊。但是你發現它不是你要的東西的時候怎麼辦?直覺的想法是 u ,我 undo 就好了嘛。問題是,要貼出下一個暫存器內容的時候你打算怎麼辦? “2p 嗎?非也。而是「 . 」,當你按下「 . 」的時候 vim 就會把 “2 的內容貼出來,依此類推,只要東西真的存在你的”[1-9] 暫存器裡面,你就一定會找到它。好吧,這個有點奇技淫巧了,因為你可能願意用 :di 看了之後再貼。
其他的 registers:
而 a-z A-Z 這些 reigster 是你指定才會用到的東西。什麼意思呢?也就是說你必須指定暫存器[a-zA-Z]和要放進去的內容才會在 :di 中出現。
一個簡單的指定方法像是在 command line 下打:
:let @a=”Hello, world”
則 “a 這個 register 就會被放入 Hello, world 這個字串。所以如果你想把某個暫存器裡面資料清除掉的話,也可以用:
:let @a=”"
你也可以像之前我們在談的 visual mode,選取範圍之後指定暫存器 “[0-9a-z] 來存放。不過由於 “[0-9] 有特殊的關係,可能會被覆蓋,所以我個人會建議你使用 “[a-z]。
或許細心的讀者會發現不是明明可以指定 [a-zA-Z] 嗎?為什麼這邊只談到 [a-z]?這是因為大寫的 [A-Z]有特殊的意義。
當你指定 “[a-z] 暫存器來使用的時候,事實上是把指定的內容覆蓋上去。但是如果你想要的是附加而不是覆蓋呢?那就得使用 “[A-Z] 了。比方說,我們之前的時候,有提到怎麼樣只顯示出包含搜尋字串的行。可是如果你想要把這些東西放進去暫存器留待下次使用的話怎麼辦?
一般來說 :g 的運作方式是根據一行一行來做的,簡單地說,當你用下面指令的時候,
:g/pattern/y a
這代表的意思其實只是把每次比對到的那行都 yank 複製到 “a 這裡面去。所以這就會造成我們最後只會拿到最後一行的結果,而不是每個比對到的都會進入到 “a 去。所以就必須告訴 vim 我們指定的內容是要做附加而不是覆蓋:
:g/pattern/y A
附帶一提:所以如果你想要把這些東西寫到某個檔案去可以這樣寫:
:g/pattern/. w >> filename
基本上你可以指定暫存器內容的有 [1-9a-zA-Z] 這些,其他的有些也可以,像是 0 ,但是因為這類暫存器都有它的特殊功用,所以我不太建議你指定內容給他們。
回到暫存器存在的目的,其實就是為了讓大家少打一些字。像是如果我今天從某個地方 copy 複製了一段文字,想要放到 vim 現在正在編輯的文件裡面。在 windows 上的 vim 你可以用幾種方法,第一個很簡單就是用 gvim ,用滑鼠按貼上的按鍵,另外一個就是用 windows 的熱鍵
“*p
就可以把剛剛的部分換成在系統「剪貼簿」裡面的東西。
如果你是在編輯模式下的話,「“*」這些字都會被打出來,所以就必須透過
*
來把內容叫出來。所以到這裡不必我說,你也知道 “* 指的就是系統「剪貼簿」裡面的內容。另外像是 “: 就是指打的命令的暫存器,同樣之前提過的 “/就是放搜尋的字串。其他像是 “. 放最近 insert 插入的文字,“- 放砍掉但不超過一行的文字,或是 “% 指現在編輯的檔名,都不見得常用。雖然有時候如果你想存個現在檔案的備份可以這樣寫而少打幾個字:
:w %.bak
不過有個東西可以稍微提一下,就是 “_ (黑洞暫存器),如果你刪除的動作不想要牽涉到任何暫存器的話,那你就可以用 “_。比方我可以用:
v”_x
就不會改到其他的暫存器。
如果你對其他的暫存器或是想知道更詳盡的資料可以打
:h registers