baohaojun / ajoke

Abducting Java Onto Emacs, K is silent.
GNU General Public License v2.0
73 stars 3 forks source link

Ajoke is a tool for doing Java programming on Emacs. It is inspired by Emacs-Eclim, but does not depend on Eclipse. Instead, it uses [[https://github.com/baohaojun/beagrep/][beagrep]] and ctags-exuberant extensively, with a bunch of Perl scripts.

For a demo, you can watch the video I made at [[http://www.youtube.com/watch?v=K4bYiQik6lE][Youtube]] (also on [[http://v.youku.com/v_show/id_XNTg5MzcxNTQ0.html][youku]] for my countrymen behind Great Free Wall, but the quality is bad because youku sucks).

Well, I tried Emacs-Eclim, it was nice. But it has dependency on Eclipse, which is awful: it is very slow with large projects. I tried to put the whole android source tree into Eclipse, it was still doing background indexing the next day. Strace showed that it is scanning all those binary files under =.git= and =.repo/projects=. I finally killed it.

But I really liked a couple of things Emacs-Eclim did, for e.g., draw the class/interface inheritance hierarchy; automatically import missing classes. So I took the ideas and extended it with source code reading in mind: with Emacs-Eclim, when a hierarchy contains android.view.View, you can't easily jump over to that class to take a peek, because that class is from a .jar file in the Android SDK; but with ajoke, android.view.View can be also from GNU Global GTAGS database, which is in turn built from the Android source code (of course, because GNU Global is a source code tagging tool great for code reading), so you can easily jump over to that class and have a sense of The Big Picture:-)

Plus, by hacking this tool, I hope it will also support other programming languages better, such as C#, which is very like Java in my opinion. This is unlike [[http://jdee.sourceforge.net/][JDEE]], which will remain Java only I think. For e.g., I have hacked GNU Global a bit, so that it will be very quick to query android.view.View as a whole. But that will be another blog post (which I will add the link [[http://baohaojun.github.io/blog/2013/10/01/0-Inside-Ajoke.html][Inside Ajoke]] here after I write it).

** Check out the source code

+BEGIN_SRC sh

git clone --recursive -b gnu-global https://github.com/baohaojun/ajoke

+END_SRC

Note the --recursive option, it's important because I have 2 submodules in ajoke, my patched versions of GNU Global and ctags-exuberant.

Also note the =-b gnu-global= option, it's because the master branch of ajoke has switched to use [[https://github.com/baohaojun/beagrep.git][beagrep]] instead of GNU Global for Java indexing, and is currently broken except for my own [[https://github.com/baohaojun/system-config][system-config]].

** Set up the env If you are using Debian or Ubuntu, I have provided a test drive script named =ajoke-test-drive=, so after you check out ajoke, you can simply type =./ajoke/bin/ajoke-test-drive= to have a taste of it.

If you are not using Debian alike systems, then please follow these steps, supposing ajoke is checked out in =$AJOKE_DIR= (in my case, it is =~/system-config/gcode/ajoke=, yours may vary):

*** Put ajoke scripts into you PATH and Perl PATH:

+BEGIN_SRC sh

export AJOKE_DIR=~/system-config/gcode/ajoke #PLEASE MODIFY THIS TO SUIT YOUR CASE export export PATH=$AJOKE_DIR/bin:$PATH export PERL5LIB="$AJOKE_DIR/etc/perl:$PERL5LIB";

+END_SRC

It may be a good idea that you put these into your .bashrc, and restart your Emacs with these environment variables set.

*** Install 3 cpan modules

String::Approx, String::ShellQuote, Text::Glob (as debian

packages, they are named libstring-approx-perl, libstring-shellquote-perl and libtext-glob-perl)

*** Compile and install the patched version of Gnu Global

This code is available at [[https://github.com/baohaojun/ajoke-global][external/global]], it will be checked out together with ajoke if you used the --recursive option when cloning ajoke.

+BEGIN_SRC sh

cd ./external/global sh ./reconf.sh ./configure make -j8 sudo make install

+END_SRC

**** If the compilation fails because of missing dependencies

If you are on Debian family, you can try to install the dependencies with the following commands. I tried them myself on a clean minimal Debian system built using pbuilder, and GNU Global compiles just fine after the dependencies resolved.

+BEGIN_SRC sh

apt-get build-dep global

apt-get install sudo bash-completion autoconf automake \ bison exuberant-ctags flex \ gperf libltdl-dev libtool netbase \ openjdk-6-jdk strace tasksel git python python3 \ libstring-approx-perl libstring-shellquote-perl \ libtext-glob-perl liburi-encode-perl

+END_SRC

*** Compile and install ctags-exuberant

Ctags-exuberant is also provided as a git submodule, under [[https://github.com/baohaojun/ctags-exuberant][external/ctags-exuberant]].

+BEGIN_SRC sh

cd ./external/ctags-exuberant autoreconf -i ./configure make -j8 sudo make install sudo mv /usr/local/bin/ctags /usr/local/bin/ctags-exuberant

+END_SRC

*** Copy the .globalrc and .ctags into your HOME

Suppose your global installed into =/usr/local/bin/global=, then ~global_prefix=/usr/local~

+BEGIN_SRC sh

global_prefix=/usr/local perl -npe "s,\@prefix\@,$global_prefix,g" $AJOKE_DIR/external/global/gtags.conf.in > ~/.globalrc ln -sf $AJOKE_DIR/etc/.ctags ~/

+END_SRC

*** Create Gnu Global tags for JDK

Taking my openjdk installation as e.g.:

+BEGIN_SRC sh

cd /usr/lib/jvm/java-6-openjdk-amd64 mkgtags

+END_SRC

Alternatively, you can use Android source tree as the fallback tags (my android is at =~/src/android=):

+BEGIN_SRC sh

cd ~/src/android mkgtags

+END_SRC

*** Create gtags for your Java project

And add the JDK or Android as fallback:

+BEGIN_SRC sh

cd ~/your-java-project mkgtags java-add-fallback /usr/lib/jvm/java-6-openjdk-amd64

or java-add-fallback ~/src/android, but not both

as it'd be a waste of time to find 2 copies of java.lang.String

+END_SRC

*** Require $AJOKE_DIR/etc/elisp/ajoke.el in your =~/.emacs=

Start Emacs with the environment variables set correctly, and
start laughing with Ajoke:-)

You can refer to the test driver script if there are any problems. In the mean time, I will try to make =ajoke-test-drive= support more systems.

Another tool very useful for code reading is [[./blog/2011/12/23/beagrep.org][beagrep, grep 2G source code in 0.23 second]]. For e.g., compared to JDEE, ajoke can't do caller/callee look up, but its friends beagrep and ctags-exuberant [[http://baohaojun.github.io/blog/2013/07/20/0-grep-cross-ref.html][can do it]].

Most of other ajoke's friends are still unborn in my personal [[https://github.com/baohaojun/system-config][system-config]] project.

Thank Emacs-Eclim and JDEE for the inspiration. Thank GNU Global for using B+ tree to query tags (it's so fast!), and ctags-exuberant for supporting so many programming languages.