Home > Vim Hacks > Hack #124: Vimで非同期実行を行う

Hack #124: Vimで非同期実行を行う

VimがEmacsと比較して一番劣っている機能として、コマンドの非同期実行があげられます。ここでは現状のコマンド実行の問題点とEmacsとの比較、その解決方法について議論を行います。

Vimのコマンド実行の欠点

Vimはsystem():readを用いて外部コマンドを実行し、その結果を得ることができます。これは非常に便利なのですが、Vimが起動した外部コマンドの終了を待ち合わせるため、Vimが停止してしまうという欠点があります。これは特にquickrunや:makeを実行しているときに問題となります。プログラムをバックグラウンドで実行すれば、終了を待ち合わせずにすみますが、それでは結果がとれません。さらにWindows上のGVimの場合、外部コマンドを実行するたびにDOS窓が開いて煩わしいです。 処理内容がシェルに依存するという欠点もあります。たとえば、Windowsでプログラムを起動するためには適切にエスケープしなければいけません。

Emacsとの比較

対するEmacsはどうでしょう。Emacsでは、start-process関数を用いてプロセスを生成することにより、コマンドを非同期的に実行できます。 comint-modeでもこれを用いてインタプリタを起動し、非同期で通信しています。 ただし、Emacsにはマルチスレッド関数がありません。全ての処理はシングルスレッドです。

外部インタフェースの欠点

RubyやPerl, Pythonといった外部インタフェースを用いるという解決策もあります。 しかし、外部インタフェースは通常のVimScriptとは文法が異なるため、連携が非常にややこしいです。時折フリーズしたり、エラーが起こったときにデバッグしづらいという欠点もあります。さらに、すべての環境で使えるわけでもありません。インストールしているRubyやPerl, Pythonのバージョンにも依存するなど、 非同期に通信するためだけに外部インタフェースを用いるのは大げさすぎます。 ただし外部インタフェース内ではマルチスレッドが使えるので、真の非同期通信をするためには、外部インタフェースを用いるほかありません。

vimprocについて

外部ライブラリであるvimprocを用いて外部コマンドと通信すれば、上記に挙げたほとんどの欠点が解消されます。 vimprocとはYukihiro Nakadairaさんが開発している、優れた非同期実行ライブラリです。私が改良したものをgithub上で開発しています。 http://github.com/Shougo/vimproc/tree/master ソースからコンパイルしてVimのautoloadディレクトリに、「proc.soまたはproc.dll」と「vimproc.vim」をコピーすれば準備完了です。

ここでは、vimprocで実装されているvimproc#system関数を紹介します。これは、標準のsystem関数を置き換えることができます。 ただしシェルを起動しないので、シェルの内部コマンドは動作しません。パイプやリダイレクトも動かないので注意してください。 パイプやリダイレクトについては、今後実装予定です。 let l:result = vimproc#system('ls') vimprocを駆使すれば非同期実行をエミュレーションできますが、スレッドの存在しないVimでは使い方がとてもややこしいので、ここでは説明を省略します。 興味がある場合にはvimprocのtestディレクトリにあるサンプルスクリプトを参照してください。 ネットワーク通信もできるので、Twit.vimみたいなプログラムも簡単に作成できます。 いずれはcomint-modeのように、インタプリタ実行機能を統合させたいと思っています。 ちなみにVimScriptでのシェル実装であるvimshellでも、vimprocを用いて非同期実行を行っています。

その他の非同期実行ライブラリ

その他のライブラリとして、vimprocやvimshellをもとにNico Raffatoさんが製作しているConqueというプラグインがあり、とても精力的に開発されています。Emacsのansi-term.elを目標にしているようで、動作が散漫なのが欠点ですが、多機能のようなので使用してみるといいかもしれません。

CursorHoldイベントの落とし穴

しかも、Vimには指定された時間が経過したら関数を呼び出すタイマー機能がありません。 CursorHoldICursorHoldイベントで代用するという手がありますが、これにはイベントごとに時間を設定できない、 ポップアップが表示されているときは呼ばれない、カーソルが動くまで呼ばれないといった欠点があります。 この欠点は本質的に回避不能です。Vim本体にタイマー実行機能が搭載されるのを待つしかありません。

clientserver機能を使う

Vimのclientserver機能を用いると、処理が完了した際に機能を呼び出すコールバック機能を実装することが可能です。 ただし、X環境が必要になります。Windows上でも使用できますが、あらかじめ別のVimを用意しておく必要があります。詳しくは:help clientserverを参照してください。

Shougo
このエントリーをはてなブックマークに追加
はてなブックマーク - Hack #124: Vimで非同期実行を行う
Share on Facebook
Post to Google Buzz
Bookmark this on Google Bookmarks
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://vim-users.jp/2010/02/hack124/trackback/
Listed below are links to weblogs that reference
Hack #124: Vimで非同期実行を行う from Vim-users.jp

Home > Vim Hacks > Hack #124: Vimで非同期実行を行う

Search
Feeds
Links
  • 公式
  • 勉強会
  • 情報
  • コミュニティ
  • Meta
    Etc
    Creative Commons License
    This blog is licensed under a Creative Commons License.

    Return to page top