通過這 5 個外掛擴充套件 Vim 功能來提升你的編碼效率。
我用 Vim 已經超過 20 年了,兩年前我決定把它作為我的首要文字編輯器。我用 Vim 來編寫程式碼、配置檔案、部落格文章及其它任意可以用純文字表達的東西。Vim 有很多超級棒的功能,一旦你適合了它,你的工作會變得非常高效。
在日常編輯工作中,我更傾向於使用 Vim 穩定的原生功能,但開源社群對 Vim 開發了大量的外掛,可以擴充套件 Vim 的功能、改進你的工作流程和提升工作效率。
以下列舉 5 個非常好用的可以用於編寫任意程式語言的外掛。
1、Auto Pairs
Auto Pairs 外掛可以幫助你插入和刪除成對的文字,如花括號、圓括號或引號。這在編寫程式碼時非常有用,因為很多程式語言都有成對標記的語法,就像圓括號用於函式呼叫,或引號用於字串定義。
Auto Pairs 最基本的功能是在你輸入一個左括號時會自動補全對應的另一半括號。比如,你輸入了一個 [
,它會自動幫你補充另一半 ]
。相反,如果你用退格鍵刪除開頭的一半括號,Auto Pairs 會刪除另一半。
如果你設定了自動縮排,當你按下Enter鍵時 Auto Pairs 會在恰當的縮排位置補全另一半括號,這比你找到放置另一半的位置並選擇一個正確的括號要省勁多了。
例如下面這段程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 |
package main import "fmt" func main() { x := true items := []string{"tv", "pc", "tablet"} if x { for _, i := range items } } |
在 items
後面輸入一個左花括號按下回車會產生下面的結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package main import "fmt" func main() { x := true items := []string{"tv", "pc", "tablet"} if x { for _, i := range items { | (cursor here) } } } |
Auto Pairs 提供了大量其它選項(你可以在 GitHub 上找到),但最基本的功能已經很讓人省時間了。
2、NERD Commenter
NERD Commenter 外掛給 Vim 增加了程式碼註釋的功能,類似在 IDEintegrated development environment 中註釋功能。有了這個外掛,你可以一鍵註釋單行或多行程式碼。
NERD Commenter 可以與標準的 Vim filetype 外掛配合,所以它能理解一些程式語言並使用合適的方式來註釋程式碼。
最易上手的方法是按 Leader+Space
組合鍵來切換註釋當前行。Vim 預設的 Leader 鍵是 \。
在視覺化模式Visual mode中,你可以選擇多行一併註釋。NERD Commenter 也可以按計數註釋,所以你可以加個數量 n 來註釋 n 行。
還有個有用的特性 “Sexy Comment” 可以用 Leader+cs
來觸發,它的塊註釋風格更漂亮一些。例如下面這段程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package main import "fmt" func main() { x := true items := []string{"tv", "pc", "tablet"} if x { for _, i := range items { fmt.Println(i) } } } |
選擇 main
函式中的所有行然後按下 Leader+cs
會出來以下注釋效果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package main import "fmt" func main() { /* * x := true * items := []string{"tv", "pc", "tablet"} * * if x { * for _, i := range items { * fmt.Println(i) * } * } */ } |
因為這些行都是在一個塊中註釋的,你可以用 Leader+Space
組合鍵一次去掉這裡所有的註釋。
NERD Commenter 是任何使用 Vim 寫程式碼的開發者都必裝的外掛。
3、VIM Surround
Vim Surround 外掛可以幫你“環繞”現有文字插入成對的符號(如括號或雙引號)或標籤(如 HTML 或 XML 標籤)。它和 Auto Pairs 有點兒類似,但是用於處理已有文字,在編輯文字時更有用。
比如你有以下一個句子:
1 |
"Vim plugins are awesome !" |
當你的游標處於引起來的句中任何位置時,你可以用 ds"
組合鍵刪除句子兩端的雙引號。
1 |
Vim plugins are awesome ! |
你也可以用 cs"'
把雙端的雙引號換成單引號:
1 |
'Vim plugins are awesome !' |
或者再用 cs'[
替換成中括號:
1 |
[ Vim plugins are awesome ! ] |
它對編輯 HTML 或 XML 文字中的標籤tag尤其在行。假如你有以下一行 HTML 程式碼:
1 |
<p>Vim plugins are awesome !</p> |
當游標在 “awesome” 這個單詞的任何位置時,你可以按 ysiw<em> 直接給它加上著重標籤(<em>):
1 |
<p>Vim plugins are <em>awesome</em> !</p> |
注意它聰明地加上了 </em> 閉合標籤。
Vim Surround 也可以用 ySS
縮排文字並加上標籤。比如你有以下文字:
1 |
<p>Vim plugins are <em>awesome</em> !</p> |
你可以用 ySS <div class="normal">
加上 div
標籤,注意生成的段落是自動縮排的。
1 2 3 |
<div class="normal"> <p>Vim plugins are <em>awesome</em> !</p> </div> |
Vim Surround 有很多其它選項,你可以參照 GitHub 上的說明嘗試它們。
4、Vim Gitgutter
Vim Gitgutter 外掛對使用 Git 作為版本控制工具的人來說非常有用。它會在 Vim 的行號列旁顯示 git diff
的差異標記。假設你有如下已提交過的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
1 package main 2 3 import "fmt" 4 5 func main() { 6 x := true 7 items := []string{"tv", "pc", "tablet"} 8 9 if x { 10 for _, i := range items { 11 fmt.Println(i) 12 } 13 } 14 } |
當你做出一些修改後,Vim Gitgutter 會顯示如下標記:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
1 package main 2 3 import "fmt" 4 _ 5 func main() { 6 items := []string{"tv", "pc", "tablet"} 7 ~ 8 if len(items) > 0 { 9 for _, i := range items { 10 fmt.Println(i) + 11 fmt.Println("------") 12 } 13 } 14 } |
_
標記表示在第 5 行和第 6 行之間刪除了一行。~
表示第 8 行有修改,+
表示新增了第 11 行。
另外,Vim Gitgutter 允許你用 [c
和 ]c
在多個有修改的塊之間跳轉,甚至可以用 Leader+hs
來暫存某個變更集。
這個外掛提供了對變更的即時視覺反饋,如果你用 Git 的話,有了它簡直是如虎添翼。
5、VIM Fugitive
Vim Fugitive 是另一個將 Git 工作流整合到 Vim 中的超棒外掛。它對 Git 做了一些封裝,可以讓你在 Vim 裡直接執行 Git 命令並將結果整合在 Vim 介面裡。這個外掛有超多的特性,更多資訊請訪問它的 GitHub 專案頁面。
這裡有一個使用 Vim Fugitive 的基礎 Git 工作流示例。設想我們已經對下面的 Go 程式碼做出修改,你可以用 :Gblame
呼叫 git blame
來檢視每行最後的提交資訊:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 1 package main e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 2 e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 3 import "fmt" e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 4 e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│_ 5 func main() { e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 6 items := []string{"tv", "pc", "tablet"} e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 7 00000000 (Not Committed Yet 2018-12-05 18:55:00 -0500)│~ 8 if len(items) > 0 { e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 9 for _, i := range items { e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 10 fmt.Println(i) 00000000 (Not Committed Yet 2018-12-05 18:55:00 -0500)│+ 11 fmt.Println("------") e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 12 } e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 13 } e9949066 (Ricardo Gerardi 2018-12-05 18:17:19 -0500)│ 14 } |
可以看到第 8 行和第 11 行顯示還未提交。用 :Gstatus
命令檢查倉庫當前的狀態:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
1 # On branch master 2 # Your branch is up to date with 'origin/master'. 3 # 4 # Changes not staged for commit: 5 # (use "git add <file>..." to update what will be committed) 6 # (use "git checkout -- <file>..." to discard changes in working directory) 7 # 8 # modified: vim-5plugins/examples/test1.go 9 # 10 no changes added to commit (use "git add" and/or "git commit -a") -------------------------------------------------------------------------------------------------------- 1 package main 2 3 import "fmt" 4 _ 5 func main() { 6 items := []string{"tv", "pc", "tablet"} 7 ~ 8 if len(items) > 0 { 9 for _, i := range items { 10 fmt.Println(i) + 11 fmt.Println("------") 12 } 13 } 14 } |
Vim Fugitive 在分割的視窗裡顯示 git status
的輸出結果。你可以在該行按下 -
鍵用該檔案的名字暫存這個檔案的提交,再按一次 -
可以取消暫存。這個資訊會隨著你的操作自動更新:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
1 # On branch master 2 # Your branch is up to date with 'origin/master'. 3 # 4 # Changes to be committed: 5 # (use "git reset HEAD <file>..." to unstage) 6 # 7 # modified: vim-5plugins/examples/test1.go 8 # -------------------------------------------------------------------------------------------------------- 1 package main 2 3 import "fmt" 4 _ 5 func main() { 6 items := []string{"tv", "pc", "tablet"} 7 ~ 8 if len(items) > 0 { 9 for _, i := range items { 10 fmt.Println(i) + 11 fmt.Println("------") 12 } 13 } 14 } |
現在你可以用 :Gcommit
來提交修改了。Vim Fugitive 會開啟另一個分割視窗讓你輸入提交資訊:
1 2 3 4 5 6 7 8 9 10 |
1 vim-5plugins: Updated test1.go example file 2 # Please enter the commit message for your changes. Lines starting 3 # with '#' will be ignored, and an empty message aborts the commit. 4 # 5 # On branch master 6 # Your branch is up to date with 'origin/master'. 7 # 8 # Changes to be committed: 9 # modified: vim-5plugins/examples/test1.go 10 # |
按 :wq
儲存檔案完成提交:
1 2 3 |
[master c3bf80f] vim-5plugins: Updated test1.go example file 1 file changed, 2 insertions(+), 2 deletions(-) Press ENTER or type command to continue |
然後你可以再用 :Gstatus
檢查結果並用 :Gpush
把新的提交推送到遠端。
1 2 3 4 5 |
1 # On branch master 2 # Your branch is ahead of 'origin/master' by 1 commit. 3 # (use "git push" to publish your local commits) 4 # 5 nothing to commit, working tree clean |
Vim Fugitive 的 GitHub 專案主頁有很多螢幕錄影展示了它的更多功能和工作流,如果你喜歡它並想多學一些,快去看看吧。
接下來?
這些 Vim 外掛都是程式開發者的神器!還有另外兩類開發者常用的外掛:自動完成外掛和語法檢查外掛。它些大都是和具體的程式語言相關的,以後我會在一些文章中介紹它們。
你在寫程式碼時是否用到一些其它 Vim 外掛?請在評論區留言分享。