先に今日やることのまとめ
何か前置きが長くなりそうなので、この記事で実現できることを動画 GIF にしました。
非同期に文法チェック(lint)が出来てますね!そしてそれがいい感じにステータスラインに出てますね!この記事を読めば出来ます!多分!
今時の linter 事情 on Vim
Vim 8.0 の新機能としてもっとも重大なものの一つは job/channel による、プロセスの非同期実行機能でしょう。今まで vimproc 等のプラグインを使わないと出来なかったことが公式にサポートされたのは大きいです。
Vim のような(簡易)IDE を使うなら lint 機能は是非欲しいところなのですが、このジャンルの雄であった Syntastic はファイル保存時の linter 実行にしか対応しておらず、ファイルを保存する度に Vim が固まって終わるまで待つという状態でした。これを job/channel を使って改善する方法も議論されているのですが、過去の遺産が多すぎるためか進捗は芳しくないです。
ALE を使おう
過去の遺産をすっぱり捨てて、job/channel を使って一から作られた async linter plugin として、最近一番注目されている(と思う)のが ALE (Asynchronous Lint Engine) です。
使おう、とか書いたのですが、ALE の設定自体はドキュメントもあるのでここには書きません。現在の所ものすごい勢いで linter が追加されている状況ですので、ここに今僕の設定を載せてもすぐに陳腐化すると思います。
この記事では公式ドキュメントにない、又、追加されることもないであろう、Lightline で ALE を使う方法を書こうと思います。
Lightline って?
Lightline は所謂 Powerline フォロワーのうちの一つです。本家 Powerline が高機能化に伴ってハイパー重くなっていく中、有力な代替として Airline が登場したのですが、これも機能が増えるに従ってスーパー重くなってしまいました。
それに対して Lightline は機能を絞ることでステータスライン業界最軽量(?)を実現した素晴らしいプラグインです。ただし設定方法が各人の vimrc に密結合するものなので、汎用のものとして紹介しにくいという欠点があります。今回の記事もあくまで僕の設定の紹介という体で書いておりますので、ご注意ください。
設定方法(ようやく)
ホントは設定方法をずらずら載せようと思ったのですが、colorscheme まで載せ出すと長すぎてあれなのでレポジトリーにまとめてしまいました。
なのでインストールはこのレポジトリーを好きな plugin manager でクローンするだけ!たとえば dein.vim なら、
call dein#add('delphinus/lightline-delphinus')
call dein#add('itchyny/lightline.vim')
これだけ!かんたん!
……で済ませてはつまらないので ALE の情報をステータスラインに載せる関数だけ抜き出して解説します。
function! s:ale_string(mode)
if !exists('g:ale_buffer_info')
return ''
endif
let l:buffer = bufnr('%')
let [l:error_count, l:warning_count] = ale#statusline#Count(l:buffer)
let [l:error_format, l:warning_format, l:no_errors] = g:ale_statusline_format
if a:mode == 0 " Error
return l:error_count ? printf(l:error_format, l:error_count) : ''
elseif a:mode == 1 " Warning
return l:warning_count ? printf(l:warning_format, l:warning_count) : ''
endif
return l:error_count == 0 && l:warning_count == 0 ? l:no_errors : ''
endfunction
ALE の error/warning 個数は ale#statusline#Count()
という便利関数で得られます。g:ale_statusline_format
に printf()
関数用のフォーマットが納められていますので、これを元に文字列を作るだけです。上記ソースはここにあります。
ただ、ALE で lint が終わったら、Lightline のこれを通知する必要があります。ALE にはこのために ALELint
というイベントが用意されています。
augroup LightLineOnALE
autocmd!
autocmd User ALELint call lightline#update()
augroup END
これで OK です。簡潔ですね。他のプラグインとの連携もやりやすいと思います。
ギャラリー
実はこれ 24bit / 256 color 両対応にしてあります。Lightline にも標準で Solarized テーマが付いてくるのですが、そのままではモードが変わったときに分かりづらかったので、各モードの色をできるだけ派手にしました。iTerm2 3.0 以上など、TrueColor 対応のターミナルでお楽しみください。