跳转至

Vim

Vim - 無處不在的文本編輯器。

簡介

Vim 是從 vi 發展出來的一個文本編輯器。其代碼補完、編譯及錯誤跳轉等方便編程的功能特別豐富,在程序員羣體中被廣泛使用。

安裝

Linux 系統通常自帶 Vim,打開終端輸入 vim 即可啓用。

若需手動安裝,Vim 的 官方網站 提供了下載的 説明文檔,按照需求編譯安裝即可。

Vim 的模式與常用鍵位

Vim 的基礎操作在 Vim 自帶的教程裏將會講述。打開終端輸入 vimtutor 即可進入教程。

這些操作通常需要二三十分鐘來大致熟悉。

命令模式 (Command Mode)

進入 Vim 後的默認模式。

此狀態下敲擊鍵盤動作會被 Vim 識別為命令,而非輸入字符,比如我們此時按下i,並不會輸入一個字符,i被當作了一個命令。

Vim 的方向鍵是,或者hjkl

1
2
3
4
5
        ↑(k)
        ^
(h)← <     > →(l)
        v
        ↓(j)

以下是命令模式常用的命令:

  • i 切換到輸入模式,在光標當前位置開始輸入文本。按Esc鍵可回到普通模式。
  • x 用於刪除光標後的一個字符。
  • : 切換到底線命令模式,以在最底一行輸入命令。
  • a 切換到輸入模式,在光標後開始輸入文本。
  • o 切換到輸入模式,在光標下插入新的一行;O 切換到輸入模式,在光標上插入新的一行。
  • p 粘貼剪貼板內容到光標下方;P 粘貼剪貼板內容到光標上方。
  • dd 刪除光標所在的一整行。
  • d 命令也是刪除,通常配合其他鍵使用。
  • u 撤銷上一次對文本的更改。
  • y 命令可以複製被選中的區域。需要按 v 進入可視模式操作。
  • yy 複製當前行。
  • Ctrl + r 重做上次撤銷的操作。
  • :w 保存文件,常配合 q 保存退出。
  • :q 退出 Vim。
  • :q! 強制退出 Vim,不保存修改。

部分其他命令:

  • c 命令用於修改,相當於 di
  • = 命令可以以默認格式對選中行應用自動縮進。
  • == 自動縮進當前行。
  • . 命令可以重複上次執行的命令。
  • gg 命令可跳至代碼的開頭;G 命令可跳至代碼最後一行的開頭;G 命令前加數字可跳至指定行。
  • w 可以跳到下個單詞的開頭;e 可以跳到當前單詞或下一單詞的結尾;b 可以跳到當前單詞或上一單詞的的開頭;0 可以跳至行首;$ 可以跳至行尾。we、-0$ 還可以與其他命令組合,比如 dedwd0d$ 分別對應刪至單詞尾、刪至下個單詞頭、刪至行首和刪至行尾。

命令模式下按/,下方即會出現查找框,輸入需要查找的字符,按回車後就能查看搜索結果。如果有多個查找結果,按n即可跳至下一個查找結果;按N可跳至上一個。

命令模式下按*可以查找當前光標下的單詞。

在輸入某個命令前,輸入一個數字 n 的話,命令就會重複 n 次。

輸入模式 (Insert Mode)

在命令模式下按下i就進入了輸入模式,按Esc鍵可以返回到命令模式。

在輸入模式中,可以使用以下按鍵:

  • 字符按鍵以及Shift組合,輸入字符
  • ENTER,回車鍵,換行
  • BACK SPACE,退格鍵,刪除光標前一個字符
  • DEL,刪除鍵,刪除光標後一個字符
  • 方向鍵,在文本中移動光標
  • HOME/END,移動光標到行首/行尾
  • Page Up/Page Down,上/下翻頁
  • Insert,切換光標為輸入/替換模式,光標將變成豎線/下劃線
  • ESC,退出輸入模式,切換到命令模式

在輸入模式下按Ctrl+o即可進入「輸入 - 命令模式」,執行完一次操作後又會自動回到輸入模式。

底線命令行模式

命令模式下按:,進入底線命令模式。

底線命令模式可以輸入單個或多個字符的命令,可用的命令非常多。

在底線命令模式中,基本的命令有:

  • :help/:h 查看英文版 Vim 在線幫助文檔。
  • :w 保存文件。
  • :q 退出 Vim。
  • :wq 保存文件,退出 Vim。
  • :q!/:!q 強制退出 Vim,不保存修改。
  • :e filename 可以打開當前目錄下的指定文件。
  • :s 命令是替換。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
" 把當前行第一個匹配的 str1 替換成 str2
:s/str1/str2/
" 把當前行所有的 str1 替換成 str2
:s/str1/str2/g
" 把當前行所有的 str1 替換成 str2,在替換前詢問
:s/str1/str2/gc
" 把第 x1 行至 x2 行中,每一行第一個匹配的 str1 替換成 str2
:x1,x2 s/str1/str2/
" 把第 x1 行至 x2 行中所有的 str1 替換成 str2
:x1,x2 s/str1/str2/g
" 第 x1 行至 x2 行中所有的 str1 替換成 str2,在替換前詢問
:x1,x2 s/str1/str2/gc
" 把所有行第一個匹配的 str1 替換成 str2
:%s/str1/str2/
" 把全文件所有的 str1 替換成 str2
:%s/str1/str2/g
" 把全文件所有的 str1 替換成 str2,在替換前詢問
:%s/str1/str2/gc

如果命令形式是 :! command,則命令將在 bash 終端執行。

Esc鍵可以退出底線命令模式。

可視模式 (Visual mode)

v 進入可視模式,多用於選中區域。按 VShift+v)進入行可視模式,用於選中行。

Ctrl+vCtrl+q進入塊可視模式 (visual block)。

進入塊可視模式後,按IA進入插入模式(相當於 ia),退出插入模式後對本行所做的改動將被應用到選中的每一行同一位置。常用於批量添加註釋。

選中後輸入 yd 亦可執行相應命令。

三種可視模式可以通過按鍵相互轉化。

Vim 的快捷鍵

可參考 史上最全 Vim 快捷鍵鍵位圖—入門到進階

進階知識

. 命令

Vim 的使用者不可避免地會抗拒重複的文本修改,因為 Vim 註定比其他編輯器會多出兩次按鍵——Esci。但是,Vim 其實提供了重複命令 .,它適用於重複的添加、修改、刪除文本操作。

. 命令可以重複上次執行的命令。但是這個「命令」並不只限於單一的命令,它也可以是 數字 + 命令 的組合;進入插入模式 + 輸入文本 + Esc 也是命令的一種。所以,適當使用 . 命令才能達到最高的效率。

例如,如下代碼的每一行末尾都少了分號:

1
2
3
4
int a, b
cin >> a >> b
cout << a + b
return 0

. 與搭配移動到行尾插入命令 A 使用,就能高效地補上末尾的分號。

1
2
3
A;<Esc>
" 重複下面的命令
j.

再例如,如下代碼中,後面五個賦值語句的數組名全部寫錯了:

1
2
3
4
5
int check() {
  book[1] = 1, book[2] = 1, book[3] = 1, bok[1] = 1, bok[2] = 1, bok[3] = 1,
  bok[4] = 1, bok[5] = 1;
  return 0;
}

一個個改過於麻煩,而命令行模式的 s 命令又會全部改掉。

第一種改法是搭配普通模式下的 s 命令(刪除光標處字符並進入插入模式)使用。來到第一個錯誤的數組名首字母處,按下 3s/cw,輸入正確的數組名並退出。之後把光標一個個移過去,再使用 . 命令。

第二種比較節省時間的改法是利用查找模式修改。鍵入 /bok,接着按下回車,並使用 n 鍵來到第一個錯誤的數組名首字母處,鍵入 3s 新數組名 <Esc>,最後重複 n.

第三種改法是簡易查找命令 f。在一行中普通模式下,f + 單個字符 即可查找此行中出現的這個字符並將光標移至字符處;按 ; 查找下一個,, 查找上一個。所以對於上面的代碼,只需鍵入 fb;;; 之後進入插入模式修改,然後 ;. 即可。這種改法適用於只需行內移動的情況。

Vim 的宏功能可以重複任意長的命令。

使用宏之前要先「錄製」,即把一串按鍵操作錄下來再回放,這樣就達到了重複的效果。錄製的方法很簡單,普通模式下鍵入 q 開始錄製。下一步,為錄製的宏指定一個執行的命令鍵,可以按下 26 個字母中的任意一個來指定。這時左下方會顯示 記錄中 @剛剛選擇的字母。然後就可以開始錄製命令了。同理,普通模式下按 q 暫停錄製。

使用方法為按下 : 進入命令行模式,鍵入 @選擇的記錄字母,然後之前錄製的命令就被調用了。

. 和宏組合,即錄製宏 → 調用宏 →. 重複命令 → 數字 +.,可以達到非常高的效率。

normal 命令

該命令與普通模式有關,效果是在指定行重複命令。

: 進入命令行模式,輸入如下命令:

1
:a,b normal command

或者:

1
:a,b norm command

以上命令的意思是在普通模式下,對 a~b 行執行 command 命令。

由於 normal 命令可以被 . 命令重複調用,且其易於理解,它的使用頻率甚至更高於宏。

數字 +.+ 宏 + normal

以上三種命令可以組合使用。例如:

我下載了一本書,我需要它的每一個章節都變成「標題」,以方便轉換成 mobi 之類的格式,或者方便生成 TOC 目錄跳轉,怎麼辦呢?

以下是用 Vim 處理的過程:

  1. 按下/調出查找框,輸入正則表達式進行查找;
  2. q 命令開始錄製宏;
  3. 鍵入 I# 命令,然後按下ESC
  4. q 進行修改操作並結束宏錄製;
  5. 鍵入 normal n@字母 轉到下一處並重覆上一步操作;
  6. 鍵入 數字 + . 多次重複。

外部鏈接