Learning Clojure: Setting up the Emacs on OSX
I’ve been using the Emacs since my Lisp and AI course back in 1987. (My use of the definite article betrays that :)) So, of course I wanted to learn Clojure using it. Unfortunately, there are either incomplete or conflicting posts in googlespace on how to go about doing this. You *can* grab the source with git and build etc., but let’s try the simplest thing possible.
There are two ways to have the Emacs interact with Clojure: inferior-lisp-mode and Slime. I will cover both here.
Initial setup
Clojure runs on the JVM (there are separate projects for the CLR and also ClojureScript), so you should have a JDK version 1.5 or later installed. If you have not set up Leiningen, or even know what that is, please read the first article in this series on setting that up.
Emacs
I was using Emacs 23. It is a bit more difficult setting it up and managing 23 since integration with the Emacs Lisp Package Archive isn’t baked in. So, just get Emacs 24.
For OSX, get the latest Emacs 24 pretest build. I – and many others – have been using it with no problems in spite of it not being a “release.”
Of course I had my Emacs init files. You may have either a ~/.emacs or ~/.emacs.d/init.el lying around. I renamed them (e.g. .emacs.d.bak) to start fresh and then launched Emacs. Just a reminder, if you have a ~/.emacs file, ~/.emacs.d/init.el will be ignored.
I edited my new ~/.emacs.d/init.el to include an additional elisp repository which hosts clojure-mode and paredit.
1 2 3 4 |
(require 'package) (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") t) (package-initialize) |
Go ahead and evaluate the buffer (M-x eval-buffer).
The sequence of Emacs commands follows. You first refresh the local list of available packages and writes that list into a directory in your ~/.emacs.d. This will take bit of time. Then you install the clojure-mode package.
1 2 |
M-x package-refresh-contents M-x package-install RET clojure-mode RET |
If you want, you can run M-X package-list-packages to see what’s there, but I suggest that you don’t blindly add packages without first knowing if they play nicely together.
Inferior Lisp mode
Edit your ~/.emacs.d/init.el again and add these lines. If you’re not on OSX, ignore the third line which changes the Meta key from the Option key to the Command key.
1 2 3 4 5 6 7 |
(setq inferior-lisp-program "lein repl") ;; where is lein located? If it's not in a "standard path, add a line like this. (add-to-list 'exec-path "/Users/gene/bin") ;; on OSX make the command key the meta key (setq ns-command-modifier 'meta) |
Now we can launch a REPL in a subprocess within the Emacs. This is Inferior Lisp Mode.
Open up a test clojure file (e.g. C-x f foo.clj), or navigate to a lein project you created in the first article in this series and edit or create one there.
Enter M-x run-lisp (or C-c C-z).
This will tell lein to start a REPL, since that is what you set the variable inferior-lisp-program to.
Now split the window by typing C-x 2. In one of the windows, navigate to your Clojure file.
Enter a simple sexp. Then after the final ), type C-x C-e to evaluate it. (clojure-mode binds this key sequence to lisp-eval-last-sexp, as well as C-c C-e so you don’t have to remember which!. As always, you can type M-x m for mode info.) You will see the result in the *inferior-lisp* REPL buffer.
1 |
(+ 2 2) |
You can also go into the REPL buffer and type expressions there and they will be evaluated. Editing is fairly basic, but it may be all that you need. Indeed, if you’ve seen the screencasts by Rich Hickey,the creator of Clojure, you will see that he is using inferior Lisp mode.
Clojure mode key bindings.
1 2 3 4 5 6 7 |
C-c C-e evaluate expression to the left of the cursor C-x C-e same thing C-c C-r evaluate expression in region C-c C-z run lisp C-M-x evaluate defn C-M-q indent There are others. Type M-x m for more. |
Slime
The Superior Lisp Interaction Mode for Emacs (Slime) has many more features, including a debugger, and code completion. It was written for other Lisps and is based on a client server model. Slime is the Emacs client and Swank is the “server”. That means you can run Clojure on a different machine if you’d like. For this article, we’ll stick with using it locally.
Swank
Since you already are using Leiningen, simply add the swank plugin. It will be downloaded to ~/.lein/plugins.
1 2 3 4 |
$ lein plugin install lein-swank 1.4.4 Including lein-swank-1.4.4.jar Created lein-swank-1.4.4.jar $ |
You can check current versions like this:
1 |
$ lein search lein-swank |
Navigate to your project: using dired is easiest. Then do this:
1 |
M-x clojure-jack-in |
This starts a Swank server, then uses Slime to connect to it from Emacs.
If you get an error stating that lein cannot be found, see OSX quirks.
Slime’s keybindings are a bit different from Inferior Lisp mode. I suggest that you type M-x m and scroll down to the Slime section or read the Swank Clojure Readme.
Since your are still learning Clojure, Slime’s inspector is quite handy. Place the cursor after a symbol or expression and type C-c I (I as in Inspector). The minibuffer will ask for confirmation and then display the result.
The other handy exploration function is slime-edit-definition. Place the cursor after a function, e.g. after the + in (+ 2 2), then type M-. (meta period). The source code for the definition of + will appear in a buffer.
Visit Slime’s home page for more information. There is a screencast there now showing it in action with Common Lisp.
Alternatives
There are two alternative ways of specifying that you want to use Swank: through a project independent profile and inside a project.
For the global profile, add this to ~/.lein/profiles.clj
1 |
{:user {:plugins [ [lein-swank "1.4.4"] ]}} |
Or add this to your project.clj if you want it inside your project. I prefer to not do this since other team members might be using another editor.
1 2 3 |
(defproject lein01 "1.0.0-SNAPSHOT" :description "test project" :plugins [[lein-swank "1.4.4"]] |
OSX quirk
Here are a few of my OSX specific entries from .emacs.d/init.el. I prefer to use the command key as Emacs’ meta key. If you placed the lein script outside of “normal” paths, (e.g. ~/bin) you may have a problem with lein not being found inside Emacs. If that is the case, you can add your PATH that you set in .bash_profile to Emacs.
1 2 3 4 5 6 7 |
;; on OSX make the command key the meta key (setq ns-command-modifier 'meta) ;; Read in PATH from .bash_profile (if (not (getenv "TERM_PROGRAM")) (setenv "PATH" (shell-command-to-string "source $HOME/.bash_profile && printf $PATH"))) |
Emacs Starter Kit
I suggest that you also install Phil Hagelberg’s Emacs Starter Kit. It includes a good set of defaults, as well as ido-mode and paredit.
1 |
M-x package-install RET starter-kit RET |
If you don’t want the starter kit, at least install paredit.
1 |
M-x package-install RET paredit RET |
Then add this to your ~/.emacs.d/init.el
1 2 3 4 |
(autoload 'paredit-mode "paredit" "Minor mode for pseudo-structurally editing Lisp code." t) (add-hook 'emacs-lisp-mode-hook (lambda () (paredit-mode +1))) (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1))) |
Of course the starter kit does this for you. Read the documentation at the Emacs Wiki on how to use paredit mode.
Have fun.
Resources
Setting up Emacs from Clojure.org
Leiningen home page
Emacs for OSX builds
Emacs Lisp Package Archive
Marmalade Lisp Package repo
Emacs Starter Kit
SLIME: The Superior Lisp Interaction Mode for Emacs
Swank Clojure readme
ParEdit mode
Hi there i am kavin, its my first occasion to commenting anywhere, when i read this paragraph i thought i could also make comment
due to this brilliant article.