VSCodeVim 最佳實踐

1. Preface

初學者在學了一些 Vim 入門教程,掌握了一些基本操作後,往往不知道從何下手,日常工作中不太可能在終端下直接寫代碼,何況直接終端用 Vim 寫代碼,還需要大量插件的支持。

其實我認識的很多 Vim 用戶,現在已經不用原生 Vim 了,都是先選一個自己喜歡的編輯器/IDE, 再裝 Vim 插件,基本上沒有哪個現代編輯器/IDE沒有 Vim 插件的了。

我比較喜歡 VSCode,日常工作也是用 VSCode 寫代碼,所以今天就來介紹下 VSCode 裏 Vim 插件的一些設置和應用技巧,至於是不是最佳實踐不重要,起這樣的標題完全是不知道用什麼好,權當做一回標題黨吧。

2. 編輯器選擇

在講具體內容之前,先介紹幾個編輯器的 Vim 插件現狀, 順便解釋下我爲什麼要選 VSCode:

  • Sublime Text, 編輯器內建了對 Vim 的支持,所以不裝插件只要改下配置就能用,但是功能比較原始,實在談不上好用,只能說能用。也許有很多第三方插件提供了類似 easymotion 這樣的功能吧,我沒研究過,想用的可以看看有沒有,如果有還是可以用的。
  • VisualStudio, 由於 VS 內建了海量的快捷鍵,且用熟了之後也很方便,所以對於 VS 資深用戶,裝個 Vim 插件反而不好用,這上面的 Vim 插件我也用過,體驗非常糟糕,不推薦。
  • MacVim, 配合 spf13-vim 還是可以用的,我個人在對 VSCode 審美疲勞時也會用一用,輕量、好看、好用。
  • IntelliJ IDEA, 這是個 IDE 了,非常重,但功能還是十分強大的,Vim 插件也基本夠用,好像也是有 easymotion 的,基本上很完整,還有社區免費版可用,所以用的人非常多,但是我一開 CPU 就狂轉,所以最終沒用它。
  • VSCode, 目前我最喜歡的,Vim 插件支持非常成熟,其他編輯器的 Vim 插件一般只是提供了 Vim 的原生功能,而 VSCode 的 Vim 插件居然提供了很多原生 Vim 裏的插件功能,也就是說,它是一個 Vim + Vim插件的插件集合體,功能非常強大,像是最常用的 easymotion 就提供了支持。原生 Vim 其實並不好用,想要高效還是要配合插件一起用,而 VSCode 的 Vim 插件做到了,我認爲現在沒有什麼編輯器的 Vim 插件能夠做到。

3. VSCode Vim 插件的安裝

上面說了那麼多,對於初學者來說,建議直接用 VSCode 吧,不折騰。

安裝非常方便,打開插件界面,輸入 Vim,第一個就是,點安裝即可。

800多萬的安裝量,感受下 Vim 用戶的龐大,是不是感覺不用 Vim 和時代脫離了:)

4. 最佳實踐

4.1 settings.json 配置

{
    "vim.easymotion": true,
    "vim.leader": ",",
    "vim.searchHighlightColor": "#5f00af",
    "vim.hlsearch": true,
    "vim.normalModeKeyBindingsNonRecursive": [
        { "before": ["H"], "after": ["g", "T"], },
        { "before": ["L"], "after": ["g", "t"] },
    ],

    "editor.lineNumbers": "relative",
    "files.autoSave": "onFocusChange",
    "workbench.editor.enablePreviewFromQuickOpen": false,
    "editor.renderWhitespace": "boundary",
    "editor.detectIndentation": false,
    "showMusicMetrics": false,
    "showGitMetrics": false,
    "showWeeklyRanking": false,
    "editor.minimap.enabled": false,
    "git.autofetch": true,
}

首先把上面的配置放到自己的配置文件裏,Mac 平臺點左上角 Code->Preferences->Settings-> 在右邊往下拉,找到 Edit in settings.json, 把上面內容放進去,大括號自己去掉。

解釋幾個:

Vim 相關的

  • “vim.easymotion”: true, 打開 easymotion, 這個是文件內快速跳轉的插件(Jump everywhere)
  • “vim.leader”: “,”, 設置 leader 鍵爲逗號,leader 鍵是 Vim 裏某些指令的前置按鍵,默認是反斜線,比較難按。這個按鍵非常常用,必須改成逗號
  • “vim.searchHighlightColor”: “#5f00af”, 設置搜索高亮,不設的話沒有高亮,很蠢
  • “vim.hlsearch”: true, 高亮顯示最近的搜索結果,就是你按一下 *, 把結果都高亮出來,這個很重要
  • “vim.normalModeKeyBindingsNonRecursive”, 這個是改按鍵映射關係的,改完可以使用 H/L 切換標籤

Vim 無關的

  • “editor.lineNumbers”: “relative”, 設置相對行號,這個對於多行刪除,多行註釋非常重要,有了這個纔算是可以用,否則自己數行數那基本上沒法用
  • “files.autoSave”: “onFocusChange”, 設置文件自動保存,onFocusChange 指的是焦點離開後就保存,這個跟 Vim 無關,但非常好用,不用一直按 Cmd+s 了
  • “workbench.editor.enablePreviewFromQuickOpen”: false, 用 ctrl-p 打開的文件,默認是處理預覽狀態的,重新預覽其他文件時就沒了,要雙擊標籤纔會固定住,這個設置就是解決這個問題的,設置完後打開就是固定住的,讀代碼很方便
  • “editor.renderWhitespace”: “boundary”, 設置顯示行首的空白字符(空格和製表符),這個也很不錯,直觀的看到自己輸出的空白,有些開源項目要求必須全用空格。
  • “editor.minimap.enabled”: false, 關掉右邊的小地圖,就是寬寬的那個,這個看個人喜好了,我不太喜歡,開分欄時會減少顯示面積

4.2 行級操作(刪除、註釋、左移右移)

上面設置了相對行號後,才能方便的做多行操作,在做具體操作前,先說單行操作分別是什麼:

  • dd 刪除一行, ddelete, 兩個 d 表示對一行操作,Vim 裏的約定吧
  • gcc 註釋一行, gcgo comment, 兩個 c 表示註釋一行
  • << 左移一行
  • >> 右移一行

上面的操作,在 v 模式下,都可以生效,可以試一下按 Shift+v 選中一行,然後分別按 d, gc,<, >, 看看是不是刪除、註釋、左移、右移

好了,有了上面的這些知識,我們可以開始多行操作了,具體操作方法如下:

  • 光標移到想要刪除或註釋的第一行
  • 通過左邊的相對行號,看一下想操作的最後一行的相對行號n
  • 得出要操作的行數 m = n+1 (因爲光標所在那行相當於第0行,所以要+1)
  • 這時就可以用 Vim 的多行操作了,刪除一行是 dd, 刪除多行是 mdd; 註釋一行是 gcc, 註釋多行是 mgcc, 其他的類推

4.3 切換標籤

  • H 大寫的 H 移動到左邊那個標籤
  • L 大寫的 L 移動到右邊那個標籤
  • ngt 移動到第 n 個標籤(從左往右從1開始),當標籤開的比較多時,由於標籤上沒顯示數字,要自己數是第幾個,所以基本上沒法用。

對於標籤開的比較多時怎麼操作,我的習慣是這樣的:

  • 如果標籤離的近,就是 H/L 移動過去
  • 如果離的不是特別遠,按5下 H/L 還是可以接受的
  • 如果特別遠,對於要長時間寫代碼的幾個標籤,用鼠標把幾個常用標籤拖到一起;如果是一次性的,就用鼠標直接點了;也會用 ctrl-p 直接搜文件重新打開。

4.4 調整光標所在行的位置(Vim基本功能)

  • zz 調整光標所在行到屏幕中間 (z 什麼意思我也不知道,就硬記吧)
  • zt 調整光標所在行到屏幕最上方 (t == top)
  • zb 調整光標所在行到屏幕最下方 (b == bottom)

這三個用的非常多,尤其是 zz, 一定要熟練使用

4.5 文件內快速搜索某個函數、變量(Vim基本功能)

把光標移到想搜索的那個函數名或變量名上,按*就可以搜索了,按n下一個,按N上一個。

比如看到類裏有個成員變量,想去回到它的定義處看有沒有註釋說它是幹嘛的,一般定義的地方肯定是文件內第一次出現的地方,我們可以這麼操作:

  • 先在這個變量上按下*鎖定它
  • gg 回到行首
  • n 到下一個它出現的地方
  • zz 調整到屏幕中間,方便閱讀

這4步熟悉後基本一氣呵成

4.6 對一個單詞進行操作

這裏先說兩個概念,操作符(operator)和動作命令(motion), 操作符就是 d(delete), c(change), y(yank) 等等,動作命令是iw(in word), aw(a word)這些,可以通過 操作符 + 動作命令的方式,組合出千變萬化的操作出來,幫助我們快速移動、修改等等。

完整列表可以在 Vim 裏輸入 :h motion.txt 查看,這裏只列出一些常用的。

4.6.1 操作符(Operators)

操作符 功能
c change (先刪除再進入插入模式)
d delete
y yank into register (does not change the text)
~ swap case (轉換大小寫)
gu make lowercase (轉爲小寫)
gU make uppercase (轉爲大寫)
> shift right (右移)
< shift left (左移)

4.6.2 動作命令(Motions)

動作命令 功能
f{char} find, 行內搜索一個字符
t{char} till, 功能類型 f{chat}, 但是是在這個搜索到的字符前停下,意思是到這個字符之前,很常用的motion
gg 跳到行首
G 跳到行尾
w 移到下個單詞的第一個字符
b 移到上個單詞的第一個字符
e 移到單詞最後一個字符
ge 上個單詞的最後一個字符
aw “a word”, 選擇一整個單詞,包括它邊上的空格
iw in word, 選擇一整個單詞,不包括空格

4.6.3 舉例:

  • diw, delete in word, 刪除一個單詞,只刪除單詞本身,不會旁邊的空格
  • daw, delete a word, 刪除一個單詞,並刪除旁邊的一個空格(至於是左還是右邊空格,Vim 會根據上下文自己判斷,非常智能)
  • d 是刪除, diw 就是刪除一個單詞
  • v 是進入 visual 模式的,如果用 viw, 就表示選中一個單詞
  • y 是複製(yank), yiw 表示複製一個單詞
  • gu 是變成小寫,guiw 就是讓一個單詞變成小寫
  • gU 是變成大寫, gUiw 就是讓一個單詞變成大寫

還有很多,這樣只要記住一個,就可以舉一反三,所以 Vim 是不需要死記硬背的,理解着記會更快。(當然不排除一些要死記硬背,但比較少)

4.7 把一個單詞改成另一個(通過複製)

比如有下面一段代碼:

local _hello = true
function test()
    print(_world)
end
-- 用複製的方式把 _world 改成 _hello

這個問題看起來很簡單,但實際上用起來後就會發現並不簡單,我們用鼠標時的操作邏輯是下面這樣的:

  • 雙擊 _hello,Ctrl+C 複製
  • 雙擊 _world,Ctrl+V 粘貼

想象中的 Vim 操作邏輯是下面這樣的:

  • 光標移到 _hello, yiw 複製
  • 光標移到 _world, diw 刪除,再 p 粘貼

這時你會發現,咦,貼出來的還是 _world, 而不是期望中的 _hello, 這是因爲 Vim 裏的刪除,實際上是剪切,會把刪除的東西放到“剪切板”裏,所以我們不能這樣操作,而應像下面這樣操作:

  • 光標移到 _hello, yiw 複製
  • 光標移到 _world, viw 選中,再 p 粘貼

這個操作是目前的最優解了,《Vim 實用技巧》這本書裏給的也是這個方案(我是先自己發明這個方案纔看的書:),這個方案雖然也很彆扭,但是夠用了,習慣了也不是不能接受。

4.8 EasyMotion 文件內快速跳轉

  • ,,j 按下後,會在每一行的行首高亮且有一個字母標在高亮處,這時輸入指定字母就可以跳過去了,這個可以說是起飛的關鍵之一,必須要熟練掌握
  • ,,k 上面是向下搜索,這個是向上,其他都一樣
  • ,,w,,j,只不過是單詞級的向後搜索
  • ,,b,,k, 只不過是單詞級的向前搜索(,,w ,,b 不如行級好用,因爲太花了,我們可以用行級 Jump 到指定行,再用 f 過去,或者按幾個 w 也可以,如果靠近行尾,可以先按$到行尾再按幾個 b,方法很多。

4.9 回到上一個編輯點

  • ctrl+o, 回到上一個編輯點
  • ctrl+i, 前進到下一個編輯點,和上面的相反方向
  • gi, 回到上一個進入插入模式的地方,並進入插入模式,這個在寫代碼時寫到一半想看一下其他地方的代碼,看完再按下 gi 回去,當然也可以 ctrl+o 回去。

4.10 代碼的快速翻頁

  • ctrl+f, 下一頁
  • ctrl+b, 上一頁
  • ctrl+d, 下半頁
  • ctrl+u, 上半頁

這四個非常常用,尤其是讀代碼時,我們不可能按住 j/k 不放去翻代碼。

4.11 分欄

  • :vs, 創建一個豎向分欄
  • :sp, 創建一個橫向分欄

在創建多個分欄後,怎樣在分欄之間移動?總不能用鼠標吧!當然不需要,下面就是移動分欄的方法:

  • 先按 ctrl+w 再按 h, 移到左邊一個分欄
  • 先按 ctrl+w 再按 l, 移到右邊一個分欄
  • 先按 ctrl+w 再按 j, 移到下邊一個分欄
  • 先按 ctrl+w 再按 k, 移到上邊一個分欄

按下 ctrl+w 後,就進入“移動分欄待決模式”了,這時按 hjkl 就可以移動了。

分欄在屏幕比較大時還是很方便的,有時候寫代碼時,要看着另一塊代碼,也很方便。

5. Postface

暫時就想到這些,還有很多比較常用的,想到了再補充。以上這些如果能掌握,基本上在 VSCode-Vim 環境下寫代碼足夠了,等真正用進去了,纔會發現有很多不會的或者不方便的點,這時要學會去 Google 或請教別人,只有這樣才能不斷強化,最終讓 Vim 操作變成肌肉記憶。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章