- Tech Corner
- Articles
- Emacs IDE
Setting Up an IDE with Emacs
Directory Structure
On Windows, I adopt a directory structure similar to Unix. That is, I usually
install software under c:\opt
and set up my %HOME%
to a given directory for instance c:\home
. The home directory is
where we need to put the .emacs
file. If it is not specified,
the .emacs
(or _emacs
) file is looked up in
c:\
.
Additionally, it is handy to have a subdirectory under the home directory
(whether on Unix or Windows) where to store libraries for Emacs. This is so
that we don't lose them when switching Emacs versions. I usually call it
~/site-lisp
.
CygWin
Even though CygWin is not required to have an Emacs IDE, it makes things
easier on Windows. Download the setup.exe
from
CygWin site and proceed with its
installation.
NOTE: select to install GNU make; it is used to compile elisp later. While you are at it, you may want to select aspell as well.
In the remainder of this document, let's assume that the install directory
is c:\opt\cygwin
.
- Add
c:\opt\cygwin\bin
to your path. Tip: make sure that CygWin is listed before Windows system directory in the path, in order to be sure the CygWin commands are used. An example is the commandfind
whose Windows version is not as powerful. - If you don't want to use bash as your default shell, modify
c:\opt\cygwin\etc\passwd
to specify your favorite shell like under Unix, and changecygwin.bat
to run your shell.
Emacs
At the time of this writing, the latest stable release of Emacs is 21.3.1. Download Emacs at the GNU site and compile/install it. Alternatively, you may get a binary version at:
- http://www.sunfreeware.com for Solaris
- http://ftp.gnu.org/gnu/emacs/windows for Windows
Add Emacs' bin directory to your path; it is needed later to compile elisp
files. Also create an .emacs
file in your home directory to
specify your personal preferences. For instance, the following tells Emacs to
use tc-shell as its primary shell and aspell for spelling check:
;; ;; Setup Emacs to run tcsh as its primary shell. ;; (setq shell-file-name "tcsh") (setq shell-command-switch "-c") (setq explicit-shell-file-name shell-file-name) (setenv "SHELL" shell-file-name) (setq explicit-sh-args '("-l")) (if (boundp 'w32-quote-process-args) (setq w32-quote-process-args ?\")) ;; Include only for MS Windows. ;; ;; Aspell for spell checking. ;; (setq ispell-program-name "aspell") (setq ispell-extra-args '("--mode=sgml")) (set-default 'ispell-skip-html t)
PMD
PMD is a Java tool that "scans Java source code for potential problems", such as unused variables, import statements etc. It is a nice feature to have in an IDE. Download and install PMD per its official instructions.
Next, we need the PMD
plugin for Emacs to make Emacs aware of PMD. Drop the pmd.el
file into ~/site-lisp
, then add the following in your
.emacs
file.
;; PMD for detecting unused variable, import etc. in Java (require 'compile) (autoload 'pmd-current-buffer "pmd" "PMD Mode" t) (autoload 'pmd-current-dir "pmd" "PMD Mode" t)
JDEE
The Java Development Environment for Emacs (JDEE) is an add on software that turns Emacs into an IDE such as Eclipse. It is useful to read the installation instruction on the JDEE site first. However, there are some variant to these instructions when installing the newer version of CEDET and JDEE. Below are the extra steps I use to install JDEE v2.3.4beta4 and CEDET v1.0beta2. They also apply to the JDEE v2.3.3, which is the production version at the time of this writing.
- Download elib 1.0 either in
compressed tar or
zip format from the JDEE
website. After uncompressing, rename the directory to elib and put it under
your
~/site-lisp
. Then run make to compile all the source files. - Download cedet 1.0beta2 from the Collection of Emacs Development
Environment Tools homepage.
Uncompress it. Compile all by running make at the base directory, or a
subcomponent by running make in the corresponding subdirectory. For
JDEE, we only need
common
,eieio
,semantic
andspeedbar
. Move them to~/site-lisp
. - Download a copy of JDEE either in
compressed tar or
zip format. After
uncompressing the distribution file, rename the base directory from
jde-<version>
tojde
and move it to~/site-lisp
. Add(require `cedet)
as the first line of code inlisp/jde.el
. Then compile by running make. - Add the following in
.emacs
;; ;; Emacs libraries load-path ;; (add-to-list 'load-path (expand-file-name "~/site-lisp")) (add-to-list 'load-path (expand-file-name "~/site-lisp/common")) (add-to-list 'load-path (expand-file-name "~/site-lisp/semantic")) (add-to-list 'load-path (expand-file-name "~/site-lisp/speedbar")) (add-to-list 'load-path (expand-file-name "~/site-lisp/elib")) (add-to-list 'load-path (expand-file-name "~/site-lisp/eieio")) (add-to-list 'load-path (expand-file-name "~/site-lisp/jde/lisp")) ;; ;; JDE ;; Set the below variable to nil to load JDE on start; ;; or to true to defer loading until a Java file is open. (setq defer-loading-jde t) (if defer-loading-jde (progn (autoload 'jde-mode "jde" "JDE mode." t) (setq auto-mode-alist (cons '("\\.java\\'" . jde-mode) auto-mode-alist))) (require 'jde)) ;; Java hook (defun my-java-mode-hook() "Hook for running Java file..." (message " Loading my-jde-hook...") (c-set-offset 'case-label '+) ; ident switch-cases ) (add-hook 'java-mode-hook 'my-java-mode-hook)
NOTE: Starting from version 2.3.4beta5, JDEE has been modified to support CEDET. Therefore steps 2 and 4 are slightly different.
- Idem.
- After uncompressing the distribution file, rename the base directory
from
cedet-<version>
tocedet
and move it to~/site-lisp
. Compile everything by running make at the cedet directory level. With cedet 1.0beta2b, I got a compile error insemantic/semantic-grammar-wy.el
file. This can be fixed by removing extra line breaks in the file and running make again. - Idem.
- The load-path reflects the changes in step 2.
;; ;; Emacs libraries load-path ;; (add-to-list 'load-path (expand-file-name "~/site-lisp")) (add-to-list 'load-path (expand-file-name "~/site-lisp/cedet/common")) (add-to-list 'load-path (expand-file-name "~/site-lisp/cedet/semantic")) (add-to-list 'load-path (expand-file-name "~/site-lisp/cedet/speedbar")) (add-to-list 'load-path (expand-file-name "~/site-lisp/cedet/eieio")) (add-to-list 'load-path (expand-file-name "~/site-lisp/elib")) (add-to-list 'load-path (expand-file-name "~/site-lisp/jde/lisp"))
Customize JDEE
Most large Java projects nowadays use Ant to build their binary distribution. Some also use XDoclet tags to generate source files. In such project it is difficult to compile a file or an entire project within Emacs. Fortunately, JDEE allows several ways for building a project. It also allows us to specify several source directories, which makes it easier to trace source code even when the generated source files are in a different directory than the main source files.
The easiest way to customize JDEE to a given project is to create a project
file, prj.el
. Unlike other IDEs, JDEE does not require the
include of all files in the project file and its loading before able to
edit a file in the project. Instead, the project file contains a set of
JDEE variables that customize the project. JDEE finds the project file by
looking up the directory tree from where the edited source file is located.
Therefore, it is best to put the project file at the project's root directory,
or at least at the highest level of the main source files directory tree.
To illustrate, let's consider a fictive project, myProject, that has a directory structure as follows:
/projects/myProject - proj.el - build.xml +- src +- main +- generated +- lib +- build +- classes +- dist
build.xml
is the project's Ant build file. It has many targets,
among others are:
- srcgen
- generates source files from XDoclet tags.
- build
- builds the project and puts it under the
myProject/build
. - dist
- builds the project then packages it for distribution under
myProject/dist
.
The source directory has two branches: src/main
where are stored
source files written by developers, and src/generated
where
generated source files are created from srcgen target.
myProject/lib
contains jar files used by the project and
myProject/build/classes
contains all the compiled class files
from the source files, generated or not.
In order to set up the project, we need to customize the following JDEE variables:
Variable | Description |
---|---|
jde-build-function | Build method. Can either be make, Ant or a custom build function. |
jde-sourcepath | List of source directories. |
jde-global-classpath | List of classes or jars directories. |
jde-ant-home | Directory where Ant is installed. |
jde-ant-program | Name of the program or script to run Ant. |
jde-ant-invocation-method | How to invoke Ant. There are three ways: via the script/program that comes with Ant, via Java, or via the Ant Server. |
jde-ant-buildfile | Ant's build file. Default is build.xml, therefore we don't need to specify it. |
jde-ant-enable-find | Whether JDE is to look up in the directory tree for the build file. |
jde-ant-read-buildfile | Whether to prompt for the build file name. We want to turn this off as we enable the buildfile lookup. |
jde-ant-args | Arguments to pass to Ant. |
jde-ant-read-args | Whether to prompt for additional Ant arguments. |
jde-ant-read-target | Whether for prompt for a build target. |
jde-ant-complete-target | Whether to attempt target completion (from targets in the build file). |
Our project file looks something like below:
(jde-project-file-version "1.0") (jde-set-variables '(jde-project-name "MyProject") '(jde-build-function (quote (jde-ant-build))) '(jde-ant-invocation-method (quote ("Script"))) '(jde-ant-home "/java/ant") '(jde-ant-program "/java/ant/bin/ant.sh") '(jde-ant-enable-find t) '(jde-ant-read-buildfile nil) '(jde-ant-args "-emacs") ; compile output in emacs format '(jde-ant-read-args t) '(jde-ant-read-target t) '(jde-ant-complete-target t) '(jde-global-classpath (quote ("./build/classes" "./build/jboss/lib" "./lib"))) '(jde-sourcepath (quote ("./src/main/" "./src/generated"))) '(jde-help-docsets (quote (("J2SE v1.4.2 API" "/manual/jsdk-1.4.2/api" nil)))) )
With this setup, individual files can be compiled without having to rebuild the whole project. A couple of steps are involved:
- First we need to generate the source from XDoclet by building with srcgen target.
- Then we need to compile all files by building with build target.
- Now that we have the necessary class files and jar files, we can compile files individually using C-c C-v C-c.
For more information on JDEE variables and project file, see the user's guide for JDEE.
Resources
- GNU Emacs
- An extensible, customizable, self-documenting real-time display, multi-platform editor. In other words, my editor of choice!
- CygWin
- A Unix-like environment for Windows. Among others, it offers several popular shells and useful commands such as find and grep.
- JDEE
- A Java Development Environment for Emacs.
- PMD
- A Java tool that scans Java source code for potential problems such as unused variables, parameters or private methods, empty if/while statements, etc.
- Ant
- Apache Ant is a Java-based build tool, a la Make.
- XDoclet
- A Java tool that generates source code or other files based on custom Javadoc @tags.
Copyright © 2004-2005, Northwest Summit. All rights reserved.