job機能を使って非同期にエラーをチェックできるサンプルコードを書きました。
ESLintでJavaScriptのコードをチェックするサンプルを2通り掲載します。
:wなどでバッファの内容をファイルに書き込む時、非同期でエラーをチェックし、エラーがあればQuickFixにエラーを表示させます。
job機能が利用できるVimが必要です。
:echo has('job')
で0が返るVimでは動作しません。
テンポラリファイルにエラーを書き出すパターン
sample.js
if () {
check.vim
function! s:callback(file, channel) abort
execute 'cgetfile ' . a:file
cwindow
wincmd p
echo 'finish'
endfunction
function! s:check() abort
set errorformat=%f:\ line\ %l\\,\ col\ %c\\,\ %m,%-G%.%#
let l:file = tempname()
let job = job_start(add(split('eslint -f compact'), expand('%')), {
\ 'out_io': 'file',
\ 'out_name': l:file,
\ 'close_cb': function('s:callback', [l:file]),
\ })
endfunction
augroup sample
autocmd!
autocmd BufWritePost *.js call <SID>check()
augroup END
Vim起動
vim -Nu NONE -S check.vim sample.js
ここで**:w**でファイルに保存するとQuickFixにエラーが表示されます。
QuickFixの内容
js|1 col 5| Error - Parsing error: Unexpected token )
バッファにエラー内容を出力するパターン
sample.js
if () {
check2.vim
function! s:callback(channel) abort
execute 'cgetbuffer ' . s:bufnr
cwindow
wincmd p
execute 'bwipeout ' . s:bufnr
unlet s:bufnr
echo 'finish'
endfunction
function! s:check() abort
set errorformat=%f:\ line\ %l\\,\ col\ %c\\,\ %m,%-G%.%#
new
let s:bufnr = bufnr('')
setlocal bufhidden=hide
setlocal buftype=nofile
hide
let job = job_start(add(split('eslint -f compact'), expand('%')), {
\ 'out_io': 'buffer',
\ 'out_buf': s:bufnr,
\ 'close_cb': function('s:callback'),
\ })
endfunction
augroup sample
autocmd!
autocmd BufWritePost *.js call <SID>check()
augroup END
ウィンドウを表示せずにバッファを開く方法が分からなかったので**:newでバッファを作成した後、:hideでそのバッファのウィンドウを閉じています。
:1newで小さいウィンドウを作成したほうが良いのか迷いましたが、:newから:hideまで違和感がなかったのでサイズ指定せずに:new**でウィンドウを作成しました。
Vim起動
vim -Nu NONE -S check2.vim sample.js
ここで**:w**でファイルに保存するとQuickFixにエラーが表示されます。
テンポラリファイルを利用したサンプルと同様のエラー内容が表示されました。
QuickFixの内容
js|1 col 5| Error - Parsing error: Unexpected token )
非同期ではないサンプル
おまけ。
チェックが終わるまでカーソルを動かせません。
function! s:check() abort
set errorformat=%f:\ line\ %l\\,\ col\ %c\\,\ %m,%-G%.%#
cgetexpr system('eslint -f compact ' . fnameescape(expand('%')))
cwindow
endfunction
augroup sample
autocmd!
autocmd BufWritePost *.js call <SID>check()
augroup END