Posted at

Vimの非同期文法チェッカALEにプロジェクト固有の情報を教える

More than 1 year has passed since last update.


はじめに

Vimの非同期文法チェックエンジン、ALE (Asynchronous Lint Engine)に、プロジェクト固有の情報を教えたいことがある。典型的なのがC/C++のヘッダのインクルードパスで、makefileで-Iで場所を教えていたりすると、ALEから呼ばれたgccclangがそのパスを探せずにエラーを報告してしまう。これを解決するには以下のようにすれば良い。



  1. .vimrcを修正して、カレントディレクトリに.vimrc.localがあったら読むようにする

  2. ALEに追加情報が必要な場合はそこに.vimrc.localを作って、その中に情報を書く

  3. 例えばC/C++のインクルードパスを教えるにはg:ale_cpp_clang_optionsg:ale_cpp_gcc_optionsに"-std=c++14 -Wall -Ipath/to/header"を指定する


状況

あるプログラムが参照するヘッダのインクルードパスが、コンパイル時に-Iオプションで指定されているものとする。

例えばこんな状況を考える。

project

├── includes/
│   └── hoge.hpp
└── src/
└── test.cpp

test.cppの中身はこんな感じ。


test.cpp

#include <hoge.hpp>


もちろん、makefileには-Iで適切にヘッダファイルの場所を教えているから、問題なくコンパイルできる。

しかし、このsrc/test.cppをALEを有効にした状態のVimで編集すると、「hoge.hppが見つからないよ」と怒られてしまう。

これはALEから呼び出されるclang++g++には-Iオプションが渡されていないのでヘッダが探せないため。


解決法

直接解決するには、g:ale_cpp_clang_optionsg:ale_cpp_gcc_optionsにヘッダの場所を教えてやれば良い。デフォルト値は-std=c++14 -Wallになっているので、今回の場合は

let g:ale_cpp_clang_options = "-std=c++14 -Wall -I../includes"

let g:ale_cpp_gcc_options = "-std=c++14 -Wall -I../includes"

とやってやれば、この警告は消える。しかし、毎回Vimを起動する度に上記の設定をするのは面倒。なのでVimでプロジェクト固有の設定を適用するを参考に、まず.vimrc


~/.vimrc

augroup vimrc-local

autocmd!
autocmd BufNewFile,BufReadPost * call s:vimrc_local(expand('<afile>:p:h'))
augroup END

function! s:vimrc_local(loc)
let files = findfile('.vimrc.local', escape(a:loc, ' ') . ';', -1)
for i in reverse(filter(files, 'filereadable(v:val)'))
source `=i`
endfor
endfunction


と書いて、もしカレントディレクトリに.vimrc.localがあったら読み込むようにする。

その上で、先程のtest.cppと同じディレクトリに


.vimrc.local

let g:ale_cpp_clang_options = "-std=c++14 -Wall -I../includes"

let g: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初心者にはそれだけの情報ではきつかった。


参考