環境
- Debian
- Vim 7.4.2228
自作のスニペットプラグインを使用してたら頻繁にW19が発生するようになりました。
原因と対策について調べた事を書きます。
原因
自動コマンド発動中にその自動コマンドのグループを削除すると警告としてW19が表示されるようです。
英語に自信がないので、詳しくはヘルプを参照してください。
:h W19
目標
InsertLeaveイベントが発動されたら、**Remove()**を実行し、自動コマンドとその自動コマンドのグループを削除する。
W19を出すサンプル
バッドサンプル1
インサートモードを抜けた時に自動コマンドと自動コマンドのグループを削除するサンプルコードです。
インサートモードを抜けた時にW19が発生します。
function! Remove() abort
echomsg 1
autocmd! sample
augroup! sample
endfunction
augroup sample
autocmd!
autocmd InsertLeave * 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
echomsg 1
endfunction
augroup sample
autocmd!
autocmd InsertLeave * 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
echomsg 1
endfunction
augroup sample
autocmd!
autocmd InsertLeave * 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
echomsg 1
autocmd! sample
call timer_start(0, {-> execute('augroup! sample', "")})
endfunction
augroup sample
autocmd!
autocmd InsertLeave * 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
endfunction
function! Remove() abort
echomsg 1
autocmd! sample
call timer_start(0, 'Callback')
endfunction
augroup sample
autocmd!
autocmd InsertLeave * call Remove()
augroup END
call feedkeys("i\<esc>")
vim -Nu NONE -S sample2.vim
その他
Vim 7.4を切る場合はこれでW19を抑えられましたが、古いVimでどうやって対応して良いのかは分かりません。