下面是一篇舊文,大多是一些已有知識的整理,并不太成熟。歡迎關(guān)注專欄 space-vim , 有空我會以 Vim 自帶的 help
(不妨 :help help
看一下) 為線索, 分享一些關(guān)于 Vim 的小知識 ,也會順帶著介紹一下 space-vim 的配置與用法。
vim概覽
-
vim的命令有如下特點:
- 字母大小寫有區(qū)別(大寫與小寫表示不同的意義,I與i功用不同)。
- 在輸入時不會顯示在屏幕上。
- 不需要在命令后加上 <code>enter</code> 鍵。
運作模式
當(dāng)前 "模式(mode)" 的概念對 vim 的運作是最基礎(chǔ)的。模式有兩種: 命令模式 (command mode) 與插入模式 (insert mode) .一開始是命令模式,此時所有的按鍵都代表命令;而在插入模式中,你輸入的東西都成為文件的內(nèi)容。
vim 命令的一般形式
如果對于 vim 不是一個完全的新手,大概能夠發(fā)現(xiàn)大部分 vim 命令具有以下模式:<code>(command)(text object)</code>.對于更改命令(change)c ,command 部分就是指c,text object (文本對象) 則是光標(biāo)移動命令(輸入時不需要加上括號)。刪除命令 d (delete)、復(fù)制命令y(yank) 同樣適用這種形式。
另外,text object(光標(biāo)移動命令)可使用數(shù)值參數(shù),因此可將數(shù)值加在 c、d、y 等命令的文本對象上。例如 d2w 與 2dw 都是刪除兩個單詞的命令。在了解這一點后,其實大部分vim命令都遵循如下模式: <code>(command)(number)(text object)</code> 或者其等效模式: <code>(number)(command)(text object)</code>. 它們的工作方式是這樣的:number 與 command 為可選項。如果沒有這兩部分,只是單純的光標(biāo)移動命令;如果加上 number,則出現(xiàn)移動多次的效果;結(jié)合command(c、d、y等等)與 text object, 則會得到編輯命令。
當(dāng)你認(rèn)識到這些組合的多樣性后,vim就成為有強(qiáng)大威力的編輯器了!
按詞性劃分
動詞
動詞代表了我們打算對文本進(jìn)行什么樣的操作。例如:
- d 表示刪除(delete)
- r 表示替換(replace)
- c 表示修改(change)
- y 表示復(fù)制(yank)
- v 表示選取(visual select)
介詞
名詞代表了我們即將處理的文本。Vim 中有一個專門的術(shù)語叫做文本對象(text object),下面是一些文本對象的示例:
- w 表示一個單詞(word)
- s 表示一個句子(sentence)
- p 表示一個段落(paragraph)
- t 表示一個 HTML 標(biāo)簽(tag)
- 引號或者各種括號所包含的文本稱作一個文本塊。
介詞
介詞界定了待編輯文本的范圍或者位置。例如:
- i 表示“在…之內(nèi)”(inside)
- a 表示“環(huán)繞…”(around)
- t 表示“到…位置前”(to)
- f 表示“到…位置上”(forward)
下面是幾個有關(guān)范圍的示意圖,你們感受一下:
組詞為句
有了這些基本的語言元素,我們就可以著手構(gòu)造一些簡單的命令了。文本編輯命令的基本語法如下:動詞 (介詞) 名詞
, 其中介詞并非必要.
下面是一些例子(如果熟悉了上面的概念,你將會看到這些例子非常容易理解),請親自在 Vim 中試驗一番。
# 刪除一個段落: delete inside paragraph
dip
# 選取一個句子: visual select inside sentence
vis
# 修改一個單詞: change inside word
ciw
# 修改一個單詞: change around word
caw
# 刪除文本直到字符“x”(不包括字符“x”): delete to x
dtx
# 刪除文本直到字符“x”(包括字符“x”): delete forward x
dfx
數(shù)詞
數(shù)詞指定了待編輯文本對象的數(shù)量,從這個角度而言,數(shù)詞也可以看作是一種介詞。引入數(shù)詞之后,文本編輯命令的語法就升級成了下面這樣:動詞 (介詞/數(shù)詞) 名詞
下面是幾個例子:
# 修改三個單詞:change three words
c3w
# 刪除兩個單詞:delete two words
d2w
另外,數(shù)詞也可以修飾動詞,表示將操作執(zhí)行 n 次。于是,我們又有了下面的語法: 數(shù)詞 動詞 名詞
.
請看示例:
# 兩次刪除單詞(等價于刪除兩個單詞): twice delete word
2dw
# 三次刪除字符(等價于刪除三個字符):three times delete character
3x
按操作劃分
保存退出
下列操作都是在命令行模式下,即退出操作為輸入<code>:q</code>.
- q ( quit ): 退出,如果有未保存的修改則無法退出
- q! ( force quit ): 強(qiáng)制退出
- w ( write edits to disk (save file) ): 保存文件。<code>:w FILENAME</code>即是將當(dāng)前正在編輯的文件另保存為FILENAME文件,并存儲在進(jìn)入vim的目錄下。
- w! ( force write ): 強(qiáng)制保存
- ZZ ( quit and save edits ): 保存文件并退出。等同于wq.
- e! ( revert your changes ): 回滾所有修改至原始狀態(tài),也就是說消除所有的編輯結(jié)果,回到原來的文件。
在當(dāng)前行 ( current line ) 有效的移動光標(biāo)
當(dāng)光標(biāo)從一點移動到另外一點,在這兩點之間的文本(包括這兩個點)稱作被“跨過”,這里的命令也被稱作是 motion。(簡單說明一下,后面會用到這個重要的概念)
- fx ( forword to x or find x ): 移動光標(biāo)到 當(dāng)前行 的 下一個 x 處,x 表示任意單個字符,區(qū)分大小寫。例:fa:移動光標(biāo)到當(dāng)前行的下一個字母a處。
- Fx : 同上,區(qū)別在于方向相反,移動光標(biāo)到當(dāng)前行的上一個 x 處。
- w ( word ) : 光標(biāo)向前移動一個詞。
- b ( backword ): 光標(biāo)向后移動一個詞。
- e ( end of word ) : 移動到字尾。
- 0 ( 數(shù)字0 ) : 移動光標(biāo)到當(dāng)前行首。
- $ : 移動光標(biāo)到行尾。
- ^ :移動光標(biāo)到本行第一個非blank字符處。
- g_ : 移動光標(biāo)到本行最后一個非blank字符處。
- ):移動光標(biāo)到下個句子。
- (:移動光標(biāo)到上個句子。
在整個文件 ( file ) 里有效的移動光標(biāo)
- < c-f > ( Ctrl+forward ): 向下移動整屏。
- < c-b > ( Ctrl+backward ):向上移動整屏。
- < c-d > ( Ctrl+down ) : 向下移動半屏。
- < c-u > ( Ctrl+up ) : 向上移動半屏。
- zz : 使光標(biāo)所在的行成為屏幕的中間行。
- <code>enter</code> : 使光標(biāo)移動到下一行的第一個字符。
- + :同<code>enter</code>.
- - : 使光標(biāo)移動到上一行的第一個字符。
- gg ( go ): 移動光標(biāo)到文件首。
- G :移動光標(biāo)到文件尾。
- numgg ( num go go ) : 移動光標(biāo)到指定行即num行。num表示數(shù)字,比如 10gg 就是移動到第10行。等價于 numG/:num 。10gg/10G/:10 都是移動光標(biāo)到第10行。
- * : 讀取光標(biāo)處的字符串,并且移動光標(biāo)到它再次出現(xiàn)的地方.
- /text:從當(dāng)前光標(biāo)處開始搜索字符串 text,并且到達(dá) text 出現(xiàn)的地方。必須使用回車來開始這個搜索命令。如果想重復(fù)上次的搜索的話,按 n。如果想要精確查找的話,不妨在text的前后加上空格。比如我想查找back,但是不想要諸如background之類的詞出現(xiàn),可以輸入<code>:/ back </code>,而不是<code>/back</code>。
- ?text:和上面類似,但是反方向。
快速進(jìn)入插入模式 ( insert mode )
- i ( insert ):在當(dāng)前字符的左邊插入
- I:在當(dāng)前行首插入
- a ( append ):在當(dāng)前字符的右邊插入
- A:在當(dāng)前行尾插入
- o ( open ):在當(dāng)前行下面插入一個新行
- O:在當(dāng)前行上面插入一個新行
- c ( change ){motion}:刪除 motion 命令跨過的字符,并且進(jìn)入插入模式。比如:c$,這將會刪除從光標(biāo)位置到行尾的字符并且進(jìn)入插入模式。ct!,這會刪除從光標(biāo)位置到下一個嘆號(但不包括),然后進(jìn)入插入模式。被刪除的字符被存在了剪貼板里面,并且可以再粘貼出來。
- d ( delete ){motion}:和上面差不多,但是不進(jìn)入插入模式。
在可視模式 ( visual mode ) 下選中
在 visual mode 選中的內(nèi)容會被高亮,可能經(jīng)常會有以下幾個操作。
- d:剪貼選擇的內(nèi)容到剪貼板。
- y:拷貝選擇的內(nèi)容到剪貼板。
- c:剪貼選擇的內(nèi)容到剪貼板并且進(jìn)入插入模式。
在非可視選擇模式下剪切和拷貝
- d( delete ){motion}:剪切 motion 命令跨過的字符到剪貼板。比如,dw 會剪切一個詞; dfS 會將從當(dāng)前光標(biāo)到下一個 S 之間的字符剪切至剪貼板。
- y( yank ){motion}:和上面類似,不過是拷貝。
- c( change ){motion}:和 d( delete ){motion} 類似,不過最后進(jìn)入插入模式。
- dd :剪切當(dāng)前行(至剪貼板)。
- dw : 刪除一個單詞,不適用于中文。由于vim中對于單詞,句子,段落等定義以及像單詞的跳轉(zhuǎn)一般距離很小,此類很“細(xì)致”的命令似乎并不是十分受用。
- yy:拷貝當(dāng)前行(至剪貼板)。
- Y:拷貝當(dāng)前行(至剪貼板)。
- D:剪切從光標(biāo)位置到行尾(到剪貼板)。
- C:和 D 類似,最后進(jìn)入插入模式。
- x:剪切(當(dāng)前字符到剪貼板)。
- s:和x類似,不過最后進(jìn)入插入模式。
替換(更改)文本
- ~ : 游標(biāo)所在處字符進(jìn)行大小寫替換。
- r ( replace ) : 替換單個字符,不必進(jìn)入插入模式(insert mode)。 在 normal mode 下將光標(biāo)停在想要替換的字符處,輸入<code>r</code>緊接著再輸入想要替換后的字符即可。完成后仍然在normal mode。
- R : 大寫的R表示連續(xù)替換,直到按下<code>esc</code>.
- cc ( change ):替換整行,即刪除游標(biāo)所在行,并進(jìn)入插入模式。
- s ( substitute ) : 替換。在normal mode下的<code>s</code>將會刪除光標(biāo)處的字符并進(jìn)入 insert mode,此時便可進(jìn)行重新編輯。
粘貼
- p ( paste or put )(小寫p) : 在當(dāng)前行后粘貼。
- P( 大寫P ): 在當(dāng)前行前粘貼。
vim 進(jìn)階
使用數(shù)字
在很多 vim 的命令之前都可以使用一個數(shù)字,這個數(shù)字將會告訴 vim 這個命令需要執(zhí)行幾次。比如:
- 3j : 將會把光標(biāo)向下移動三行。
- 10dd : 將會刪除十行。
- y3″ : 將會拷貝從當(dāng)前光標(biāo)到第三個出現(xiàn)的引號之間的內(nèi)容到剪貼板。 數(shù)字是擴(kuò)展 motion 命令作用域非常有效的方法。
用vim寫代碼
vim 是程序員專用,自然有一些特性是專門為程序員而設(shè)計的。這里是一些常用的:
- >:縮進(jìn)所有選擇的代碼
- <:和上面類似,但是反縮進(jìn)
查找替換
s指substitute(代替,替換的意思),g指global。
-
:s/hello/sky/
替換當(dāng)前行第一個 hello 為 sky -
:s/hello/sky/g
替換當(dāng)前行所有 hello 為 sky -
:n,$s/hello/sky/
替換第 n 行開始到最后一行中每一行的第一個 hello 為 sky -
:n,$s/hello/sky/g
替換第 n 行開始到最后一行中每一行所有 hello 為 sky(n 為數(shù)字,若 n 為 .,表示從當(dāng)前行開始到最后一行) -
:%s/hello/sky/
替換所有行的第一個 vivian 為 sky -
%s/hello/sky/g
替換所有行中所有 hello 為 sky
小技巧
- 比如對于
hello(test)
,光標(biāo)停留在括號處,那么di(
表示刪除括號里面的內(nèi)容,即刪除括號里面的test內(nèi)容, 簡記為delete in (
。同理,(
也可以換成[
,刪除里面的內(nèi)容。還有類似的da(
是連同周圍的括號一起刪除,delete around (
.
調(diào)整本行內(nèi)容位置
- <code>:ce</code> : 在命令行模式下輸入 <code>:ce</code> (center)將本行內(nèi)容居中。
- <code>:ri</code> : 將本行內(nèi)容居右(right).
- <code>:le</code> : 將本行內(nèi)容居左(left).
參考:
- Vim學(xué)習(xí)筆記
- 學(xué)習(xí)vi與vim編輯器 第七版 中文 東南大學(xué)出版社
- 一起來說vim語