続 NTEmacs への malabar-mode のインストール。(未完)

どもです。
5月なのになぜかフリースを着て,暖かいコーヒーを飲んでいるわけでして。
要するにさぶいとかそういうことです。

進捗状況

malabar-mode の導入について,ちょっと進捗があったので,ご報告。


  • Emacs がブロックするとか言っていた問題。

ワタシのミスだと思われる。*Malabar Groovy* バッファは,
ある種エコーエリア的な役目をしているっぽい。なので,このバッファで
パチパチしても意味がない。

  • *Malabar Eval Server* バッファ

このバッファで,適当に java の式なり文を入力すると実行できる。
これが,groovysh ということかな?

groovysh で,少し試してみたところ,
ToolProvider.getSystemJavaCompiler() が null を返していて,
ここからナルポが飛ぶことがわかった。
ほいで,groovysh で,上記式を評価したら,やっぱ null だった。
import javax.tools.* した後でね。
で,ググると,どうやら,JRE の tools.jar 使ってるんじゃね? ということらしい。
なので,JDK の tools.jar を malabar の jar が入っているディレクトリにコピーして,
再起動。

groovy:[] 000> ToolProvider.getSystemJavaCompiler();
===> com.sun.tools.javac.api.JavacTool@11fcdde

おっ。ちゃんとオブジェクトが返ってきているようだ。
で,コンパイルしてみたら,一応できたっぽい。

で,コンパイルエラーだすようにソースを修正して,
再度 C-cC-zC-c でコンパイル。あれ?
コンパイルできねーぞ,ごらぁ。


でですね,それ以降,モードラインに,Compiling ってでるようになったんですが。
text-mode で日記を書いているこのバッファにも。


関数 malabar-groovy-eval-as-compilation の中で,
thunk を作って,現在,なんかをコンパイル中でなければ,
funcall。コンパイル中だったら,malabar-groovy--compilation-backlog というリストに
つっこんでいる。ほいで,たぶん,このバックログをあとで処理しましょうということだと
思う。だから,thunk。だから backlog。


問題は,コンパイルが終わっている(と思われる)にも関わらず,
終わったと判断できてないので,このバックログにthunkがたまっているということ。
終わったと判断できてないから,モードラインに,Compiling と表示されている。
これはちょっとした恐怖ですよ。
ちなみに,groovysh 上で,下記のように,直打ちするとちゃんとコンパイル出来るので,
コンパイル処理の終了判断あたりに問題がありそう。

groovy:[] 000> Projects.get('e:/cygwin/home/whitypig/prog/tmp/maven/sample/pom.xml', []).compiler.compile('e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java')
java.util.regex.PatternSyntaxException:
Illegal/unsupported escape sequence near index 10
e:\cygwin\home\whitypig\prog\tmp\maven\sample\src\main\java\com\example\App.java:14:
          ^
        at org.grumblesmurf.malabar.Compiler$_compile_closure2.doCall (Compiler.groovy:67)
        at org.grumblesmurf.malabar.Compiler.compile (Compiler.groovy:65)
        at org.grumblesmurf.malabar.Compiler$compile$0.callCurrent (Unknown Source)
        at org.grumblesmurf.malabar.Compiler.compile (Compiler.groovy:42)
        at org.grumblesmurf.malabar.Compiler$compile.call (Unknown Source)
        at groovysh_evaluate.run (groovysh_evaluate:4)
        ...
groovy:[] 000> Projects.get('e:/cygwin/home/whitypig/prog/tmp/maven/sample/pom.xml', []).compiler.compile('e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java')
===> true

次回予告

バックログをどう処理しているかを見れば解決できそうなので,
その辺を,気が向いたら見てみます。

追記

勢いでやってみた。
いつまでたってもコンパイルが終わらない病は,

(setq compilation-in-progress nil)

すれば,治る。


ほいで,コンパイルエラーの際の処理だけど,色々と問題がありそう。
とりあえず,下記のように修正すれば,いつまでたってもコンパイル終わらない病は,
起きないはず。

  • 追記

嘘でした。また起きました。

--- malabar-groovy.el.org	2011-05-23 09:34:19.370625000 +0900
+++ malabar-groovy.el	2011-05-24 22:47:32.462671300 +0900
@@ -202,10 +202,10 @@
         (progress-reporter-force-update reporter 4 "Starting Groovy...connecting to servers ")
         (make-comint malabar-groovy-compile-server-comint-name
                      (cons "localhost"
-                           (number-to-string malabar-groovy-compile-server-port)))
+                           malabar-groovy-compile-server-port))
         (make-comint malabar-groovy-eval-server-comint-name
                      (cons "localhost"
-                           (number-to-string malabar-groovy-eval-server-port)))
+                           malabar-groovy-eval-server-port))
         (progress-reporter-force-update reporter 5 "Starting Groovy...waiting for server prompts ")
         (malabar-groovy--wait-for-prompt malabar-groovy-compile-server-buffer-name
                                          initial-points-alist)
@@ -474,7 +474,7 @@
 (defun malabar-groovy--compile-handle-exit ()
   (with-current-buffer malabar-groovy-compilation-buffer-name
     (let ((result (progn (goto-char (point-max))
-                         (re-search-backward "===> \\(.*\\)$")
+                         (re-search-backward "===> \\(.*\\)$" nil t)
                          (match-string-no-properties 1))))
       (replace-match "" t t)
       (setq compilation-in-progress


しかし,コンパイルエラーの際に,

groovy:[] 000> Projects.get('e:/cygwin/home/whitypig/prog/tmp/maven/sample/pom.xml', []).compiler.compile('e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java')
java.util.regex.PatternSyntaxException:
Illegal/unsupported escape sequence near index 10
e:\cygwin\home\whitypig\prog\tmp\maven\sample\src\main\java\com\example\App.java:14:
          ^
        at org.grumblesmurf.malabar.Compiler$_compile_closure2.doCall (Compiler.groovy:67)
        at org.grumblesmurf.malabar.Compiler.compile (Compiler.groovy:65)
        at org.grumblesmurf.malabar.Compiler$compile$0.callCurrent (Unknown Source)
        at org.grumblesmurf.malabar.Compiler.compile (Compiler.groovy:42)
        at org.grumblesmurf.malabar.Compiler$compile.call (Unknown Source)
        at groovysh_evaluate.run (groovysh_evaluate:4)
        ...

と出ているように,java もしくは,groovy レベルで例外が発生している。
Windows のパスの separator がバックスラッシュだから,それをエスケープシーケンスと
勘違いしている?
この辺になってくるとお手上げ。
java なり,groovy を知っている人に任せるしかない。
ちなみに,Compiler.groovy の54行目71行目を抜粋させてもらいます。

    54	            def task =
    55	                compiler.getTask(Utils.getOut(), fileManager, diagnosticCollector,
    56	                                 ["-cp", classpath.asClassPath(),
    57	                                  "-g", "-deprecation",
    58	                                  "-d", output,
    59	                                  "-source", project.source,
    60	                                  "-target", project.target,
    61	                                  "-encoding", project.encoding,
    62	                                  "-Xlint:all", "-Xlint:-serial"],
    63	                                 null, compilationUnits);
    64	            def success = task.call();
    65	            diagnosticCollector.diagnostics.each {
    66	                def start = [it.source as String, it.lineNumber].join(":")
    67	                def message = it.getMessage(null).replaceFirst(start + ":", "")
    68	                println([it.kind, it.source as String, it.lineNumber, it.columnNumber,
    69	                         it.startPosition, it.endPosition, it.position,
    70	                         message].join("::"))
    71	            }

Utils.getOut() でこけてる? でも,Utils がなんなのか? getOut() がなんなのか
わけわかめ。task.call() で実際にコンパイルしているのはなんとなくわかる。
いや,違うぞ。きっと。
Emacs 内の zsh から,javac してみたら,メッセージが8進になった!
そういうことか! javac の出すエラーメッセージが,sjis だからか!
でもいいや。疲れたし,風邪引いて体調悪いし,今週末に法事があるから,
はやく風邪治さないとならないし。法事がなくても風邪は,はやく治すべきだし。
それに,ほとんど答えは見えているからダイジョウブデスたいっ!

追記その2

追記その1で書いたことは嘘でした。ごめんなさい。
いつまでたってもコンパイルが終わらない病は治りませんでした。

追記その3

適当に当たりをつけて,ソースをいじってビルドして試してみたら,
一発だった。

--- Compiler.groovy.org	2011-05-23 09:10:44.433125000 +0900
+++ Compiler.groovy	2011-05-24 23:44:14.697046300 +0900
@@ -64,7 +64,8 @@
             def success = task.call();
             diagnosticCollector.diagnostics.each {
                 def start = [it.source as String, it.lineNumber].join(":")
-                def message = it.getMessage(null).replaceFirst(start + ":", "")
+                //def message = it.getMessage(null).replaceFirst(start + ":", "")
+                def message = it.getMessage(null)
                 println([it.kind, it.source as String, it.lineNumber, it.columnNumber,
                          it.startPosition, it.endPosition, it.position,
                          message].join("::"))


コンパイルエラーはこんなの。

Projects.get('e:/cygwin/home/whitypig/prog/tmp/maven/sample/pom.xml', []).compiler.compile('e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java')
src\main\java\com\example\App.java::14::19. 以下,文字化け起こしていたりするので略。
別に化けてはないのか。


とりあえず,コンパイル終わらない病は治ったとみていいでしょうか。今度こそ。
あと,エラー行の左にびっくりマークがつくのね。
結局,replaceFirst() で落ちていたということなのかなぁ。
groovy のソースはじめて見たし,慣習知らんしで,どうするのがいいのかわからん。
Java も苦手だし。そして,問題が解決したわけではない。

  • パスのセパレータがらみでこけている。
  • エラーメッセージが sjis だからこけている。


このどっちかだとは思うんだけどどうすればわかるんだろう。
上記の,diagnosticCollector を使って処理しているのは,エラーメッセージを小洒落たものに
するためのものだろうからなぁ。
あとは未来のオレに任せることにする。

未来のオレが来ましたよっと。

これと,

(setq malabar-groovy-java-options '("-Duser.language=en"))

これでどやっ。

--- Compiler.groovy.org	2011-05-23 09:10:44.433125000 +0900
+++ Compiler.groovy	2011-05-25 01:08:11.212671300 +0900
@@ -63,9 +63,11 @@
                                  null, compilationUnits);
             def success = task.call();
             diagnosticCollector.diagnostics.each {
-                def start = [it.source as String, it.lineNumber].join(":")
-                def message = it.getMessage(null).replaceFirst(start + ":", "")
-                println([it.kind, it.source as String, it.lineNumber, it.columnNumber,
+                def src = it.source as String
+                src = src.replace('\\', '/')
+                def start = [src, it.lineNumber].join(":")
+                def message = it.getMessage(null).replace('\\', '/').replaceFirst(start + ":", "")
+                println([it.kind, src, it.lineNumber, it.columnNumber,
                          it.startPosition, it.endPosition, it.position,
                          message].join("::"))
             }


やはり原因はパスセパレータのバックスラッシュがエスケープシーケンスと勘違いされて,
いや,この場合はエスケープシーケンスと解釈する方が正しいのか。
で,それが原因なので,JavaAPI リファレンス見ながら,
バックスラッシュをスラッシュで置換するようにした。
groovy とか知っている人に添削をお願いしたい。
ほいで,日本語のエラーメッセージが8進化されるので,これを防ぐために,
ここ http://d.hatena.ne.jp/smotokezuru/20100418/1271565315
参考にmalabar-groovy-java-options を設定。ありがとう!


こんなんになります。

Projects.get('e:/cygwin/home/whitypig/prog/tmp/maven/sample/pom.xml', []).compiler.compile('e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java')
ERROR::e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java::10::39::152::152::152:: ';' expected
ERROR::e:/cygwin/home/whitypig/prog/tmp/maven/sample/src/main/java/com/example/App.java::14::19::203::203::203:: ';' expected


Compilation exited abnormally at Wed May 25 01:07:58

ワタシは基本的に,日本語のエラーメッセージとか信用しないタイプなので,
むしろこっちの方がありがたい。
ERROR とか表示されているのは,たぶんだけど,Emacs 内のコンパイルバッファで有効な
プロトコル的なものだと思う。Emacs 内で見る際にには,表示されず,色が変わったりするだけ
だと思う。知らんけど。なので,もちのろんで,M-g,M-n でエラー箇所へぴょんぴょん飛べるよ!

まとめ

そんなわけで,やっとこさ malabar-mode のインストールという当初の目的を
達成できたのでした。
えっ。