EmacsでのTypeScript補完をWebsocketで作りなおした

観測史上最速で夏日を観測したというニュースがあり、そのとき私が住んでいる地点では、28℃までいったようで、普通に半袖を着ていました。なんでこの時期なのに半袖が出ているのかは置いておいて・・・。

さて、前の記事でEmacs+AutoCompleteでTypeScriptの補完を行うelispを作成しましたが、パフォーマンスが非常にまずく、ぶっちゃけ実用に耐えなかったものでした。
パフォーマンスが出なかった原因としては、一々curlでhttpリクエストを投げているため、その分のオーバーヘッドが馬鹿にならないものだろう、というのが一つありそうでした。

というわけで(どういうわけだ)、NodeはWebsocket実装が充実していることもあるということなので、websocket.elと組み合わせて、websocketで通信して、オーバーヘッドをできるだけ減らしてやろう、という結論に至りました。

実装にあたって

いくつかNodeのWebsocket実装を試してみました。

  • Socket.IO
  • websocket
  • sockjs

Nodeで一番有名?なWebsocket実装はSocket.IOかと思いますが、これは色々なブラウザとの互換性とか、Websocket実装が無い環境でも同様の処理ができるように、色々としているため、普通に使うにはSocket.IOと、socket.IOのクライアントの組合せじゃないと上手く動かなさそうでした。実際、上手く動かないのであきらめました。
もうひとつ、そのままの名前でWebsocketというものがありました。これはSocket.IOの内部実装としても利用されているようですが、こいつはネイティブでコンパイルする必要があります。私の場合、Linuxではなんてこと無いのですが、いかんせんWindowsだと上手いぐあいにコンパイルしてくれなかったので、これもあきらめました。ちゃんとコンパイルできれば、これが一番パフォーマンスがでそうです。
というわけで、Javascriptのみで実装されている(と思われる)sockjsを利用することにしました。今回程度の利用であれば、どれも使い方はほとんど変わりません。

機能とか

Websocketにしたことで、以前のパフォーマンスの問題は大体解決することができました。そのため、前回は断念した、バッファの更新毎に、サーバーに更新データを送信する、という真似が可能になりました。
しかし、emacsで更新の度に実行されるようなフックがよくわからず、ちょっと無理矢理気味の実装になってしまっていますが、型がわかっているようなオブジェクトに対して、わりとちゃんと補完がでてくるようになっています。

ただ、まだ問題は大量に残っています。一回しか編集していないのに、大量に更新がサーバーに飛んでいってしまい、結果として補完が遅延したり、どういう状態なのかはよくわからないけど、補完が上手くはたらかなくなったりします。
実際に使ってみると、比較対象にもなりませんが、VisualStudioの補完は本当によくできていると思います。あのパフォーマンスは、ネイティブということもあるのでしょうが、バッファの更新をどうやって正確に渡しているのかも気になります。

ま、とりあえずは自分でしか使わないのでどうでもいいことではありますが、まともなelispというのを久々に書きました。日頃Javaとかばっかりなので、たまには目先の違うものもやっていかないと、ですね。