quickrun.vim で非同期実行できるようにした

前からやりたいと思っていたのだけど、先日 ujihisa さんが correr.vim なるものをリリースして、これはこの波になるしかないと言う事で勢いで機能を追加した。
quickrun.vim 0.4.0 で使えるよ。

GitHub - thinca/vim-quickrun at v0.4.0: Run commands quickly.

使い方

前提条件

Vim が +clientserver 付きでコンパイルされている必要がある。確認するには、

echo has('clientserver')

で 1 が返ってくれば OK。

さらに、v:servername に何かしら名前が入っている必要がある。

echo v:servername

で、何か表示されれば OK。されない場合は Vim

vim --servername VIM

などとして適当な名前を付けてやる。
複数Vim が起動している場合に結果を返す Vim を確実にするため現在は必須にしてある。
将来的にはなくても動くようにするかも。ただしその場合複数Vim を起動するとうまく動かないだろうけど。

設定
let g:quickrun_config = {
\   '*': {'runmode': 'async:remote:vimproc'},
\ }

こうすると標準で非同期で実行する。vimproc はなくても動くけどあった方がいいです。プロセスが終了しない場合ゾンビ化する可能性があるので。
設定の 'async:remote:vimproc' は vimproc を使いたくない場合は 'async:remote' で OK。ただし 'async:remote:vimproc' でも vimproc が見つからなかった場合は自動でないバージョンで動作する。
すでに何かコマンドを実行中に別のコマンドを実行した場合、実行中のコマンドは強制的にキャンセルされる。vimproc 使ってればちゃんと kill するので変なプロセスは残らないはず。
今のところキャンセルだけをする方法はまだないです。すいません。

仕組み

一応簡単に仕組みを解説。
複数のコマンドも実行するため、まずはコマンドをスクリプトファイルに書き出してます。Windows なら bat、それ以外なら sh。今のところ、どっちかは必ず入ってるだろというやっつけ実装なので Windows 以外で sh がない場合は実は動きません。そういう環境があったら教えてください。
で、そのスクリプトの最後にvim --remote-expr で終了を知らせるコマンドを追加して、バックグラウンドで実行するだけ。入出力は予め用意したファイルで行う。リダイレクトの処理もスクリプト内に書き出してる。
実はその関係で、標準入力の扱いが通常の実行とすこし違います。通常はコマンド 1 つ 1 つに入力を与えてるけど、非同期の場合は全コマンドを && でくっつけてまとめて入力してます。
この部分は通常実行も将来はスクリプトに書き出す方式に変えようかなと思ってる。その方が何かと都合がよさそうな気がしたので。なんとなくだけど。

その他

デフォルトの設定を g:quickrun_config から g:quickrun_default_config に移して、g:quickrun_config はユーザ設定専用の変数にした。
なので、再読み込み対策の

if exists('g:quickrun_config')

はもう必要ない。上書きしても大丈夫なので。

あとはめんどいので ChangeLog 読んでください。

機能を考えるとバグが含まれている可能性が大いにありまくりなので、もし見つけた方は教えてください。コメ欄でも github の Issues でも Twitter でも lingr でもメールでもなんでもいいので。リクエストもあればどうぞ。
というか既にいくつか見つけてしまっていたり…。