pythonとrubyだと、コーディングルールのインデント幅が違います。これを毎回設定するのはわずらわしいので、vimに自動で切り替えてもらいましょう。拡張子で処理を切り分けることができます。
FileTypeで処理を分ける
vimにはFileTypeというオプションが定義されています。もしFileTypeがpythonの時に実行したい設定がある場合は、~/.vim/ftplugin/python.vim
を作成します。次の設定だと、ファイルを開いた時に"filetype python"という文字列が画面の下に出力されます。
echo 'filetype python'
上記のファイルを自動実行させるために、開いたファイルの拡張子によって自分でファイルタイプを定義する必要があります。拡張子がpyの時はpython、rbのときはrubyというFileTypeを定義することにしましょう。setfiletype
で設定するファイルタイプ名は大文字小文字は区別されません。pythonでもPyThoNでも同じです。
このFileTypeを定義する処理は~/.vimrc
に書いて大丈夫です。実行さえされればいいので。
autocmdBufRead,BufNewFile *.pysetfiletype python
autocmdBufRead,BufNewFile *.rb setfiletyperuby
これで拡張子がpyの時は~/.vim/ftplugin/python
が、rbの時は~/.vim/ftplugin/ruby
が実行されます。今回は自分でFileTypeを設定しているので好きな文字列を定義することができます。
autocmdBufRead,BufNewFile *.pysetfiletype FoO
この場合は拡張子がpyの時に~/.vim/ftplugin/foo
が実行されます。ftplugin以下のファイル名ですが、_(アンダーバー)以降は無視されます。例えば、FileTypeがpythonときは次のどの名前のものでも実行されます。複数の対象ファイルが同時に存在する時は、私の場合は1つしか実行されませんでした。
- python.vim
- python_150704.vim
- python_main.vim
また、FileTypeはファイル名の接頭辞で判断されるだけでなくディレクトリ名も判断します。~/.vim/ftplugin/python_main.vim
というのは、~/.vim/ftplugin/python/main.vim
でも同じ動作をします。
autocmdとは?
autocmdについてですが、これはvimの特定のイベント時に処理を実行させるコマンドです。使い方は次の通りです。
autocmd イベント名 ファイル名 実行コマンド
今回はBufReadとBufNewFileという新規ファイルと既存ファイル読み込み時に起きる2つのイベントを指定しています。これらのイベントが起きてなおかつ拡張子がpyの時に、ファイルタイプを決定するようにしているのです。詳細はVim documentation: autocmdでどうぞ。ちなみに、autocmdはauとも書くことができます。
イベント名の一覧はVim documentation: autocmdで確認することができます。
augroupと自動コマンドの重複設定
vimを起動中に:source ~/.vimrc
を実行すると.vimrc
をvimを終了せずに再読み込みすることができます。もし.vimrc
に次の処理が書かれていて再読み込みをします、その後に新しいファイルを開くと、読み込んだ回数分だけhelloと表示されるようになってしまいます。vimを終了した場合は元に戻ります。
autocmdBufRead,BufNewFile * echo 'hello'
この時はautocmd
の後ろに!(エクステンションマーク)をつけます。これで設定された自動コマンドを削除するので、1回しかコマンドが設定されないことになります。
複数のautocmdは複数のグループに分けて整理することができます。グループに分けることによって、自動コマンドの起動や削除をグループ単位で指定することができます。グループ化にはaugroup
を使います。次は2つのautocmd
をMyGroupというグループに登録しています。
augroup MyGroup
autocmd!autocmdBufRead,BufNewFile *.pysetfiletype python
autocmdBufRead,BufNewFile *.rb setfiletyperuby
augroup END
一番最初のautocmd!
はMyGroupの自動コマンドを削除するという意味です。これがないと同じコマンドが重複されて設定されてしまいます。
vimのインデントオプション
vimの設定の仕方がわかったところで、本題に入りましょう。vimには次のようなインデントを設定するオプションがあります。これを使って自動コマンドを設定するだけです。
オプション名 | 補足 |
---|---|
expandtab | tabキーを押すとスペースが入力される |
tabstop | 画面上で表示する1つのタブの幅 |
softtabstop | いくつの連続した空白を1回で削除できるようにするか |
shiftwidth | 自動インデントでのインデントの長さ |
autoindent | 改行した時に自動でインデントします |
smartindent | {があると次の行は自動で1段深く自動インデントしてくれる |
smartindentはC言語を知っている人には、ブロックごとのインデントといえばわかりやすいでしょうか。
tabstopは、タブ文字(\t)の表示する際の幅です。1つのタブ文字を何文字分で表示するかという見栄えの変更のみです。すごい長くしても実際のデータとしてはタブは1文字分しか記録されていません。これはexpandtabを有効にしている人にはタブがスペースで展開されているので、見た目に変化はありません。意図的にタブ文字を入力した場合は別ですが。
タブ文字にしておくと、tabstopでいつでも自由に見た目の幅を変更することはできますが、スペースの場合は常に固定ということになります。
私はFileTypeごとに.vim
ファイルを作るのをやめて、.vimrc
にすべて記述することにしました。今は拡張子ごとにインデントを変えたいだけなので、設定が多くなってきたらファイルを分けたいと思います。それと.vimrc
にまとめておけば一度に俯瞰できるので便利です。
settabstop=4setshiftwidth=4setsofttabstop=4setexpandtabsetautoindentsetsmartindent
augroup fileTypeIndent
autocmd!autocmdBufNewFile,BufRead *.pysetlocaltabstop=4softtabstop=4shiftwidth=4autocmdBufNewFile,BufRead *.rb setlocaltabstop=2softtabstop=2shiftwidth=2
augroup END
これで拡張子pyとrbによってタブ幅が自動で変わるにようになりました。それ以外のファイルではデフォルトの4になります。これはグループの外で常に設定しているからです。その上から条件にあったらautocmdで上書きしているわけです。
set
ではなくsetlocal
を使っている理由は、未設定の拡張子のファイルを開いた場合に自動で開くようにするためです。localというは今開いているファイル(バッファ)のみということです。もし、localにしない場合は次のようになります。
- foo.rbを開く
- タブ幅は4になる
- タブ幅は2に上書きされる
- bar.txtを開く
- タブ幅は2のまま
localにした場合は次の通りです。
- foo.rbを開く
- タブ幅は4になる
- タブ幅は2に上書きされる(現在のバッファのみ)
- bar.txtを開く
- 2の設定が解除される
- タブ幅はデフォルトの4に戻る
これで複数の言語をスムーズに記述できるようになりました。