ちまちまと Java の開発環境を

どもです。

Java の開発環境をちまちまと整えています。

で,yasnippet-java-modeを使っていて気づいた小さいバグというかタイポ? を。

  • tryf
diff --git a/tryf b/tryf
index 1110923..83b6218 100644
--- a/tryf
+++ b/tryf
@@ -1,6 +1,6 @@
 # -*- mode: snippet -*-
 #name : try, finally
-#key : trycf
+#key : tryf
 # --
 try {
     $0

展開はすごく便利だけど,相変わらず,TAB で移動したあとの抜け方がわからん!
あのモードに入ると,「{」を入力して「}」が自動で入らなくなるから困るんだよね〜。
マニュアル読んでももひとつわからんし。
いや,まあ,読み込みが甘いんだろうけどさ〜,使い方くらい,
オレみたいなカスにもわかる場所に書いて欲しいぞ!
修正したら,M-x yas-load-directory でスニペットのトップディレクトリを指定してあげてね。
java-mode だけを指定したら変更が反映されんかったので。

一応設定を晒しておきます。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; yasnippet
(require 'yasnippet)
(require 'dropdown-list)
(yas-global-mode 0)
(yas/load-directory "~/.emacs.d/snippets")
(setq yas/prompt-functions '(yas-dropdown-prompt yas-completing-prompt))
(global-set-key (kbd "\C-c\C-y") 'yas-expand)

mcomplete.el たんはぁはぁ

これがないと死ねる。まじで。
そのくらい溺愛しています,mcomplete.el ちゃん。
ずいぶん前にあるエラーが発生していたんだけど,
見て見ぬふり。手を加えると条例に引っかかるんじゃないかとか思って,
中身を覗きませんでした。


さて,emacsjava 使っていて,ドキュメントが引けないのは致命的。
以前も言ったけど,ドキュメントをさっと引けるかどうかが肝要。
なので,java-docs.el というのを導入してみました。
これね。
https://github.com/skeeto/emacs-java

設定も何も,java-docs.el をロードパスが通ったところに置いて,
下記。

(require 'java-docs)
(java-docs "E:/java/jdk_6u10_docs/api")

これで索引を作ってくれて,万々歳! のはずでした,ええ。
ためしに Vector でも見てみるかと,M-x java-docs-lookup してみると,
え〜,FQN で指定する必要があるのかぁ。
はっはーん。余裕余裕。オレの隣には mcomplete たんがいるんだい!
substring モードにして,vector とタイプしようとすると,
見て見ぬふりをしてきたエラー発生!

Error in post-command-hook: (wrong-type-argument listp java.sql.Ref)

これが問題1。

とりあえずドキュメントを見られるかどうか試したかったので中断して,
リトライ。
java.util.Vector とタイプ。emacs-w3m が起動。よし,ちゃんと見られるな。
リンクをたどろうとすると,リンクのURLが変。あちゃー。
これが問題2。

問題1について

まず,mcomplete.el を最新にしてみるもダメ。
中身を見ると,associative list を期待するところへ,
普通の? list が来ているのが問題っぽい。とりえあず条件分岐で回避。
diff がでかくなっているのは,インデント修正とか余計な空白を削除したからです。
これで一応動いた。

diff --git a/mcomplete.el b/mcomplete.el
index c48602f..22a88c8 100644
--- a/mcomplete.el
+++ b/mcomplete.el
@@ -707,7 +707,7 @@ These bindings are used when an exact match is required."
                  (deactivate-mark nil)  ; protect the original value
                  (str (mcomplete-minibuffer-string)))
             (goto-char (point-max))
-                   
+
             (funcall (mcomplete-get :exhibit)
                      str
                      (mcomplete-all-completions str "abort on input")
@@ -1251,17 +1251,22 @@ Otherwise try to complete it."
                  minibuffer-completion-predicate)))
     (let ((case-fold-search mcomplete-ignore-case)
           (regexp (regexp-quote str))
-	  (len (length str))
+          (len (length str))
           list)
       (cond
-       ((listp table)                   ; alist or nil
+       ((and (listp table) (listp (car table)))                   ; alist or nil
         (let ((rest table))
           (while rest
             (when (and (string-match regexp (caar rest))
                        (or (null pred) (funcall pred (car rest))))
               (setq list (cons (caar rest) list)))
             (setq rest (cdr rest)))))
-
+       ((and (listp table) (atom (car table)))
+        ;; ordinary list, well, presumably...
+        (setq list
+              (remove-if-not (lambda (e)
+                               (string-match regexp e))
+                             table)))
        ((vectorp table)                 ; obarray
         (mapatoms
          #'(lambda (s)
@@ -1272,15 +1277,15 @@ Otherwise try to complete it."
 
        (t
         (error "Invalid TABLE")))
-      
+
       (sort list (lambda (a b)
-		   (let ((a-prefix (eq (compare-strings a 0 len str 0 len) t))
-			 (b-prefix (eq (compare-strings b 0 len str 0 len) t)))
-		     (cond 
-		      ;; Sort prefix matches first
-		      ((and a-prefix (not b-prefix)) t)
-		      ((and b-prefix (not a-prefix)) nil)
-		      (t (string< a b)))))))))
+                   (let ((a-prefix (eq (compare-strings a 0 len str 0 len) t))
+                         (b-prefix (eq (compare-strings b 0 len str 0 len) t)))
+                     (cond
+                      ;; Sort prefix matches first
+                      ((and a-prefix (not b-prefix)) t)
+                      ((and b-prefix (not a-prefix)) nil)
+                      (t (string< a b)))))))))
 
 
 (defun mcomplete-substr-method-try-completion (str abort-on-input)

ひゃっほーい。
今,これ書きながら一応と,試したんだけど,
case sensitive はめんどいね。これも修正するか。
さらにさらに,また別のエラー・・・キタアアアアァ!!
Error in post-command-hook: (wrong-type-argument sequencep t)
獲れたて産直新鮮ほやほやなエラーなので発生条件がわからん。
あとで調べる。
オレのドキュメント道を邪魔するヤツはゆるさん!

とりあえず,1.10 の mcomplete.el を上記の様に修正すれば,
java.util.Vector じゃなくて,Vector だけでドキュメント引けるよ!
mcomplete ないとダメだけどね!

問題2について

これは Windows 下で使っているから起きる問題でした。
パス名が「アルファベット:」で始まっていたら,「file:///」を頭につけることで
解決。たぶんだけど,cygwin-mount が入ってないとだめかも。
修正後のドキュメントのURLが,なぜか,
file:///cygdrive/e/java/jdk_6u10_docs/api/java/util/Vector.html
とかになっていたので。
以下diff。

diff --git a/java-docs.el b/java-docs.el
index ca7c846..2f45121 100644
--- a/java-docs.el
+++ b/java-docs.el
@@ -211,7 +211,11 @@ hash plus version info."
          (case-fold-search nil))
     (when (and (string-equal ext "html")
                (string-match "^[A-Z].+" class))
-      (puthash fullclass fullfile hash)
+      (puthash fullclass
+               (if (string-match "^[a-zA-Z]:" fullfile)
+                   (concat "file:///" fullfile)
+                 fullfile)
+               hash)
       (setq java-docs-class-list
             (cons fullclass java-docs-class-list)))))

これでたぶん動く。ああ,browse-url-browser-function を w3m に設定するのをお忘れなきよう。
もしくはお好みに合わせてね。

(setq browse-url-browser-function #'w3m-browse-url)

まとめ

  • 長年の悩みの種だった mcomplete のエラーが治ったのはうれしい!
  • Java でドキュメントを引けるようになったのがうれしい!
  • mcomplete で新たなエラーが発生したのがうれしくない!
  • Java のドキュメントを引く際に,case sensitive になっているのがうれしくない!
  • Java のドキュメントを引く際に,クラス名からしか引けないのがうれしくない!

一難去ってまた一難とはこのことか!!
いや,待て待て。「うれしい」よりも「うれしくない」の方が多いぞ! orz