はじめに
Vimの非同期文法チェックエンジン、ALE (Asynchronous Lint Engine)に、プロジェクト固有の情報を教えたいことがある。典型的なのがC/C++のヘッダのインクルードパスで、makefileで-Iで場所を教えていたりすると、ALEから呼ばれたgcc
やclang
がそのパスを探せずにエラーを報告してしまう。これを解決するには以下のようにすれば良い。
.vimrc
を修正して、カレントディレクトリに.vimrc.local
があったら読むようにする- ALEに追加情報が必要な場合はそこに
.vimrc.local
を作って、その中に情報を書く - 例えばC/C++のインクルードパスを教えるには
g:ale_cpp_clang_options
とg:ale_cpp_gcc_options
に"-std=c++14 -Wall -Ipath/to/header"を指定する
状況
あるプログラムが参照するヘッダのインクルードパスが、コンパイル時に-I
オプションで指定されているものとする。
例えばこんな状況を考える。
project
├── includes/
│ └── hoge.hpp
└── src/
└── test.cpp
test.cppの中身はこんな感じ。
#include<hoge.hpp>
もちろん、makefileには-Iで適切にヘッダファイルの場所を教えているから、問題なくコンパイルできる。
しかし、このsrc/test.cpp
をALEを有効にした状態のVimで編集すると、「hoge.hppが見つからないよ」と怒られてしまう。
これはALEから呼び出されるclang++
やg++
には-I
オプションが渡されていないのでヘッダが探せないため。
解決法
直接解決するには、g:ale_cpp_clang_options
とg:ale_cpp_gcc_options
にヘッダの場所を教えてやれば良い。デフォルト値は-std=c++14 -Wall
になっているので、今回の場合は
letg:ale_cpp_clang_options ="-std=c++14 -Wall -I../includes"letg:ale_cpp_gcc_options ="-std=c++14 -Wall -I../includes"
とやってやれば、この警告は消える。しかし、毎回Vimを起動する度に上記の設定をするのは面倒。なのでVimでプロジェクト固有の設定を適用するを参考に、まず.vimrc
に
augroup vimrc-local
autocmd!
autocmd BufNewFile,BufReadPost * call s:vimrc_local(expand('<afile>:p:h'))
augroup ENDfunction! s:vimrc_local(loc)letfiles= findfile('.vimrc.local', escape(a:loc,' ') . ';',-1)foriin reverse(filter(files,'filereadable(v:val)'))
source `=i`endforendfunction
と書いて、もしカレントディレクトリに.vimrc.local
があったら読み込むようにする。
その上で、先程のtest.cpp
と同じディレクトリに
letg:ale_cpp_clang_options ="-std=c++14 -Wall -I../includes"letg:ale_cpp_gcc_options ="-std=c++14 -Wall -I../includes"
というファイルを作ってやればよい。ファイル構成はこんな感じになる。
project
├── includes/
│ └── hoge.hpp
└── src/
├── .vimrc.local
└── test.cpp
この状況でtest.cpp
をVimで開いても、「ヘッダが見つからない」とは怒られない。
まとめ
ALEにプロジェクト固有の情報を伝える方法をまとめた。「C/C++のヘッダは面倒だよね」という話はALEのissueにもなってて、作者も「100%の解決策はないよね〜」みたいなことを書いている。また、冒頭に書いたように本家のFAQに「vimrc-localを使え」と書いてあるんだけれど、僕のようなVim初心者にはそれだけの情報ではきつかった。