quickrun.vim でリアルタイムに出力を行う場合の注意

この記事は Vim Advent Calendar 2012 347日目の記事になります。
Vim Advent Calendar 2013 の募集も開始しました。
興味のある方はぜひご参加下さい。


今回は Vim 成分薄いんですが、簡単な小ネタでも。

さて、quickrun.vim は runner に vimproc を設定すると非同期で実行を行うことができます。
この時に次のような Ruby のコードを実行させた場合、一定間隔でバッファに出力される事を期待すると思います。

puts "hello"
sleep 1

puts ","
sleep 1

puts "world"
sleep 1


しかし、実際にはしばらくたってから『hello,world』が一気に出力されます。
これは上記の Issues にも書かれていますが、Ruby が出力をバッファリングしているためです。
これを回避する場合、Ruby 側で明示的に flush する必要があります。

puts "hello"
STDOUT.flush
sleep 1

puts ","
STDOUT.flush
sleep 1

puts "world"
STDOUT.flush
sleep 1


もしくは

$stdout.sync = true

puts "hello"
sleep 1

puts ","
sleep 1

puts "world"
sleep 1


というように Ruby 側に処理を追加して対応することができます。
この問題は Ruby 以外でも起こりうる可能性があります。
例えば PythonC++ なども同様の挙動になります。
ちなみに python ではコマンドオプションの -u で回避できるので、

let g:quickrun_config = {
\   "python" : {
\       "cmdopt" : "-u"
\   },
\}


のような設定をしておくとコードを修正する事なくリアルタイムに出力を行うことができます。
ちなみに quickrun.vim 以外では vimshell でも同様の挙動になるので注意して下さい。