Vim 進階 - 剪切(刪除)、複製、粘貼與寄存器

Vim 和其它編輯器同樣,也有剪切、複製、粘貼等操做,可是在 Vim 中這些操做都有不一樣的名字:刪除 delete、複製 yank、粘貼 put。segmentfault

通常的編輯器在進行復制、剪切等操做時,會使用操做系統的剪貼板 clipboard 來暫時存儲文本,而 Vim 的「剪貼板」和系統的剪貼板並不互通,Vim 使用內建的「寄存器 register」來保存文本。編輯器

剪切(刪除)、複製、粘貼操做

剪切(刪除)Delete

在其餘編輯器中,剪切通常表明着刪除一段文本的同時,將這段文本保存到剪貼板中,以便在其餘地方粘貼出來。而在 Vim 當中,剪切和刪除並無明顯的界限,由於在 Vim 中,全部被刪除的文本都會被放到寄存器中,這樣咱們在下次想使用的時候能夠直接粘貼。操作系統

具體放到哪一個寄存器裏了,以及寄存器的操做方法,咱們稍後再說。先來看看 Vim 中和剪切 / 刪除相關的命令:code

命令 用途
c{motion} 刪除字符並進入插入模式
cc 刪除整行並進入插入模式(=== S
C 從光標處刪除到行尾並進入插入模式
d{motion} 刪除字符並進入插入模式
dd 刪除整行
D 清除當前行的全部字符(不會刪除行)
s 刪除光標下的字符並進入插入模式
S 刪除整行並進入插入模式(=== cc
x 刪除光標下的字符
X 刪除光標前面的字符

在 Vim 裏,c 表明 change,d 表明 delete。ip

簡單來說,cs 相關的命令在刪除字符後會進入插入模式,而 dx 在刪除以後會留在普通模式。cd 能夠刪除成段字符,而 sx 只刪除一個字符。ci

c{motion}d{motion} 中的 {motion} 表明動做命令,關於動做命令的更多內容能夠參考這一篇。例如:ciw - 刪除當前單詞並進入插入模式,dt" - 刪除到 " 前邊,di] - 刪除 [] 內包括的內容,等等。開發

除動做命令外,也可以使用可視模式選中文本後用 cd 進行刪除。get

另外,還有方便的 ccdd 命令能夠用來直接刪除整行。io

複製 Yank

在 Vim 中,yank 表明複製。Yank 原本的意思是拉起、拉出。使用 yank 表明複製主要是由於在 Vim 開發的時候 c 已經被 change 佔用了,因此只能用還空餘的 y 了。table

y 命令的使用方式和 cd 相似,y{motion} 能夠對複製相應文本,也能夠在可視模式下選中文本後用 y 複製。

ccdd 相似,yy 能夠複製整行。

粘貼 Put

p 能夠把剛剛刪除 / 剪切 / 複製的文本放(put)在光標後面。若是是整行的文本,則放在光標下面的行。而 P 是放在前 / 上面。

在可視模式下,p 會在粘貼的同時替換選中的文本。

此外,還有 gpgP 命令,和 p P 不一樣的是,前兩個命令會在粘貼以後,把光標的位置移到文本的結尾而不是開頭。

寄存器 Register

看到這裏,咱們已經學到刪除 / 剪切 / 複製的一些一本操做,能應付不少平常場景了。

可是設想這樣的場景:

我想複製一處的文本 a,並替換另外一處的文本 b。我用 y 複製了文本 a,而後把光標移動到文本 b 上,選中或者使用動做命令搭配 d 刪除了文本 b,而後按 p

奇怪的事情發生了,咱們獲得的並非文本 a,而是把文本 b 粘貼(put)了出來。糟糕,我把複製的內容弄丟了!

固然你可能會說,複製文本 a 以後,選中文本 b 而不刪除,直接用 p 便可完成替換。確實如此,這也是我更傾向的操做,它不會既複製又刪除,只用兩步操做就完成了替換。

而要弄懂爲何會 put 出文本 b,就要了解寄存器的概念。

什麼是寄存器

通常來說,操做系統的剪貼板只有一個,後來的會覆蓋先來的。新的內容被存到剪貼板的同時,老的內容也會被刪除。

Vim 的寄存器不太同樣,寄存器有不少個,能夠經過 "{reg} 的方式指明要使用的寄存器。其中," 用來告訴 Vim,要進行和寄存器有關的操做,而 {reg} 表明寄存器的名字。

寄存器的名字能夠是 [a-z0+"*#%.:/] 等,其中 [a-z] 共 26 個可供咱們隨意使用,另外的那些是 Vim 內置的專用寄存器。

使用寄存器

使用 "{reg} 加命令能夠指明咱們想要使用的寄存器,例如 "ep - 粘貼寄存器 e 中的內容,"fdd - 刪除當前行並放到 f 寄存器中,等等。

無名寄存器(默認)""

當沒有指定要使用的寄存器時,Vim 會使用無名寄存器 ""

前面提到,cdsxy 命令都會將相應的文本放到寄存器中,而沒有聲明 [a-z] 中的某一個時,這段文本就會被放到默認的寄存器 "" 中。而當咱們使用 p 進行粘貼的時候,也會讀取 "" 中的內容。

這就是糟糕,我把複製的內容弄丟了! 的緣由。當咱們執行刪除操做的時候,刪除的文本替換了 "" 中的內容,也就是咱們剛剛複製的文本 a。

因此,正如咱們剛剛提到的,在 Vim 當中剪切和刪除並無清晰的界限,被刪掉的文本也會默認被放到無名寄存器 "" 中,而這有可能會覆蓋咱們剛剛複製的內容,在使用的時候必定要注意這一點。

固然,咱們也能夠利用 Vim 的這個特色。例如:

xp 能夠刪除光標下的字符再把它放到光標後面,也就是交換了光標下面兩個字符的位置

ddp 能夠刪除當前行,並把這行粘貼在光標下面,也就是交換了光標下面的兩行

有名寄存器 "[a-z]

Vim 提供了完整的 26 個英文字母供咱們命名寄存器,這意味着咱們能夠同時剪切/複製 26 段文本。

使用大寫字母命名寄存器,會將相應的內容添加到相對應的小寫字母命名的寄存器後面。

複製專用寄存器 "0

當使用 y 進行復制時,複製的文本不只會被存進無名寄存器 "",也同時會被存進 "0,而 cdsx 均不會覆蓋這個寄存器。只有當咱們下一次複製的時候,這個寄存器纔會被覆蓋。

因此,也可使用這個寄存器來規避糟糕,我把複製的內容弄丟了! 的問題。

系統剪貼板寄存器 "+

前面提到 Vim 使用的寄存器和操做系統的剪貼板是相互隔離的,可是這個隔離也不絕對,使用 "+ 寄存器能夠和系統剪貼板進行交互,例如,咱們能夠經過 "+p 粘貼系統剪貼板的內容,也能夠用 "+y 把內容存進系統剪貼板。這意味着咱們能夠在 Vim 中直接複製文本,而後到其餘程序中粘貼。

其餘

此外,Vim 還提供了一些其餘的寄存器供咱們使用,這些寄存器也被稱爲只讀寄存器:

寄存器 內容
"% 當前文件名
"# 輪換文件名
". 上次插入的文本
": 上次執行的命令
"/ 上次查找的模式
相關文章
相關標籤/搜索