vim 回顧

下面是一篇舊文,大多是一些已有知識的整理,并不太成熟。歡迎關(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)范圍的示意圖,你們感受一下:

range

組詞為句

有了這些基本的語言元素,我們就可以著手構(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).

參考:

  1. Vim學(xué)習(xí)筆記
  2. 學(xué)習(xí)vi與vim編輯器 第七版 中文 東南大學(xué)出版社
  3. 一起來說vim語
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容