Vimではプラグインを入れることでプログラミングコードの 構文をチェックしてエラーなどをハイライトすることが出来ますが 構文チェック用のプラグインを新しくして ALE を使い始めました。
VimのSyntaxチェッカープラグイン
構文チェック用のプラグインとして老舗で一番有名なのは syntastic だと思います。
今まではこれを使ってました。 このプラグインは同期処理で行っていて保存時等に 構文チェックを行います。
一方、 最近、NeoVimの登場やVim 8 でも非同期な操作が可能になったことから 非同期で処理できるプラグインも出てきました。
- osyo-manga/vim-watchdogs: Async syntax checking.
- neomake/neomake: Asynchronous linting and make framework for Neovim/Vim
- w0rp/ale: Asynchronous Lint Engine
watchdogsなんかはVim自体で非同期処理が出来る様になる前に vimproc などを用いて非同期処理を行える様にしていました。 watchdogsは一時期使っていましたが全体的な動作がもっさりしてしまう状態になったこともあり Syntasticに戻していました。 これを今使うには余計なものを入れる必要が出てくるのでちょっと古い感じです。
NeomakeやALEはVim自体の非同期処理を使ったもので、 ALEの方が新しいプラグインだと思いますがGitHubのスターだとすでにALEの方が多くなっています。
後継ということもあってNeomakeからALEに移った、というブログ記事もちらほら見かけました。
Neomakeも以前使ったことがありましたが、やはり動作に影響がある感じがあったので Syntasticに戻していました。
今回また色々見直してる中でALEという新しいプラグインを見つけた、という状態で試してみることにしました。
Asynchronous Lint Engine (ALE)
インストールはプラグイン管理プラグインなんかで適当に。
1 2 3 4 5 6 |
|
job
、channel
、timers
は
Vim 8.0で導入された非同期関連の新しい機能で
2
aleではこれらの機能付きでコンパイルされている事を要求します。
(通常のインストールなら入っているはず。)
こんな感じで書いておくと非同期処理が使えない環境ではSyntasticを使う、ということも出来ます。
ALEのレポジトリがちょっと大きい(~20MB)ので、場合によってインストール時にタイムアウトになってしまいインストールエラーが起こる可能性があります。 deinだと初期値で120秒になってますが、実際に
[dein] /home/user/.vim/dein/repos/github.com/w0rp/ale
[dein] Remove the installed directory:/home/user/.vim/dein/repos/github.com/w0rp/ale
[dein] Process timeout: (xxxx/xx/xx xx:xx:xx)
[dein] Error installing plugins:
[dein] ale
[dein] Please read the error message log with the :message command.
こんな感じのエラーが出てしまう環境がありました。 試しに
$ git clone https://github.com/w0rp/ale
とかやってみて、clone出来るものの時間がかかるようだったら
let g:dein#install_process_timeout = 600
を.vimrcに加えると600秒待つことが出来ます。
プラグインの設定はこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
dein_enabled
はファイルの最初の方で自分で設定している変数です。
まず最初にg:ale_lint_on_enter
を0にして
ファイルを開いた瞬間のチェックを外しています。
(開く時はぱっと開きたいし、ただ見たいだけでエラー表示も必要ないこともあるので。)
<Subleader>
は<Leader>
の様に使える様にしてあり、
<Space>
にあてています。
(<Leader>
は,
に変更。)
1 2 3 4 5 |
|
これを使って前/次のerrorやwarningが出てる行に飛ぶキーをSpace-P/N
に割り当てています。
ここではale_previous
/ale_next
と言った値を使ってますが、
ale_previous_wrap
/ale_next_wrap
と言う一番上/下に行った後に
一番下/上に周って検索を続ける、というmappingの値もあります。
ale_toggle
はaleをオン/オフする機能。
その後でALEList
というコマンドを定義してこれを:ALEList
と実行すると
別ウィンドウでエラー/警告一覧を出せる様にしています。
g:ale_open_list
を1にしておくとこの別ウィンドウが出る様になりますが常にあると邪魔なので。
これも<Subleader>m
に割り当てています。
ウィンドウを出した後、そのウィンドウに行って消すだけだとその後のチェックの際にまた開いてしまうので、
ウィンドウタイプがqf
(quickfix)の時にはg:ale_open_list = 0
してから閉じる様にしています。
MyAutoGroup
は.vimrcの中で他のグループに属さないものを全部入れてるグループです。
元々、
autocmd MyAutoGroup FileType help,qf,man,ref nnoremap <silent> <buffer> q :q!<CR>
の様な設定をしていてヘルプとかquickfixとか編集用に開いたものでない場合には
Qを押すだけで閉じる用にしていたのでqf
のときだけちょっと加える形で。
ALE
のウィンドウのときだけ、というのをやりたいところですが
特別な名前を付けてるわけでもなさそうなのでとりあえずはこれで。
加えてこれらhelp
やqf
などでは基本編集はしないですし構文チェックする必要もないので
そのバッファではALEをオフにするようにバッファ変数のb:ale_enabled
を0にしています。
この辺ALE本体にあったらいいな、と思う機能でもあるのできちんと出来たらプラグインに加えて見てPull Requestしてみるかも。
その次ではlightlineのプラグインを入れている時、
ステータスラインにaleに関する表示を出すので
ALELint
(構文チェック)を行った際にすぐにステータスラインをアップデートするための設定です。
(lightlineについては後述。)
最後には各言語のチェッカー(linter)に関するオプションですが、
ここではshellcheck
に対するオプションで
source
する先が変数だったりする時に出すwarningなどをオフにする設定です。
ALEでは使用できるlinter全てを使って補完的にエラーやおかしなところを探して結果を出す様です。 (Syntasticとかだと複数のlinterがある場合には最初のlinterでエラーなどが無ければ次ので探して、 みたいなことをやります。)
linterを指定したいときには
1 2 3 |
|
の様な感じで指定するとそのlinterだけを使うようになります。
SyntasticやNeomakeに比べるとaleで最初に指定してあるlinterはまだ少し少ない感じもありますが 有用なものはどんどん追加されてくと思います。
lightlineでの表示
lightline側で以下のような設定を加えることで
なにも問題ない時はOK
、エラーなどがある場合にはE: 10 W:8
の様にエラーの数などを表示できる様になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
実際には他の表示との兼ね合いでちょっと違った設定を使ってます。 実際に使ってるのは下記で。
いずれにしろ大事なのはale#statusline#Count(bufnr(''))
で現在の情報を取ってこれるという所。
(Count
の引数はバッファ番号でbufnr('')
で現在のバッファ番号を与えています。)
取れるのは辞書オブジェクトで、
- error : 構文エラーの数。
- warning : 構文警告の数。
- info : インフォタグの付いた数。
- style_error : スタイルに関するエラーの数。
- style_warning : スタイルに関する警告の数。
- total : トータル数。
これらを使って後は好きなように表示するだけです。
これに対してALEGetStatusLine()
(またはale#statusline#Status()
)という
直接適当な形で情報を表示を返してくれる関数もありますが、
これはdeprecatedということなのでCount
を使って表示を作るべきです。
(g:ale_echo_msg_format
という変数もこの出力のためだけのなので使わない。
ちょっと前のブログ記事だとALEGetStatusLine
を使ってるのが多いのでちょっと注意。)
表示はリスト表示もするとこんな感じになります。
vim-airlineでの表示
vim-airline もステータス表示プラグインですが、 こちらにはALE用の設定が元々あり、
let g:airline#extensions#ale#enabled = 1
をするだけで表示できる様になります。
必要な場合はALEのREADMEに従って表示を変更することも可能です。
その他のメモ
コマンド
ALELint
: チェックを手動実行。ALEFix
:g:ale_fixers
で指定された修正の実行(fixersは自分で指定する必要がある)。ALEFixSuggest
: 現在のバッファでの修正の提言。'remove_trailing_lines' - Remove all blank lines at the end of a file.
というのがどこでも出る。(fixerを指定しないとこれが出る?)
オプション
g:ale_completion_max_suggestions
: 1にすると補完が出来るようになる。- Neocompleteを使ってるので取り敢えずオフのまま。
g:ale_fixers
:ALEFix
で使う修正用ツールの指定。g:ale_fix_on_save
: 1だとファイルを保存するタイミングでALEFix
を行う。初期値0。- チェックのタイミング:
g:ale_lint_on_enter
: ファイルを開いた時にチェックを実行。初期値1。設定で0に。g:ale_lint_on_filetype_changed
: filetypeが変わった時にチェックを実行。初期値1。g:ale_lint_on_save
: ファイルを保存する時にチェックを実行。初期値1。g:ale_lint_on_text_changed
: 内容が変更された時にチェックを実行。初期値1。余りにガチャガチャしすぎなら0に。g:ale_lint_on_insert_leave
: インサートモードを終了する時にチェックを実行。初期値0。text_changed
を0にしたらこちらを1にした方が良い。
g:ale_maximum_file_size
: チェックを行う最大ファイルサイズ。初期値は0。1以上に設定するとそのbyte数より大きいファイルをチェックしない。- 使ってて辛いのが出てきたら設定してみる。
- 左枠の表示の調整:
g:ale_sign_column_always
: 1にするとエラーや警告がない場合でも左側にその分の枠を空けておく。初期値0。ガチャガチャ動くのが嫌な場合は1に。g:ale_sign_offset
: signのオフセット。初期値1000000。エラー箇所にsignのIDを振っておいてそこにjump出来たりするようにしている。Vimの機能で他のプラグインも含めてIDはユニークじゃないといけない。もし他のプラグインを入れて上手く動作しない場合は同じ様な初期値からIDを振ってる可能性がありその場合はこの初期値を変える事で回避できる。- ALEの様に大きな番号のオフセットを使ってるものは無かったが幾つか
sign place
を使ってるプラグインがあって小さい番号でconflictが起こりそうな感じもあったので今後注意してみる。
- ALEの様に大きな番号のオフセットを使ってるものは無かったが幾つか
g:ale_sign_error
: エラーの指標。初期値>>
。g:ale_sign_warning
: 警告の指標。初期値--
。g:ale_sign_info
: インフォの指標。初期値g:ale_sign_warning
。g:ale_sign_style_error
: スタイルエラーの指標。初期値g:ale_sign_error
。g:ale_sign_style_warning
: スタイル警告の指標。初期値g:ale_sign_warning
。
- リスト表示
g:ale_open_list
: 1でエラーや警告一覧を別ウィンドウで表示する様にする。初期値0。g:ale_keep_list_window_open
: 1でエラーや警告がない場合でも一覧用のウィンドウを消さない様にする。初期値0。g:ale_list_window_size
: 一覧表示用ウィンドウサイズ。初期値10。
g:ale_set_loclist
: 1でエラーなどの一覧をloclist
に保存。初期値1。g:ale_set_quickfix
: 1でエラーなどの一覧をquickfix
に保存。初期値0。loclist
ではなくquickfix
にしたい場合は上を0にしてこれを1に。
まとめ
とりあえず入れてみて使ってる感じでは特に動作に影響は無いように見えます。 (マシン自体の向上もありますが。)
Syntasticで行っていた様なことは出来ているのでしばらく使ってみます。