NodeのREPLとEmacsとで話をする

随分久しぶりになってしまいました。最近は土日しか時間が取れないうえ、土日もどっちかというとゲームに忙殺?される毎日です。

以前ac-typescriptというものを作りましたが、実際パフォーマンスについてはまだ満足いっていない状態でした。
パフォーマンスが上がらなかったのは、原因としてはもうWebsocketだから、という他無さそうです(TypeScriptコンパイラ自体の遅さは置いておいて)。

しかし、WebSocket以上の速度を出そうとすると、取れる手段は後一つ・・・パイプ(ソケット)通信しかなさそうです。
EmacsからFirefoxのReplを動作させる、とかそういうこともできているようなので、できないことはなさそうです。

NodeのREPL

ローカルでJavaScriptを動作させるため、とりあえずNodeを使っています。

Nodeには、そのものずばりの名前を持つreplモジュールというのが標準で添付されています。

var repl = require('repl');
repl.start(" >");

みたいな感じで使えます。第二引数はstreamであればなんでもよいらしいので、ここにソケットとかを設定して、HTTP経由でREPLを弄ったり、というのもできるようです。

とりあえずこれを使ってみます。

Emacs

Emacsは非同期プロセスを扱う柔軟な方法がいくつかあります。

  • start-process
  • start-process-shell-command

非同期で実行する場合、大体この二つのどちらかが利用されるようです。shellとかが無い環境でも動作するのはstart-processの方なんでしょうか?調べてませんが・・・。

これらは、いずれも起動させたプロセスに対して、バッファを一つ割り当てることができます。後述のfilterを設定していない場合、プロセスの出力が全部これに出力されます。

プロセスからのログとかを出力するだけならこれでもいいんですが、出力に対して動作をさせたいとかがある場合、

(set-process-filter プロセス 関数)

として、filterを登録する必要があります。このfilterには、プロセスとプロセスからの出力が渡されます。基本的には標準出力に出力された文字列が出力されてきます。

・・・が、今回はここで引っ掛かりました。

Nodeのreplに対して、process-send-stringでを文字列を送信しているのですが、この出力した文字列がprocess-filterに引っ掛かり、対してNodeの方でconsole.logをしている文字列が欠片も渡ってきません・・・。
というか、process-filterに入力した文字列が渡ってくること自体が想定外でした。よく考えればそりゃそうか、とも思えなくも無いのですが、どこでconsole.logしても文字列が返ってこないため、なんともはや、という状態です。

現状、これをどうにかしたいのですが、中々どうにかなってくれないため、色々試しています。これが上手くいけば大分速くなりそうなんですがねー。