【一人 vimrc Advent Calendar 2017】vimrc で安全に autocmd を設定する【3日目】

一人 vimrc Advent Calendar 2017 3日目の記事になります。
今回は autocmd について書きます。

autocmd とは

autocmd とは『任意のタイミング』に処理をフックするための機能です。
例えば、 『バッファに入る度にバッファ名をフルパスで表示する』 みたいな機能を実装する場合は以下のような感じになります。

" フックするタイミング:BufEnter(バッファに入った後)
" フックを実行する対象: *(全て)
" 実行する処理:echo expand("%:p")
autocmd BufEnter * echo expand("%:p")

フック可能なタイミングは :help autocmd-events-abc を参照してください。

vimrcautocmd を設定する場合の問題点

さて、Vim を使っていると『Vim を起動している時に vimrc を書き換えて vimrc を再読込する』みたいなことをすることが多いです。
しかし、先ほどのような autocmd の設定を vimrc に記述していると『vimrc を再読込する度に autocmd が新しく追加されてしまう』という問題が発生します。

" vimrc を読み込む度にこの autocmd が追加されてしまう!
autocmd BufEnter * echo expand("%:p")

なので vimrc などで autocmd を記述する場合は少し工夫する必要があります。

augroup を使って autocmd をまとめる

このような場合に autocmd をグループ化する augroup を使います。

" autocmd を "vimrc" という名前でグループ化
augroup my_vimrc
   " グループ内の autocmd をリセットする
    autocmd!

   " グループ内で autocmd を定義する
    autocmd BufEnter * echo expand("%:p")
augroup END

上記のように augroup を使用することで『そのグループで設定した autocmdを一括で削除すること』ができます。
これにより『最初に一括で autocmd を削除すること』で autocmd が重複することを防ぐことができます。
また、これは以下のようにグループ名を指定して autocmd を定義することもできます。

augroup my_vimrc
    autocmd!
augroup END

" autocmd にグループ名を指定する
autocmd my_vimrc BufEnter * echo expand("%:p")

前者のように augroup 内で autocmd の設定を完結するか、後者のように autocmd に対してグループ名を記述するかは好みによって使い分けるとよいと思います。

vimrcautocmd を設定しやすくする

先ほどの後者のように『autocmd にグループ名を指定して定義する』場合、次のようなヘルパコマンドを定義しておくと autocmd が設定しやすくなります。

augroup vimrc
    autocmd!
augroup END

" グループ名を一緒にして autocmd を定義する
command! -nargs=*
\   MyAutocmd
\   autocmd my_vimrc <args>

" 定義したコマンドで autocmd を定義する
MyAutocmd BufEnter * echo expand("%:p")

こんな感じで同じようなコマンドを何回も定義する必要がある場合は、自前でコマンドを定義しておくと記述が簡単になりますし、安全になります。

まとめ

  • autocmd は重複して設定される可能性があるので注意して使おう
  • 何回も使うような記述は自分でコマンドを定義しておくと簡単になる
  • また vimrc は再読込される可能性を考慮して設定しよう

autocmd は他の設定とは違い上書きするような挙動ではないので注意して使いましょう。