Vimでインデントを増減する方法(>> / << / shiftwidth)
Pythonのようにインデントが構文上の意味を持つ言語では、行の字下げを素早く調整できるかどうかが編集速度に直結します。Vimでは1行でも、範囲を選んでの一括インデントでも、キー2つで完結します。
目次(10項目)
| キー | これだけ覚える |
|---|---|
| >> / << | カーソル行のインデントを増やす/減らす |
| Ctrl-t / Ctrl-d | インサートモード中にインデントを増やす/減らす |
| gv | 直前の選択範囲を再選択 |
1行のインデントを増減する
function foo() {
console.log(1);
}
function foo() {
console.log(1);
}
反対に<<を押せば、同じ行のインデントを1段減らせます。インサートモードでは、行頭に近い位置で次のキーが使えます。
Ctrl-t " インデントを増やす
Ctrl-d " インデントを減らす
複数行をまとめてインデントする
ビジュアルモードで範囲を選択してから同じキーを使います。
v{範囲選択}> " 選択範囲を右にずらす
v{範囲選択}< " 選択範囲を左にずらす
関数の中身をまとめてインデントし直したいときや、if文の追加でブロック全体を1段深くしたいときに便利です。ビジュアルモードで>を押すと選択が解除されてしまうが、続けて調整したい場合はgvで直前の選択範囲を再選択できます。
gv> " 直前の選択範囲を再選択してもう1段インデント
カウントで複数回分をまとめて指定する
3>> " カーソル行から3行分をまとめて右にインデント
行数を数字で前置きすれば、ビジュアルモードを使わずに複数行へ一度に適用できます。ビジュアルモードで選択してから数字を掛け合わせる書き方もできます。
v{範囲選択}2> " 選択範囲を2段右にインデント
操作を繰り返す
インデント操作もドットコマンドで繰り返せます。同じ深さのブロックが複数箇所にある場合、1箇所だけ>>を実行してから、次の行に移動して.を押せば同じインデント量をそのまま再現できます。
>> " 1行目をインデント
j. " 次の行へ移動して同じ操作を繰り返す
インデント幅を決めるオプション
1回の>>/<<でどれだけ動くかは'shiftwidth'オプションで決まります。
set shiftwidth=4 " 1回のインデントで4桁分移動する
タブとスペースの扱いに関わる'expandtab'・'tabstop'とセットで設定しておくと、言語ごとの慣習(Pythonなら4スペース、YAMLなら2スペースなど)に合わせたインデント幅を統一できます。ただしこれらはこれから打つキーにしか効かないので、すでにあるタブは:retabで置き換えます。
autocmd FileType python setlocal shiftwidth=4 expandtab
autocmd FileType yaml setlocal shiftwidth=2 expandtab
複数のファイルタイプを行き来していると、shiftwidthを統一していないと1つの>>で意図しない桁数動いてしまい違和感が出ます。FileType別にautocmdでshiftwidthを固定するようにしてから、言語を切り替えるたびに違和感を覚えることがなくなりました。
shiftwidthを0にしておくと、ずらす幅としてtabstopの値が使われます。手元のVim 9.1.1752でtabstop=4とtabstop=8それぞれにshiftwidth=0を組み合わせて>>を押すと、字下げはそれぞれ4文字ぶんと8文字ぶんになりました。2つの値を別々に管理して片方だけ直し忘れる、という事故を避けたいときに使えます。
shiftround で桁を揃え直す
字下げが中途半端な桁で止まっているファイルを触ると、>> がそのずれを引きずったまま加算します。3桁目から始まる行を shiftwidth=4 でずらせば7桁目になり、他の行と揃いません。
set shiftround を書いておくと、ずらした結果が shiftwidth の倍数に丸められます。手元のVim 9.1.1752で shiftwidth=4 と shiftround を設定し、1桁ぶん字下げされた行に >> を押すと、5桁目ではなく4桁目に揃いました。
set shiftwidth=4
set shiftround " ずらした結果を4の倍数に丸める
他人が書いたファイルや、複数のエディタが混ざったリポジトリを触るときに効きます。逆に、意図して半端な桁に置いている箇所があるなら、丸められて困るので設定しないほうが無難です。
コマンドラインからずらす
離れた行や広い範囲を動かすときは、カーソルを持っていかずにコマンドラインで指定できます。:2,4> なら2行目から4行目までを1段、:2>> なら2行目を2段、:2> 3 なら2行目から3行ぶんを1段ずらします。いずれもVim 9.1.1752で確認しました。
:2,4> " 2〜4行目を1段右へ
:2>> " 2行目を2段右へ
:2> 3 " 2行目から3行ぶんを1段右へ
エラーメッセージが行番号を出してきたときのように、直す場所が数字で分かっている場面ではこちらが速く済みます。範囲を % にすればファイル全体です。
= との使い分け
字下げを何段動かすかを自分で決めるのが >> と << なのに対して、ファイルの種類の規則に任せて整えるのが = です。== で1行、=G でカーソル行からファイル末尾まで、=ap で段落を整形します。
貼り付けた直後の崩れたコードを直すなら = が向きます。段数が分かっていて機械的にずらしたいだけなら >> です。Pythonのように字下げが構文の一部になっている言語では、= がどこまで面倒を見てくれるかが言語ごとの設定に依存するので、結果を確かめてから常用するかを決めてください。
整形結果が意図と違うときに見るのは indentexpr と equalprg の2つです。前者はVim内部の整形ルール、後者は外部コマンドに任せる設定で、後者が設定されているとそちらが優先されます。
まとめ
インデントの増減は>>/<<が基本、複数行はビジュアルモードかカウント指定でまとめて処理できます。'shiftwidth'を言語ごとに設定しておけば、インデントのずれに悩まされることが減ります。インデントが空白かタブかを目で確かめたいときは不可視文字の表示が役に立ちます。複数行をまとめて動かす操作は移動コマンドと組み合わせると範囲指定が楽になります。
ここで扱ったキーは、ブラウザ上で動くVim道場の行をつなぐ・字下げを変えるでそのまま試せます。インストールもログインも要りません。