ねえぶ

猫好きエンジニアのブログ

NeomakeでEslintが動かない場合の対処

以下のブログを参考にSyntasticからNeomakeに乗り換えてみたのですが,私の環境ではEslintがうまく実行されませんでした.

[Vim]SyntasticによるESLintチェックが遅いのでNeomakeに乗り換えた - dackdive's blog

TL;DR

次のようにしたら動きました.

NeoBundle 'neomake/neomake'
NeoBundle 'benjie/local-npm-bin.vim'

augroup ft_javascript
  autocmd!
  " get eslint path of current environment
  function! s:GetEslintExe()
    let l:eslintExe = GetNpmBin('eslint')
    if empty(l:eslintExe)
      return 'eslint'
    else
      return l:eslintExe
    endif
  endfunction

  " set exe of neomake eslint
  autocmd FileType javascript let g:neomake_javascript_myeslint_maker = {
        \ 'exe': s:GetEslintExe(),
        \ 'args': ['-f', 'compact'],
        \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' .
        \ '%W%f: line %l\, col %c\, Warning - %m'
        \ }
augroup END

let g:neomake_javascript_enabled_makers = ['myeslint']
let g:neomake_error_sign = {'text': '>>', 'texthl': 'Error'}
let g:neomake_warning_sign = {'text': '>>',  'texthl': 'Todo'}
call neomake#configure#automake('nrw', 750)

環境

  • Mac 10.13.3
  • MacVim 8.0

現象

参考ブログに倣ってインストールしてみましたが,ローカルのeslintがなく,グローバルのeslintだけある場合にNeomake実行時に次のようなエラーが出ました.

19:31:12 [D +7.45] [-.-:1:1] automake: handling event FileType.
19:31:12 [D      ] [-.-:1:1] Using setting automake.ignore_filetypes=['startify'] from 'global'.
19:31:12 [E +0.02] [-.-:1:1] Exe () of maker eslint is not executable.
19:31:12 [D      ] [-.-:1:1] automake: configured buffer for ft=javascript (no enabled makers).
19:31:12 [D      ] [-.-:1:1] automake: setting tick for new buffer.
19:31:12 [D      ] [-.-:1:1] automake: no enabled makers.

エラーログは次のような設定を入れて出力させました.

let g:neomake_verbose = 3
let g:neomake_logfile = '/tmp/neomake.log'

また,この時:NeomakeInfoを実行すると,eslintのexe項目が空文字でした.

原因

ローカル環境のeslintを使うように調整してくれるbenjie/local-npm-bin.vimが,ローカル環境のeslint(node_modules/.bin/eslint)が見つからない場合にeslintのexeに空文字を設定するようになっていたのが原因でした(該当コードGetNpmBin()はローカル環境の実行ファイルが見つからない時に空文字を返す).

参考ブログのbenjie/neomake-local-eslint.vimから名前から変わっているから,動作が当初から変わってしまったのかな?

解決策

  • myeslintというmakerを新たに定義して,filetypeがjavascriptに変わる時に現在のローカル環境のeslintをmakerのexeにセットするようにしました
  • benjie/local-npm-bin.vimeslintmakerを上書きしてしまうタイミングが後になるからか,eslintmakerをvimrcで書き換える方法ではうまく動きませんでした
" filetype: javascript
augroup ft_javascript
  autocmd!
  " get eslint path of current environment
  function! s:GetEslintExe()
    let l:eslintExe = GetNpmBin('eslint')
    if empty(l:eslintExe)
      return 'eslint'
    else
      return l:eslintExe
    endif
  endfunction

  " set exe of neomake eslint
  autocmd FileType javascript let g:neomake_javascript_myeslint_maker = {
        \ 'exe': s:GetEslintExe(),
        \ 'args': ['-f', 'compact'],
        \ 'errorformat': '%E%f: line %l\, col %c\, Error - %m,' .
        \ '%W%f: line %l\, col %c\, Warning - %m'
        \ }
augroup END

その他

  • 参考ブログではautocmdでNeomakeの実行を設定していましたが,公式の方法に則って以下のようにしました
call neomake#configure#automake('nrw', 750)

syntasticからNeomakeへの乗り換えで変更したdiffは↓で確認可能です.

https://github.com/ottijp/dotfiles/compare/4f8f4690a53cfde376367ac990efc54d59c217fd...36e6207e5a4f290b96dc2eeeb2a0d911ac7666ea