Clojure, Swank, and Leiningen with Emacs on Linux

References

This tutorial is provided as a very specific approach to installing a clojure environment on linux. Although an attempt is made to keep it up to date, the various technologies used are moving very fast. The following list contains links to the offical documentation of the most relevant packages.

Command line support

Install Java

Arch

~$ sudo pacman -S jdk

Ubuntu

~$ sudo apt-get install sun-java6-jdk

Install Ant

Arch

~$ sudo pacman -S apache-ant

Ubuntu

~$ sudo apt-get install ant

Install Maven

Arch

~$ sudo pacman -S maven

Ubuntu

~$ sudo apt-get install maven2

Install Git

Arch

~$ sudo pacman -S git

Ubuntu

~$ sudo apt-get install git-core

Install Clojure

~$ mkdir ~/opt

~$ cd ~/opt

~$ git clone git://github.com/clojure/clojure.git

~$ cd clojure

~$ ant

~$ mkdir ~/.clojure

~$ cp clojure.jar ~/.clojure

Test Clojure

Gentlemen, start your REPLs.

~$ cd ~/.clojure 

~$ java -cp clojure.jar clojure.main

user=> (+ 1 41) 

42 

Ctrl-d will exit the REPL.

Install clojure-contrib

~$ cd ~/opt 

~$ git clone git://github.com/clojure/clojure-contrib.git 

~$ cd clojure-contrib 

~$ mvn install

~$ cp modules/complete/target/complete*.jar ~/.clojure/clojure-contrib.jar

Configure Bash Start-up Script

clojure-contrib contains a bash script called clj-env-dir for starting clojure with various options. Edit your ~/.bashrc file to configure this script.

export CLOJURE_EXT=~/.clojure

export PATH=$PATH:~/opt/clojure-contrib/launchers/bash

alias clj=clj-env-dir

The last line added to the file above sets an alias to the clj-env-dir script. This example uses clj but it could be set to anything.

See the file at ~/opt/clojure-contrib/launchers/bash/clj-env-dir for more options.

Add JLine support

Download JLine from http://jline.sourceforge.net/ and unzip and copy jar to the ~/.clojure directory.

Add jline.ConsoleRunner to the last line in ~/opt/clojure-contrib/launchers/bash/clj-env-dir to add JLine functionality.

exec $JAVA $OPTS jline.ConsoleRunner $MAIN "$@"

Test the Script

To test the new script and verify access to the clojure-contrib library, open a new terminal window and try this:

~$ clj

user=> (System/getProperty "java.class.path")

If any other jars are needed either copy or link them to the ~/.clojure directory.

Emacs support

Install Emacs

Arch

~$ sudo pacman -S emacs

Ubuntu

~$ sudo apt-get install emacs-snapshot-gtk

Install Slime

~$ cd ~/opt

~$ git clone git://github.com/nablaone/slime.git

Install clojure-mode

~$ cd ~/opt 

~$ git clone git://github.com/technomancy/clojure-mode.git 

Install leiningen

~$ cd ~/opt

~$ mkdir leiningen

~$ cd leiningen

~$ wget --no-check-certificate http://github.com/technomancy/leiningen/raw/stable/bin/lein

Add the following to .bashrc.

export PATH=$PATH:~/opt/leiningen

Execute the leiningen script.

~$ chmod +x lein

~$ ./lein self-install

Configure Emacs

Add these specifics to the .emacs file.

;; clojure-mode
(add-to-list 'load-path "~/opt/clojure-mode")
(require 'clojure-mode)

;; slime
(eval-after-load "slime" 
  '(progn (slime-setup '(slime-repl))))

(add-to-list 'load-path "~/opt/slime")
(require 'slime)
(slime-setup)

Test Configuration

Create a test project.

~$ mkdir ~/tmp

~$ cd tmp

~$ lein new test-project

~$ cd test-project

~$ emacs project.clj

Add the following:

(defproject test-project "0.1.0"
  :description "Test Project"
  :dependencies [[org.clojure/clojure "1.2.0-master-SNAPSHOT"]
                 [org.clojure/clojure-contrib "1.2.0-SNAPSHOT"]])

Save and exit the file.

~$ lein deps

~$ lein swank

Open a new terminal and open the generated file in emacs:

~$ emacs ~/tmp/test-project/src/test_project/core.clj

Connect to the running swank server:

M-x slime-connect

Add some code to the file:

(System/getProperty "java.class.path")

And then at the end of the line, evaluate:

C-x C-e

The output will show the configured jar files and their associated paths on the Java classpath.

Lastly, compile the file:

C-c C-k

Paredit support

To add paredit support to emacs, follow these steps:

Install paredit

~$ cd ~/opt

~$ mkdir paredit

~$ cd paredit

~$ wget http://mumble.net/~campbell/emacs/paredit.el

Modify the .emacs file to this:

;; clojure-mode
(add-to-list 'load-path "~/opt/clojure-mode")
(require 'clojure-mode)

;; paredit
(add-to-list 'load-path "~/opt/paredit")
(require 'paredit)

;; slime
(eval-after-load "slime" 
  '(progn (slime-setup '(slime-repl))	
	(defun paredit-mode-enable () (paredit-mode 1))	
	(add-hook 'slime-mode-hook 'paredit-mode-enable)	
	(add-hook 'slime-repl-mode-hook 'paredit-mode-enable)
	(setq slime-protocol-version 'ignore)))

(add-to-list 'load-path "~/opt/slime")
(require 'slime)
(slime-setup)

Note: This last modifcation also supresses the slime protocol version message.