もう少し整理してみる。
vim で input モードで tab キーを押した時に、まず以下のオプションが参照される:
- tabstop
- expandtab
tab とスペースの変換という点で見ると、この 2 つがコアになる。tabstop は tab が最大何文字幅分に伸びるかを指定する。expandtab は、tab キーを押した際に対応する文字数分の空白に置き換えるか、および行頭インデントの最小化(つまり、空白を可能ならタブに置き換える処理)をスキップするかを指定する。
一方で、本質的ではない以下のオプションも参照される:
- softtabstop
- shiftwidth
- smarttab
softtabstop は、「タブ幅は標準の 8 桁から変えたくないけど、インデントの単位は 8 じゃない数値にしたい!!」という向きに応えるためにある。タブ幅自体を変えても気にしないなら、このオプションを弄る必要はない。
shiftwidth は、本来は、< と > コマンドによってシフトする際のシフト量を指定するためのものだが、smarttab の状態によっては tab キー押下時に参照されるときがある。
smarttab は、インデント量をカーソルの位置に応じた文脈で選択させるようにする。smarttab がオンの状態で、カーソルが行頭のインデント領域の中にある時、shiftwidth の分だけインデントされる。smtarttab がオフであるか、あるいはオンであってもカーソルが行頭インデントではない箇所にある場合は、softtabstop、tabstop の順に評価して 0 ではない最初の値を取り出し、それをインデント量とする。
とこのように、expandtab 自体は単純明快なのだけど。字下げスタイルという個々人の好みにものすごく左右されるものにできるだけ対応するための、付加的なオプションのおかげで全体的になんだかわよくわからないものになってしまっている。
さらに cpoptions オプションの設定によって微妙に部分的な動作が変わったり、あるいは前の記事の通り backspace オプションが絡んできたり、:retab コマンドの動作にも影響したりする。カオスすぎる。