Lightline で ALE を使って非同期文法チェック

# 先に今日やることのまとめ

何か前置きが長くなりそうなので、この記事で実現できることを動画 GIF にしました。

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/8880/05e1a35f-33d0-4297-dfb4-7663f1cd9165.gif)

非同期に文法チェック（lint）が出来てますね！そしてそれがいい感じにステータスラインに出てますね！この記事を読めば出来ます！多分！

# 今時の linter 事情 on Vim

Vim 8.0 の新機能としてもっとも重大なものの一つは job/channel による、プロセスの非同期実行機能でしょう。今まで [vimproc][] 等のプラグインを使わないと出来なかったことが公式にサポートされたのは大きいです。

[vimproc]: https://github.com/Shougo/vimproc.vim

Vim のような（簡易）IDE を使うなら lint 機能は是非欲しいところなのですが、このジャンルの雄であった [Syntastic][] はファイル保存時の linter 実行にしか対応しておらず、ファイルを保存する度に Vim が固まって終わるまで待つという状態でした。これを job/channel を使って改善する方法も[議論されている][699]のですが、過去の遺産が多すぎるためか進捗は芳しくないです。

[Syntastic]: https://github.com/vim-syntastic/syntastic
[699]: https://github.com/vim-syntastic/syntastic/issues/699

# ALE を使おう

過去の遺産をすっぱり捨てて、job/channel を使って一から作られた async linter plugin として、最近一番注目されている（と思う）のが [ALE (Asynchronous Lint Engine)][ale] です。

[ale]: https://github.com/w0rp/ale

使おう、とか書いたのですが、ALE の設定自体はドキュメントもあるのでここには書きません。現在の所ものすごい勢いで linter が追加されている状況ですので、ここに今僕の設定を載せてもすぐに陳腐化すると思います。

この記事では公式ドキュメントにない、又、追加されることもないであろう、[Lightline][] で ALE を使う方法を書こうと思います。

[Lightline]: https://github.com/itchyny/lightline.vim

# Lightline って？

[Lightline][] は所謂 [Powerline][] フォロワーのうちの一つです。本家 Powerline が高機能化に伴ってハイパー重くなっていく中、有力な代替として [Airline][] が登場したのですが、これも機能が増えるに従ってスーパー重くなってしまいました。

[Powerline]: https://github.com/powerline/powerline
[Airline]: https://github.com/vim-airline/vim-airline

それに対して Lightline は機能を絞ることでステータスライン業界最軽量（？）を実現した素晴らしいプラグインです。ただし設定方法が各人の vimrc に密結合するものなので、汎用のものとして紹介しにくいという欠点があります。今回の記事もあくまで僕の設定の紹介という体で書いておりますので、ご注意ください。

# 設定方法（ようやく）

ホントは設定方法をずらずら載せようと思ったのですが、colorscheme まで載せ出すと長すぎてあれなのでレポジトリーにまとめてしまいました。

* [delphinus/lightline-delphinus: Yet another theme for lightline][delphinus]

[delphinus]: https://github.com/delphinus/lightline-delphinus

なのでインストールはこのレポジトリーを好きな plugin manager でクローンするだけ！たとえば [dein.vim][] なら、

[dein.vim]: https://github.com/Shougo/dein.vim

```vim
call dein#add('delphinus/lightline-delphinus')
call dein#add('itchyny/lightline.vim')
```

これだけ！かんたん！

……で済ませてはつまらないので ALE の情報をステータスラインに載せる関数だけ抜き出して解説します。

```vim
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()` 関数用のフォーマットが納められていますので、これを元に文字列を作るだけです。上記ソースは[ここ][]にあります。

[ここ]: https://github.com/delphinus/lightline-delphinus/blob/24684ac8f1675125a3aca9fa75454889ffc5f3b3/autoload/lightline/delphinus/components.vim#L111-L127

ただ、ALE で lint が終わったら、Lightline のこれを通知する必要があります。ALE にはこのために `ALELint` というイベントが用意されています。

```vim
augroup LightLineOnALE
  autocmd!
  autocmd User ALELint call lightline#update()
augroup END
```

これで OK です。簡潔ですね。他のプラグインとの連携もやりやすいと思います。

# ギャラリー

実はこれ 24bit / 256 color 両対応にしてあります。Lightline にも標準で Solarized テーマが付いてくるのですが、そのままではモードが変わったときに分かりづらかったので、各モードの色をできるだけ派手にしました。iTerm2 3.0 以上など、TrueColor 対応のターミナルでお楽しみください。

## Solarized Dark (Improved)

<img width="962" alt="スクリーンショット 2017-04-16 23.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/b6667802-60bb-34cb-d91a-d86a6020b9e8.png">
> <img width="840" alt="スクリーンショット 2017-04-16 23.13.09 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/d4485960-44de-fe3c-897b-8511344e6e10.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/4d752770-772e-4296-be00-763c1bd0d861.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/7673302a-46cc-a620-b840-a3a8d7914ebf.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/53242e9e-9b67-cc23-bfb1-a549d7074f0b.png">

## Solarized Light (Improved)

<img width="962" alt="スクリーンショット 2017-04-16 23.13.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/14b3d338-6f30-4cfa-8880-c207d26b010f.png">
>  <img width="840" alt="スクリーンショット 2017-04-16 23.13.14 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/6018133e-d295-dc91-fb2a-6f04b1151215.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/04ff6d6e-63a8-0905-031d-b19d0149ac1d.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/5df2ae34-aba1-fefc-2a72-8e5c8b8b6891.png">
<img width="840" alt="スクリーンショット 2017-04-16 23.13.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/329c24bb-f90c-8426-9994-92a6c48024c0.png">