neovimらしいeslint

（注）最近は[ale.vim](https://github.com/w0rp/ale)に移行しました。

# 概要

vimでjavascriptを書くための設定をしていたところどうにもシンタックスチェックが遅いの改善しようと思った。

もともとは`Syntastic`と`eslint`使っていたが、保存しないとしてくれないし、そもそも遅い。
eslint自体遅いという話もあるので、非同期できないのか調べたけどまだ出来ない模様。いま取り組んでいるようなので、そのうち出来ると思うけど、そもそもsyntasticがvim用なのでneovimの非同期処理は使わないみたい。

neovimの非同期処理を使ったリンターがないか調べてみたら[あった](https://gregjs.com/vim/2015/linting-code-with-neovim-and-neomake-eslint-edition/)のでそちらに移行することにした。

# Neomake
その名も[Neomake](https://github.com/neomake/neomake)。  
名前からてっきりコンパイルしてくれるやつかと思っていたら、linterとかもしてくれるみたい。それも非同期で！
まだ導入したばかりだけど、問題なく動くし固まらないし良さそう。

## 導入
必要となるのは以下のもの

+ neovim
+ eslint
+ Neomake

### eslint

```
npm install -g eslint
```

### neomake
適当なプラグインマネージャーを使ってインストールしたらいい。
自分の場合、dein.vimを使っているので以下のようtomlで記述している。

```
[[plugins]]
repo = 'neomake/neomake'
on_path = '.*'
hook_add = '''
source  ~/.config/nvim/plugins/neomake.rc.vim
'''
```

```vim
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Neomake setting

" 保存時とenter時にNeomakeする
autocmd! BufWritePost,BufEnter * Neomake

let g:neomake_javascript_enabled_makers = ['eslint']
```

簡潔にするために、`neomake.rc.vim`にneomakeの設定を書いているが、上記の設定は`.vimrc`や`init.vim`に書いてもいい。

基本的にこれだけで動くはずである。ダメだった場合
`let g:neomake_verbose=3` や `let g:neomake_logfile='/tmp/neomake.log'`を設定してみてデバッグしよう。

eslintの場合、`.eslintrc`に設定を書いているので特に引数を与える必要は無いと思うけど、以下のようにパラメータを付与することが出来る（試していないので保証できないが）。

```vim
let g:neomake_javascript_eslint_maker = {
    \ 'exe': 'eslint',
    \ 'args': ['-f', 'compact'],
    \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' .
        \ '%W%f: line %l\, col %c\, Warning - %m'
    \ }
```

## 使い方
jsファイルを開くとしばらくしたらgutterにマークが出るはずである。
その行に行くとエラーの内容が見える。

エラーの一覧はlocation listにある。
なので以下のコマンドが使える。

|コマンド|説明|
|:---|:----|
|:lopen|location listを閉じる|
|:lclose|location list を閉じる|
|:lnext|次のエラーに移動|
|:lprev|前のエラーに移動|

# eslint_d
mysticateaさんに[eslint_d](https://github.com/mantoni/eslint_d.js)なるものがあると教えてもらったので使ってみた。
eslint_dはeslint用のサーバーを立上けることで立ち上げのオーバーヘッド(〜700ms)をなくして高速化を図ったものらしい。特にjs環境でないvimなどはlintするたびに別プロセスを立ち上げるので特に有効なはずである。

eslint_dはeslint3.0.0+対応している。

# 導入

```
npm i -g eslint_d
```

neomake自体はeslint_dに対応しているので、以下のようにするだけでいい。
ついでにインサートモードを抜けた時もlintするようにした。
また、vim終了時にeslint_dを閉じるようにした。

```neomake.rc.vim
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Neomake

augroup neomake_run
  " 保存時とenter時にlintする
  autocmd! BufWritePost,BufEnter * Neomake

  " インサートモードを抜けた時もlint
  autocmd! InsertLeave *.js Neomake 

  " vim終了時にeslint_dを終了
  autocmd! VimLeave *.js  !eslint_d stop
augroup END

let g:neomake_javascript_enabled_makers = ['eslint_d']
```

### おまけ
実際どれだけ速いのか試してみた。

```
❯ wc test.js
     798    2474   24938 test.js

❯ time eslint test.js
eslint test.js  1.05s user 0.14s system 105% cpu 1.123 total

❯ time eslint test.js
eslint test.js  1.08s user 0.13s system 110% cpu 1.092 total

❯ time eslint test.js
eslint test.js  1.00s user 0.12s system 114% cpu 0.978 total

❯ time eslint_d test.js
eslint_d test.js  0.12s user 0.07s system 12% cpu 1.495 total

❯ time eslint_d test.js
eslint_d test.js  0.10s user 0.07s system 43% cpu 0.405 total

❯ time eslint_d test.js
eslint_d test.js  0.10s user 0.06s system 48% cpu 0.326 total

❯ time eslint_d test.js
eslint_d test.js  0.10s user 0.07s system 52% cpu 0.336 total

```

2回目以降は2倍ほど速い！