2013年12月16日月曜日

[Clojure][Emacs]EmacsのCiderを起動するLeiningen pluginを作ってみた

$ lein cider
とすると、REPLを起動して、Emacsのciderコマンドを実行して、Emacs側でもREPLを起動するLeiningen pluginを作ってみた。

私はDebianを常用しており、Clojureでの開発には、REPLとして、Emacs上で動作するCiderを使用している。Emacsと同時に複数のターミナルを開いて、Emacsとターミナルの間を行き来している。
lein replは、ターミナルで起動して、Emacsからはciderコマンドで接続していた。
EmacsとターミナルのREPLを同時に使っていることも多い。
毎回ターミナルでlein replした後に、Emacsからciderで再接続するのが面倒なので、このpluginを作ってみた。

便利かなと思って作ってみたものの、cider-jack-inコマンドがあることを考えると、機能的には微妙なプラグインだな...

使い方

~/.lein/profiles.clj に lein-cider の設定を追加する。

{:user {:plugins [[lein-cider "0.1.0-SNAPSHOT"]]}}

Emacsをサーバーとして起動しておく(server-start関数を使用)。
プロジェクトのディレクトリで、
$ lein cider
を実行すると、Emacs上でciderコマンドが実行されて、REPLを起動する。

ソース

ソースはこちら
標準のREPL(lein repl)を起動後に、emacsclientコマンド経由で ELispのcider関数を呼び出している。
REPLが完全に起動した後に、Emacs側でcider関数を実行しないと、
IllegalAccessError pp does not exist clojure.core/refer
というエラーがでてしまうので、手っ取り早く、もう完全に起動した頃かなーという3秒後に、emacsclientコマンドを実行するようにした。

(defn server [project cfg headless?]
  (let [port (apply original-server-func [project cfg headless?])
        host (:host cfg)]
    (future
      (Thread/sleep leiningen.cider/WAIT_TIME) ; ←◆コレ
      (call-cider host port))
    port))


うーむ。まったくもって、行き当たりばったりな実装だ。

Emacsサーバー

こちらを見ると、
Note that since Emacs 23 this is the preferred way to use Emacs in daemon mode. (start-server) is now mostly deprecated.
というコメントがあった。
ほー。今はdaemon modeで使う方が良いようだ。

参考