天天看點

使用 Vim 寄存器(registers)和系統剪貼闆(clipboard)寄存器分類1. 匿名寄存器2. 編号寄存器3. 小删除寄存器4. 命名寄存器5. 隻讀寄存器6. 交替檔案寄存器7. 表達式寄存器8. 選擇和拖放寄存器9. 黑洞寄存器10. 搜尋寄存器指令行模式拷貝擴充閱讀

常見文本編輯器都會提供剪切闆來支援複制粘貼,Vim也不例外。 不同的是Vim提供了10類共48個寄存器,提供無與倫比的寄存功能。 最常用的

y

操作将會拷貝到預設的匿名寄存器中,我們也可以指定具體拷貝到哪個寄存器中。

一般來講,可以用

"{register}y

來拷貝到

{register}

中, 用

"{register}p

來粘貼

{register}

中的内容。例如: 

"ayy

可以拷貝目前行到寄存器

a

中,而

"ap

則可以粘貼寄存器

a

中的内容。

注:Vim的拷貝與大家預期的方式可能略有不同。拷貝指令不是大家料想的c。因為c表示“修改”,已經被占用了。Vim用拉取(yank)來表示拷貝,簡寫為y。

  • y: 拷貝選中内容
  • yy: 拷貝目前行

除了

a-z

26個命名寄存器,Vim還提供了很多特殊寄存器。合理地使用可以極大地提高效率。例如:

  • "+p

    可以粘貼剪切闆的内容,
  • ":p

    可以粘貼上一個Vim指令(比如你剛剛費力拼寫的正規表達式),
  • "/p

    可以粘貼上一次搜尋關鍵詞(你猜的沒錯,正是normal模式下的

    /foo

    搜尋指令)。

在Vim中可通過

:reg

來檢視每個寄存器目前的值。

寄存器分類

Vim提供了10類寄存器,可在Vim中通過

:help registers

檢視幫助。

  1. 匿名寄存器 

    ""

  2. 編号寄存器 

    "0

     到 

    "9

  3. 小删除寄存器 

    "-

  4. 26個命名寄存器 

    "a

     到 

    "z

  5. 3個隻讀寄存器 

    ":

    ".

    "%

  6. Buffer交替檔案寄存器 

    "#

  7. 表達式寄存器 

    "=

  8. 選區和拖放寄存器 

    "*

    "+

    "~

  9. 黑洞寄存器 

    "_

  10. 搜尋模式寄存器 

    "/

1. 匿名寄存器

使用

d

c

s

x

等會删除字元的指令時,被删除字元會進入匿名寄存器

""

。 你可以認為

""

寄存器是一個指針,指向剛才被存到的寄存器。

在如何用Vim搭建IDE?一文中提到,Mac下可通過下列設定來讓Vim共享系統剪切闆, 就是這個原理:所有删除和拷貝操作預設都會到匿名寄存器。

set clipboard=unnamed
           

使用

y

指令未指定寄存器會存到

"0

寄存器中,同時

""

會與該寄存器保有同樣的值。 這意味着你使用

p

"p

總會得到同樣的結果。

2. 編号寄存器

編号寄存器從

"0

"9

共10個,其中

"0

儲存着拷貝來的字元串,

"1

"9

儲存着删除掉的字元串。 删除操作符包括

s

c

d

x

。 删除掉的字元串會被存到

"1

中,上次删除的則會被存到

"2

中。以此類推,Vim會儲存你最近的9次删除。

  • 隻有整行整行的删除,和通過段落級别的移動指令(包括

    %,(,),/,`,?,n,N,{,}

    ) 的删除才會被放到

    "1

    中。
  • 當使用者指定拷貝操作的寄存器時(如

    "ap

    ),

    "0

    不會被寫入;但删除操作一定會被寫入到

    "1

    中。

"0

寄存器很有用,比如我們copy了一段文本然後用它替換另一段文本。 這時預設寄存器

""

中的值就變成了被替換文本,如果還需要用copy的文本繼續替換的話就需要

"0p

了。

3. 小删除寄存器

不足一行的小删除則會被放到小删除寄存器中(

"-

),起作用的删除操作符也包括

s

c

d

x

。 例如:

dw    # 删除一個詞
d9l   # 删除9個字元
cb    # 向前更改一個詞
           

"0

寄存器類似,當使用者指定寄存器并進行删除時,

"-

不會被寫入。

4. 命名寄存器

命名寄存器有

"a

"z

共26個,這些寄存器隻有當我們指定時才會被使用。 其實我們在錄制宏時,所有鍵盤操作會以字元串的形式存到寄存器中。 例如錄制一個宏存到

"a

寄存器中,内容為更改目前行

cc

,改為

foo

字元串:

qaccfoo
           

然後執行

:reg

來檢視寄存器,可以發現

a

寄存器的值是

ccfoo

小技巧:當使用小寫字母進行操作時會覆寫目前寄存器内容,當使用大寫字母進行操作時,會追加目前寄存器内容。

5. 隻讀寄存器

隻讀寄存器共3個,它們的值是由Vim提供的,不允許改變:

  • ".

    :上次insert模式中插入的字元串。還記得嗎?

    .

    指令可以重複上次操作,而

    ".

    存儲了上次插入。
  • "%

    :目前檔案名,不是全路徑,也不是純檔案名,而是從目前Vim的工作目錄到該檔案的路徑。例如此時Harttle的Vim中,

    "%p

    的結果為

    _drafts/vim-registers.md

  • ":

    :上次指令模式下鍵入的指令。正如

    @a

    可以執行

    "a

    寄存器中的宏一樣,

    @:

    可以執行上次指令。

6. 交替檔案寄存器

交替檔案寄存器

"#

存儲着目前Vim視窗(Window)的交替檔案。交替檔案(alternate file)是指 Buffer中的上一個檔案,可通過

Ctrl+^

來切換交替檔案與目前檔案。

Window和Buffer有什麼差別?參見Vim 多檔案編輯:視窗一文。

7. 表達式寄存器

表達式寄存器

"=

主要用于計算Vim腳本的傳回值,并插入到文本中。 當我們鍵入

"=

後光标會移動到指令行,此時我們可以輸入任何Vim腳本的表達式。 例如

3+2

,按下回車并且

p

則會得到

5

這在我們調試Vim腳本時非常有用,比如調用一個函數看它是否有正确的傳回值。

8. 選擇和拖放寄存器

選擇和拖放寄存器包括

"*

"+

, 和

"~

,這三個寄存器的行為是和GUI相關的。

"*

"+

在Mac和Windows中,都是指系統剪貼闆(clipboard),例如

"*yy

即可複制目前行到剪貼闆。 以供其他程式中粘貼。其他程式中複制的内容也會被存儲到這兩個寄存器中。 在X11系統中(絕大多數帶有桌面環境的Linux發行版),二者是有差別的:

  • "*

    指X11中的PRIMARY選區,即滑鼠選中區域。在桌面系統中可按滑鼠中鍵粘貼。(滑鼠中鍵即滑鼠中間的滑輪)
  • "+

    指X11中的CLIPBOARD選區,即系統剪切闆。在桌面系統中可按Ctrl+V粘貼。
上文所述的Mac下

set clipboard=unnamed

會使得系統剪切闆寄存器

"*

和Vim預設的匿名寄存器

""

始終保有同樣的值,即Vim和系統共用剪切闆。

有文本拖拽到Vim時,被拖拽的文本被存儲在

"~

中。Vim預設的行為是将

"~

中内容插入到光标所在位置。 當然你可以給

<DROP>

做鍵盤映射。

9. 黑洞寄存器

黑洞寄存器

"_

,所有删除或拷貝到黑洞寄存器的文本将會消失。 這是為了在删除文本的同時不影響任何寄存器的值,

"_

通常用于Vim腳本中。

10. 搜尋寄存器

搜尋寄存器

"/

用于存儲上一次搜尋的關鍵詞。Vim中如何進行搜尋呢? 在normal模式下按下

/

即進入search模式,輸入關鍵字并按下回車即可。

該寄存器是可寫的,例如

:let @/ = "harttle"

将會把

"harttle"

寫入該寄存器。 下次搜尋時不輸入搜尋詞直接回車便會搜尋

"harttle"

指令行模式拷貝

值得一提的時,任何寄存器中的值都是可以拷貝到指令模式下的。

比如對于寄存器

"a

中的值,在normal模式下可以通過

"ap

來粘貼;在command-line模式下通過

<Ctrl-R>a

來粘貼。這一操作存在風險,因為寄存器中的值可能是從網頁中拷貝來的。

如果寄存器中的字元串存在

<Esc>

字元或

<CR>

字元,則會時Vim回到normal模式, 并繼續執行寄存器中的指令。為了防範剪切闆劫持,可以添加下列的Vim配置:

inoremap <C-r>+ <C-g>u<C-\><C-o>"+gP
           
該指令的解釋請移步:http://vim.wikia.com/wiki/Pasting_registers

擴充閱讀

  • 剪切闆與X11選區:http://stackoverflow.com/questions/11489428/how-to-make-vim-paste-from-and-copy-to-systems-clipboard
  • Vikia-Pasting Registers: http://vim.wikia.com/wiki/Pasting_registers
  • Vim Help: 

    :help registers

    :help quotestar

    :help quoteplus

本文采用 知識共享署名 4.0 國際許可協定(CC-BY 4.0)進行許可。轉載請注明來源: https://harttle.land/2016/07/25/vim-registers.html 歡迎對文中引用進行考證,歡迎指出任何不準确和模糊之處。可以在下面評論區評論,也可以郵件至 [email protected]。

繼續閱讀