Published on

Vim 縮排大全

Authors
  • avatar
    Name
    米K朗基羅
    Twitter
    @kvzl_

雖然現在已經很少直接用 Vim 做開發,一般都是使用其他 Editor 的 Vim 插件在做日常開發,但有時候直接在終端機底下直接用 Vim 改些檔案還是很方便的。

為了不要再受到怪怪的縮排所影響,決定在這週末一口氣把 Vim 的縮排搞定!

縮排指令

透過指令縮排的方式有很多,比如說遇到像這樣的程式碼:

function test() {
  console.log('123')
  console.log('456')
  console.log('789')
}

這時候可以可以將鼠標移到第 2 行,用 3>> 手動把 2~4 行往右邊縮進一格(反之則是 3<<),或是對指令範圍進行自動縮排,例如:

  • v 選取指定程式碼後執行 =
  • 透過 =a{ 縮排 { } 內的程式碼
  • 直接用 gg=G 對整份程式碼做縮排
  • ...等。

縮排的種類

剛剛有提到可以用 >>=<< 來做手動、自動縮排,但每次調整縮排時 Vim 要怎麼幫你插入空白字元或 Tab 字元?縮排的寬度如何?怎麼決定要不要自動縮排?這些都可以對 Vim 進行設定。

不過在說明怎麼設定之前,必須先說明其實在 Editor 中,所謂的 Tab 有分硬的跟軟的,也就是 Hard TabSoft Tab。那這兩者差別在哪呢?

  • Hard Tab 指的是透過 Tab 字元來縮排
  • Soft Tab 則是使用空白字元
  • Hard Tab 在不同系統、不同編輯器中可能以不同的寬度呈現
  • 簡單來說,Hard 是相對的概念,Soft 則是絕對的概念

至於硬的好還是軟的好?由於牽涉到個人偏好,長久以來已在網路上掀起無數戰文,不知有多少對朋友因此而反目、多少男女因此而分手,因此這裡就不多做論述了。

只能說這和 Coding Style 一樣,事前和團隊充分溝通,並且透過工具(如 EditorConfig)來加以約束是比較不會有問題的。

相關設定

以下就來介紹一些 Vim 所提供常用來調整縮排的選項。

註:給尚不熟悉 Vim 的朋友參考,以下是進行 Vim 設定的語法範例:

set autoindent
set tabstop=1
set noexpandtab softtabstop=0

將設定寫在 ~/.vimrc 即可在啟動時生效。

自動縮排

autoindent

沿用上一行的縮排

smartindent

類似 autoindent,此外還可以辨識類 C 語法,並適時的增加、減少縮排。

cindent

可以客製化,簡直比 smartindent 更 smart,但客製化的參數其實不多,也不太好用。

不過以上方法其實不一定能適用於所有檔案類型,最好還是讓 vim 自動幫你判斷,只要加入:

filetype plugin indent on

調整寬度

tabstop

tab 字元的寬度。

shiftwidth

針對程式縮排(使用 <<>>= 時),或按下 tab 鍵時的寬度 。

softtabstop

設 expandtab 時,可以像刪除 Tab 一樣,刪除固定寬度的空白。

設 noexpandtab 時,每逢 tabstop 的倍數就會轉成 Tab 字元,剩下的則是空白,也就是說這種情況下 Tab 字元和空白是有可能混用的,比如說:

  • set tabstop=4 softtabstop=8 shiftwidth=8:插入 1 個 Tab 得到 2 個 Tab 字元(4*2)
  • set tabstop=4 softtabstop=10 shiftwidth=10:插入 1 個 Tab 得到 2 個 Tab 字元加上 2 個空白(4*2+2)
  • set tabstop=8 softtabstop=4 shiftwidth=4:插入 1 個 Tab 得到 4 個空白,插入 2 個 Tab 得到 1 個 Tab 字元

expandtab

以空白鍵取代 Tab 字元

其他問題

進行縮排或是按下 tab 鍵時,實際插入的寬度為何?

寬度為 shiftwidth,除非 shiftwidth 設為 0 就會變為 tabstop。

進行縮排或是按下 tab 鍵時,實際插入的是 tab 字元還是 space?

要看情況,如果有設 expandtab 的話,一律都會是 space。但如果設 noexpandtab 就不一定了。

如果 shiftwidth 為 0 且設 noexpandtab,就會得到 tab 字元,否則還是根據 softtabstop 決定得到幾個 tab 字元和 space,有可能同時都有。

如果設定 expandtab 的情況下,真的很想插入真正的 tab 字元怎麼辦?

在 insert 模式下輸入 ctrl+v tab 即可~

垃圾話

一直把縮排看成雞排,我一定是肚子餓ㄌ

參考資料