最近Androidの開発をしていまして、例にもれずEclipseが体に合わないため(というかEmacsが好きなため?)、Emacsで開発をしています。

しかし、いままでJavaで本格的に開発したことなかったのでEmacsにおけるJavaの開発環境がまったく整備されていないので、EmacsでもうちょっとJavaの開発がしやすくする便利なモードないのかなと調べてみました。

いろいろ調べてみたら、JDEE − Java Development Environment for Emacsってのがあったのですがなんかごてごてしていて、そんなモリモリの機能いらないんだよなぁと思っていたら「ajc-java-complete」っていうのをみつけました。

ajc-java-completeは名前の通りauto-completeやyasnippetと連携して補完することをメインにしたものになっていて、今も開発が継続しているようでなかなかよさげ。ということでさっそくインストールしてみました。

  • auto-complete のインストール

    http://cx4a.org/software/auto-complete/ からダウンロードしてきて、この辺を参考にインストール。

    .emacsに以下のような設定をしておくとよいでしょう。
    (require 'auto-complete)
    (global-auto-complete-mode t)
    (define-key ac-complete-mode-map "\C-n" 'ac-next)
    (define-key ac-complete-mode-map "\C-p" 'ac-previous)

  • yasnippet のインストール

    http://code.google.com/p/yasnippet/ からダウンロードしてきて、この辺を参考にインストール。

    .emacsに以下のような設定をしておくとよいでしょう($PATH_TO_SNIPPETはsnippetをインストールしたディレクトリね)。
    (require 'yasnippet-bundle)
    (yas/initialize)
    (yas/load-directory "$PATH_TO_SNIPPET/snippets")

  • ajc-java-complete のインストール

    https://github.com/jixiuf/ajc-java-completeからcloneしてきて、この辺を参考にajc-java-complete自体をインストール。

    なお、ajc-java-completeは、auto-completeに付属するpopup.elにパッチをあてないといけないらしく、ajc-java-completeのパッケージに付随するpopup.elを、すでにインストールしたauto-completeのpopup.elと入れ替える必要があります。

    あと、Javaのクラスを補完させるためにタグファイルを生成する必要があります。そのためのJavaのプログラムが添付されているので、それを以下のようにjavacでコンパイルしてから実行する必要があります。
    % javac Tags.java
    % env CLASSPATH=$PATH_TO_ANDROID_HOME/platforms/android-11/android.jar:/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar:. java Tags

    この例ではAndroid開発もしたいのでAndroidのSDKのパッケージも含めています。
    (なお、classes.jarのパスはMac OS X用なので適宜自分の環境に合わせて変えてください)

    んで、最後に.emacsに以下のように書きます。
    (require 'ajc-java-complete-config)
    (add-hook 'java-mode-hook 'ajc-java-complete-mode)

以上でインストールが完了しました。

あとはEmacsを起動してFoo.javaとかやってみると補完がきくようになります。

補完以外の機能で言うと、「C-c i」でインポートしていないものを自動でインポートして(ファイルの上部に「import com.example.foo;」って挿入して)くれたり、クラス名のところにカーソルをもってきて「C-c m」とやるとそのクラスをインポートしてくれたりするものがあります。(ただし、なぜかextendsの後に書いたクラスはインポートしてくれず...)

ちなみに、さきほど補完用にタグファイルを生成したのですが、あれがけっこうな容量になっていて、それを起動時に読み込むため、初回のみですがちょっと時間がかかるようです。これ直したいとajc-java-completeをいまいじってるところです。なにかいい案があったらまたお知らせします。(っていうかpull requestしたい)

それともう1つ、自分はMac OS XのEmacsでインポート機能を使うとダイアログがウィンドウで出てうざい(のとEmacs自体が固まったりする)ので以下のパッチをあててます。
--- old/ajc-java-complete.el	2011-07-08 00:00:28.000000000 +0900
+++ new/ajc-java-complete.el	2011-07-08 00:00:12.000000000 +0900
@@ -938,7 +938,8 @@
 before that it will use y-or-n-p ask user to confirm "
   (let ((import-class-buffer "*ajc-import-java-class*")
         (import-class-window) (user-confirmed-class-items-list)
-        (java-buffer (current-buffer))(java-window))
+        (java-buffer (current-buffer))(java-window)
+        (last-nonmenu-event t))
     (setq case-fold-search nil)
     (if (and import-class-items-list (> (length import-class-items-list) 0))
         (progn