Vimメモ : asyncrun.vimプラグインで非同期実行してみる
ayncrun.vim
Vimで非同期実行するにはvimproc.vimを使う方法があるが、asyncrun.vimというプラグインがあったので試してみる。

インストール
前提条件としてasyncrun.vimはVim 8.0またはNeovimでないと動作しない。
一般のプラグインと同じ方法でインストールできvim-plugの場合は下記コードを追加して:PlugInstallを実行。
Plug 'skywind3000/asyncrun.vim'
使い方
READMEにチュートリアルがあるが、基本的には以下のように:AsyncRunの後にコマンドを指定して実行すればQuickfixに結果が表示される。ここで%は現在開いているファイルのファイル名、%<は拡張子なしのファイル名を表す。
:AsyncRun gcc % -o %< :AsyncRun g++ -O3 "%" -o "%<" -lpthread
:AsyncRun make :AsyncRun make -f makefile
grepコマンドを実行する例。:AsyncRunの後の!があるとQuickfixでの自動スクロールが無効になる(!がない場合はgrepの結果が多い場合にスクロールして表示される)。<cword>はカーソル下の単語を表す。
:AsyncRun! grep -R word . :AsyncRun! grep -R <cword> .
キーマッピングを設定する場合は以下のようにする(例では<F7>でgccを実行)。
:noremap <F7> :AsyncRun gcc "%" -o "%<" <cr>
途中で止めたい場合は下記コマンドを実行する(:AsyncStop!のように最後に!を付けるとKillシグナルによる終了になる)。
:AsyncStop
なお、デフォルトでは自動でQuickfixが開かないのでFAQにあるように以下のようなコードをvimrcに追加する。
augroup MyGroup autocmd User AsyncRunStart call asyncrun#quickfix_toggle(8, 1) augroup END
%, <cword>などのパラメータは下記表を参照。
| パラメータ | 意味 |
|---|---|
| %:p | File name of current buffer with full path |
| %:t | File name of current buffer without path |
| %:p:h | File path of current buffer without file name |
| %:e | File extension of current buffer |
| %:t:r | File name of current buffer without path and extension |
| % | File name relativize to current directory |
| %:h:. | File path relativize to current directory |
| <cwd> | Current directory |
| <cword> | Current word under cursor |
| <cfile> | Current file name under cursor |
| <root> | Project root directory |
Pythonコードの実行
下記Pythonコードの実行を試してみる。
import time for i in range(10): print(i) time.sleep(1)
上記コードを編集して、
:AsyncRun python %
コマンドを実行するとPythonコードが実行されるが、0, 1, 2…と1秒毎に表示されずに全ての処理が完了してから結果が表示された。
これは出力がバッファリングされているのが原因で、以下のように-uオプションを指定するか、
:AsyncRun python -u %
printにflush="True"を追加するなどすればよい。
# Python 3.3以降 print(i, flush="True")

気になる点としてQiitaの記事に下記のようなことが書かれていたのでパス周りには注意。
なお類似プラギンにasyncrunという非同期実行を、vimprocではなくvim本体の機能で行うプラギンがあるのですが、どうもパス周りをうまく読み込んでくれなかったため、インストールだけして使っていません。`