網頁

2013年3月26日

Tabs and Indent in Vim

Vim 中關於 tab 的相關設定,大致上就是 tabstop 、expandtab、shiftwidth、softtabstop 這四個變數,要搞懂其中的道理著實不容易啊。所以就將我所理解的部分,做個筆記。

下面是我從國外網站關於這四個變數的英文敘述,先列在下面比較好釐清他們之間的關係

expandtab

When expandtab is set, hitting Tab in insert mode will produce the appropriate number of spaces.

這個變數大致上是在大型專案多人開發的時候,為了避免大家的 coding style 不同,造成版面上的混亂,因此將所有的 tab 用 space 來做取代,可以讓大家看到一致的面貌。正常情況下不建議打開這個變數,假設一個 tab 用四個 space 做取代,space 所站的空間就會變成 tab 的四倍大。

shiftwidth

Set shiftwidth to control how many columns text is indented with the reindent operations (<< and >>) and automatic C-style indentation.

在 vim 的 normal mode 中,我們可以利用 << 和 >> 進行縮排和取消縮排的指令,那一次要縮排多少呢,就是透過 shiftwidth 來做控制。例如shiftwidth設定成12的話,如果按一次 <<,其實就已經插入了3個 tab 了。

tabstop

Set tabstop to tell vim how many columns a tab counts for. Linux kernel code expects each tab to be eight columns wide. Visual Studio expects each tab to be four columns wide. This is the only command here that will affect how existing text displays.

定義一個 tab 在 vim 畫面上的顯示多少個 space,一般來說是設定成8,文件上建議盡量採用這個數值,但是當程式碼比較長的時候,容易造成程式碼折行的現象。所以我個人是比較喜歡用4。

softtabstop

Set softtabstop to control how many columns vim uses when you hit Tab in insert mode. If softtabstop is less than tabstop and expandtab is not set, vim will use a combination of tabs and spaces to make up the desired spacing. If softtabstop equals tabstop and expandtab is not set, vim will always use tabs. When expandtab is set, vim will always use the appropriate number of spaces.

這個變數比較難解,主要是在 vim 的 insert mode 下,按下 tab 鍵的時候,游標會跳多少個 space。當 expandtab 沒有設定的時候,softtabstop 才會起作用。上面提到跳多少個space,實際上就是插入這麼多的space嗎,其實不然,他會很聰明的用 tab + space 來達成你最後的需求。

例如:

  • 如果 tabstop = 8,softtabstop = 8,按下 tab 鍵,插入的就是一個正常的 tab。
  • 如果 tabstop = 8,softtabstop = 16,按下 tab 鍵,插入的就是兩個正常的 tab。
  • 如果 tabstop = 8,softtabstop = 4,按下 tab 鍵,一開始會插入4個 space,如果再按下 tab 鍵,就會將前面的4個 space 和現在的4個 space取代成一個完整的 tab。換句話說就是只要每逢8個 space,就會用一個正常的 tab 做取代,當然,前提是 tabstop = 8

Indentation in the real world

Linux Kernel 裡常做這樣的設定
:set shiftwidth=8 tabstop=8 softtabstop=8 noexpandtab 

Windows裡常做這樣的設定
:set shiftwidth=4 tabstop=4 softtabstop=4 noexpandtab

用空白取代 tab 的風格
:set tabstop=4 softtabstop=4 expandtab 

基本上,我個人比較喜歡第二種設定,就是維持 tab 為四個 space 的顯示。
另外 expandtab 打開的話,並不會影響已經存在檔案中的 tab,如果要整個內文中的 tab 用 space 做取代的話,可以在 vim 中執行這個命令。
:retab!

Vim list mode
有時候你或許想要查看畫面中的空白到底是 tab 還是 space,可以進入 vim 的 list mode,在 vim 中執行這個命令 :set list,tab 會以 ^I 形式顯示,如果要關閉 list mode,執行這個指令 :set nolist。

Indent

在 vim 中還可以進行自動縮排,主要有cindent、smartindent和autoindent三種。

cindent
vim 可以很好的識別出 C 和 Java 等結構化的程式語言,並且能用 C 語言的縮排格式來處理程序的縮進結構。可以用下列命令,啟用cindent。
:set cindent

smartindent
smartindent 在這種縮進模式中,每一行都和前一行有相同的縮進量,同時這種縮進形式能正確的識別出花括號,當遇到右花括號(}),則取消縮進形式。此外還增加了識別C語言關鍵字的功能。如果一行是以#開頭的,那麼這種格式將會被特殊對待而不采用縮進格式。可以使用以下命令,啟用smartindent縮進結構:
:set smartindent

autoindent
autoindent 在這種縮進形式中,新增加的行和前一行使用相同的縮進形式。可以使用以下命令,啟用autoindent縮進形式。
:set autoindent

我個人比較喜愛打開 smartindent 和 autoindent。另外,有時候從其他地方複製了一段程式碼想要直接在vim中貼上,但是會發現程式碼整個都亂掉了,這是因為smartindent發生作用了,這個時候可以直接禁用smartindent。或是在黏貼到 vim 內文前,:set paste,貼完了以後再恢復原狀,:set paste!

Reference

沒有留言:

張貼留言