in which are found tricks of the trade concerning clojure authorshipSo it turns out getting set up to write Clojure code can be a little tricky. There are a lot of disconnected tidbits about how folks have figured out how to configure things, but it can be a bit tricky to tell the difference between, "hey, this is how I finally got it to work" and "this is how you really should be doing it". I figure I know about as much about using Clojure with Emacs as anybody, so here's a run-through of how I've done my setup. There are a lot of moving parts, but bear with me; most of the installation is automated.
Spoiler Alert: Using SLIME with Clojure is now much easier than the instructions detailed below indicate. This page is left up as it provides some background that may be helpful, but if you just want to get going with SLIME, use ELPA.
The easiest way to get started is to grab ELPA. If you
use Emacs
Starter Kit you've already got ELPA. (If you're new to Emacs,
you might want to use the Starter Kit anyway as a base for your
own customizations; also check out
the PeepCode
screencast.) Use M-x package-list-packages to pull
up the package list. Move down to clojure-mode and
press i to mark it for installation, then
press x to go.
Once it's installed you should be able to work with .clj files, and you may be happy with just this. It has rudimentary subprocess support with M-x run-lisp, which is good enough for many, including Rich Hickey, the creator of Clojure. But most of us find it much more convenient to interact more richly with a running Clojure process as we code.
Pressing M-x clojure-install will kick off the
Clojure installation process. Once you choose a download location,
it will download a number of repositories and compile Clojure
itself, so it will take a few minutes. (It requires having git,
Java 1.5+, and ant installed.) When it's done, it will configure
SLIME and swank-clojure, and it will give you instructions on a
few lines to add to your personal config (usually found
in Deprecated in favour
of similar functionality in
swank-clojure.$HOME/.emacs.d/init.el) so it will work for future
sessions.
Hitting M-x slime will launch a new Clojure session in
a *slime-repl* buffer. You can also interact with
the *inferior-lisp* buffer, but the slime-repl buffer provides
a higher-level interface with a few extra niceties. The REPL
works as you'd expect, but you can hit , to activate
some shortcuts, the most useful being i to change the
current namespace (with tab-completion) and restart.
Back in your .clj buffers, C-x C-e has been rebound to execute the form under the point in Clojure instead of Elisp. This is handy, but you won't get accurate line numbers from stack traces involving functions loaded this way. Pressing C-c C-k will load the entire file and ensure stack traces come through accurately.
As you type out function calls, you should see their argument
list show in the minibuffer. This is called eldoc, and
it's a great way to get a quick refresher about what a function
expects. For full documentation lookup you'll need to get handy
with C-c C-d d though. Finally you can
use M-. to jump to the definition of any given
function.
Of course, after a while you'll be done with just playing at the
REPL and want to hack on a real project. Since the JVM doesn't
allow you to modify the classpath at runtime, you need to specify
up front where it should look for code. The simplest thing to do
is add src/, test/, lib/,
and classes/ (for AOT compilation, if desired)
directories in your project root to the classpath. Then you place
your dependency jars in the lib directory. If
you've got complicated dependencies, you could
use maven to
manage them, but if you've only got a couple it's not hard to
do by hand.
Use Leiningen
for dependency management and other build needs.
Invoking M-x swank-clojure-project will prompt you for a project root and start SLIME with the classpath configured appropriately.
If you've written automated tests for your project using
the clojure.test library (which you should), you can
use clojure-test-mode to run them. Install it
via M-x package-list-packages, and then you can
use C-c C-, to run the tests in the current
buffer. Failures and errors get highlighted, so if you want to see
details about a failure, move the point to the red region and
press C-c C-'.
I hope this is helpful and clears up some confusion. Now get out there and write some code.
Update: If you are using Slime with both Clojure and Common Lisp, refer to the instructions at http://felipero.posterous.com/1446961.
M-X
load-file
~/.emacs.d/elpa/clojure-mode-1.1/clojure-mode.el
Fortunately hitting ? while in ELPA told me to do that :)
One more thing, you say that the user's config is in init.el, but why not mention that it's probably better to put it in .emacs.d/username/username.el. I was thinking off adding exactly this to the documentation the otherday since I had to track it down in one of the git commit entries.
Anyway, thanks again. Great stuff. Rename it!
Can't use the emacs-starter-kit though, there's a bug in it that makes it unusable (at least for me since I don't know how to fix it myself). Displays "paredit void" after starting emacs and big parts of the config aren't loaded. Was fixed 2 days ago in the chicken-or-egg commit I think but on the same day the error returned in new commits :p My uninformed guess would be that moving paredit from elpa-to-submit to elpa has something to do with it, or at least that commit.
Bertrand: Thanks. I've had a couple other people suggest a rename, but nobody has come up with a better name. Also, renaming can be very disorienting to new users; it's very hard to update all pointers to the old name. Generally the Starter Kit is named at new users since most old Emacs hands are very reluctant to part with their existing config. A new name would be nice, but I'm not sure it's feasible right now.
Looking forward to your post on clojure projects. I'm having some problems setting the classpath in emacs/slime correctly, so I'll stay tuned.
cheers!
Unfortunately the information the ELPA install told me to add to my .emacs file was not sufficient to load everything on subsequent startups. I still haven't figured out exactly what the install process did to get clojure to be the default lisp, but I did have to add the following to my .emacs:
(add-to-list 'load-path "~/../swank-clojure")
(add-to-list 'load-path "~/../slime/contrib")
(add-to-list 'load-path "~/../slime")
(require 'slime)
(autoload 'clojure-mode "clojure-mode" "foo" t)
(add-to-list 'auto-mode-alist '("\\.clj$" . clojure-mode)
ELPA for installing slime/clojure could be so great, it's too bad there's this tiny bit of configuration information missing.
Peter: the stuff you added to your .emacs file is almost exactly what the clojure-slime-config function does. Maybe if you set the clojure-src-root variable? I've had reports that for some reason on OS X that function doesn't work, but unfortunately I can't test on that platform. If you figure anything out please let me know.
Just installed the emacs-starter-kit and clojure-mode, and i can't delete curly braces when in clojure-mode. Is there a logical explanation for that?
/Hingebjerg
I meant to cover it in this post, but it got too long; I'll try to cover it in a future post. In the mean time, take a look at the cheat sheet to see how it works.
Peter: Sounds like the clojure-mode documentation needs a refresh. I'll take a look at that.
After a few retries, I noticed that if I had opened a .clj file, thus starting up clojure-mode, then slime would start up and connect to a clojure REPL without issue.
Long story short:
1. Follow the instructions in the post.
2. M-x clojure-mode (or open a .clj file)
3. M-x slime
The above three steps work every time.
Symbol's value as variable is void: swank-clojure-extra-vm-args
This is on Mac OSX with Emacs 22.3.1. I have no .emacs file and a fresh install of ESK.
Kato: I don't use CL anymore, but if you have any code or instructions that would help for that case I'd be glad to include or link to it.
(format "cd %s&& %s" (replace-regexp-in-string "/" "\\\\" src-root)
Note also the ampersands used by win32 batch language instead of semicolons. I then setq'd clojure-src-root in my startup file, ran clojure-mode first, then slime. Seems to work now.
(message "Checking out source... this will take a while...")
(dolist (cmd '("git clone git://github.com/richhickey/clojure.git"
"git clone git://github.com/richhickey/clojure-contrib.git"
"git clone git://github.com/jochu/swank-clojure.git"
"git clone --depth 2 git://github.com/nablaone/slime.git"))
(unless (= 0 (shell-command (format "cd %s; %s" src-root cmd)))
Search failed: "[0-9]: \\([^$(]+\\).*?\\([0-9]*\\))"
I am on Max OS X. Any ideas?
Thanks!
(clojure-slime-config "/Users/chad/src")
instead of the suggested
(clojure-slime-config)
Apparently, clojure-src-root doesn't get set properly on Mac OS X. This sets it explicitly in the call to clojure-slime-config.
(re-seq #"[0-9]+" "abs123def345ghi567")
results in:
Debugger entered--Lisp error: (invalid-read-syntax "#")
read(#<buffer new.clj>)
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)
while
(map (fn [x] (+ 2 x)) [1 2 3])
results in:
Debugger entered--Lisp error: (void-function fn)
(fn [x] (+ 2 x))
(map (fn [x] (+ 2 x)) [1 2 3])
eval((map (fn [x] (+ 2 x)) [1 2 3]))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)
recursive-edit()
byte-code("\306^P @\307=\203!^@\310\311\312\"\210\313\311!\211^ZA@)\242\314=\203!^@\310\315\31$
debug(error (invalid-read-syntax "#"))
read(#<buffer new.clj>)
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp)