neocomplcache.vim のインクルード補完の使い方

neocomplcache v3.06 より、インクルード補完(include_complete.vim)が実装された。作者の Shougo さん一押しの機能なのだが、どういった機能なのかよくわからない人もいると思うので勝手に解説してみる。間違っていたら突っ込みよろしく。

include とは

Vim には標準で 'include' などのオプションがある。このオプションで C の #include や Java の import を探して、現在編集中のバッファと関係ありそうなファイルからキーワードを検索できたりする。

インクルード補完とは

neocomplcache のインクルード補完は、これらの機能を利用して関係ありそうなファイルを探索し、そこから補完候補を出してしまおうという機能。もちろん結果をキャッシュしているので、1 度キャッシュしてしまえば Vim 標準のより速く動作する。

どうすれば使えるの?

まずはインクルードしているファイルのファイル名を正しく認識してくれないと話にならない。そのためには、各オプションを理解して正しく設定する必要がある。
重要なのは以下のオプション。概要は本当に概要なので詳細は :help を参照のこと。
ちなみに include_complete.vim では専用のオプションを使って別の値を使うことができる。このオプションには filetype をキーとする辞書を指定する。

オプション 概要 include_complete オプション
'include' この正規表現にマッチした箇所の後ろにある文字列をインクルードするファイル名として認識する。 g:neocomplcache_include_patterns
'includeexpr' 'include' で抽出した文字列をファイル名に加工するための式。Javaで.を/に変えたりとか。 g:neocomplcache_include_exprs
'path' 見つかったファイルを探すパス。スペースを含むディレクトリは \ でエスケープしておく必要がある。 g:neocomplcache_include_paths
'suffixesadd' ファイルを探す際に、この値を末尾に追加したファイルも探す。大抵は拡張子が指定される。 なし

これらのオプションは多くの場合は標準の filetype プラグインが設定してくれる。


ただ、中には標準ではうまく設定されないオプションもある模様。以下は私がざっと調べたもの。*1

言語(filetype) 設定されない値 設定例
java 'include' setlocal include=^import
python 'path' let &l:path = system('python -', 'import sys;sys.stdout.write(",".join(sys.path))')
haskell 'include' setlocal include=^import
haskell 'includeexpr' setlocal include=substitute(v:fname,'\\.','/','g')
haskell 'suffixesadd' setlocal suffixesadd=.hs

この他、例えば Perl は 'path' の値中のスペースをエスケープしていなかったりといい加減な設定も見られる。
これらの言語を使う場合は設定を見直した方がいいかも。設定例を追加したい場合は ~/.vim/after/ftplugin/{filetype}.vim に書く。

インクルードファイルからキーワードを抽出する

インクルードファイルが見つかったら、include_complete.vim はそこからキーワードを抽出する。キーワードの抽出は以下の順序で行なわれる。

  1. キャッシュがあればそれを使う。
  2. ctags コマンドを使う。
  3. 言語が ctags に対応していない、もしくは ctags がインストールされていない場合は自力でキーワードを探す。

ctags の実行の際は filetype 毎に追加の引数を指定できる。g:neocomplcache_ctags_arguments_list に、例によって filetype をキーに追加したい引数を指定しておけばいい。もちろん ctags 標準の設定ファイルに書いても問題ない。

実際に使ってみる

こんな感じ。Perlの例。

その他

  • インクルードパスの検索は、filetype 決定直後とファイル保存直後に全バッファを一括で行っている模様。
  • 初回はキャッシュを取るので少し時間がかかる。最初は少し我慢。とはいえ Shougo さんも遅いのを気にしているようなのでそのうち改良されるかも?

きちんと設定さえすればかなり使える機能だと思うので、積極的に使ってみよう!とくに 'path' はバッファローカル変数なので工夫のしどころかも。


追記: オプション名を 2011年2月5日時点のものに更新

*1:かなり適当に調べたのであまり鵜呑みにしないでね