環境
- Debian
- Vim 7.4.2228
自作のスニペットプラグインを使用してたら頻繁にW19が発生するようになりました。
原因と対策について調べた事を書きます。
原因
自動コマンド発動中にその自動コマンドのグループを削除すると警告としてW19が表示されるようです。
英語に自信がないので、詳しくはヘルプを参照してください。
:h W19
目標
InsertLeaveイベントが発動されたら、Remove()を実行し、自動コマンドとその自動コマンドのグループを削除する。
W19を出すサンプル
バッドサンプル1
インサートモードを抜けた時に自動コマンドと自動コマンドのグループを削除するサンプルコードです。
インサートモードを抜けた時にW19が発生します。
function! Remove() abort
echomsg1autocmd! sample
augroup! sample
endfunction
augroup sample
autocmd!autocmdInsertLeave * call Remove()
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S bad1.vim
Vimを起動するとW19が発生します。
次の3つのコマンドを実行してみます。
:mes
1が表示されました。:au
自動コマンドが消えました。:aug
--削除済-- と表示されました。
W19は出ないけど不完全なサンプル
バッドサンプル2
function! Remove() abort
echomsg1endfunction
augroup sample
autocmd!autocmdInsertLeave * autocmd! sample | augroup! sample |call Remove()
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S bad2.vim
次の3つのコマンドを実行してみます。
:mes
何も表示されません。:au
自動コマンドが消えました。:aug
sampleと表示されました。グループが残ってます。
バッドサンプル3
function! Remove() abort
echomsg1endfunction
augroup sample
autocmd!autocmdInsertLeave * call Remove()|autocmd! sample | augroup! sample
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S bad3.vim
次の3つのコマンドを実行してみます。
:mes
1が表示されました。:au
自動コマンドが消えました。:aug
sampleと表示されました。グループが残ってます。
W19を出さないサンプル
サンプル1
lambda
と timer
の機能を使用してW19を出ないようにbad1.vimを修正しました。
function! Remove() abort
echomsg1autocmd! sample
call timer_start(0, {-> execute('augroup! sample',"")})endfunction
augroup sample
autocmd!autocmdInsertLeave * call Remove()
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S sample1.vim
Vimを起動してもW19が出なくなりました。
次の3つのコマンドを実行してみます。
:mes
1が表示されました。:au
自動コマンドが消えました。:aug
グループが消えました。
サンプル2
lambda
を使わない書き方も載せます。
実行結果はサンプル1と同じです。
function! Callback(timer) abort
augroup! sample
endfunctionfunction! Remove() abort
echomsg1autocmd! sample
call timer_start(0,'Callback')endfunction
augroup sample
autocmd!autocmdInsertLeave * call Remove()
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S sample2.vim
その他
Vim 7.4を切る場合はこれでW19を抑えられましたが、古いVimでどうやって対応して良いのかは分かりません。