Emacs-based clojure environment, tested on
- OSX Lion, ‘GNU Emacs 22.1.1’ (stock osx emacs)
- OSX Lion, ‘GNU Emacs 126.96.36.199’ (latest, from homebrew)
- Ubuntu 11.10, ‘GNU Emacs 23.3.1’
This will walk through the simplest and best environment for clojure in emacs, as of [25 Mar 2012]. You don’t have to think about slime and swank - after installation it “just works”.
- lein: https://github.com/technomancy/leiningen
- latest emacs:
brew install emacs --cocoa #stable
brew install emacs --cocoa --use-git-head --HEAD #latest
- emacs plugins for clojure: https://github.com/overtone/live-coding-emacs
(by convention, i put software that is not managed by a package manager in ~/opt, as opposed to using an installer or homebrew, which can go wherever it ends up. that way i can remove them by hand too.)
- lein new helloworld
- cd helloworld
- lein deps
- emacs src/helloworld/core.clj
- `M-x clojure-jack-in`
- in core.clj, type in (+ 3 4), put the cursor after the last paren, C-x C-e to evaluate the expression, observe “7” in bottom left
i’m starting to use emacs in windowed mode, iterm eats certain keychords like C-M-f which is pretty important in paredit. `open -a emacs` was sufficient. i don’t think i’m going to make an alias to keep the distinction between terminal and cocoa emacs.
here’s whats going on under the hood
There are different ways people configure their emacs and clojure, some deprecated, many different ways to get working with various levels of success and complexity. This document will walk you through my way with no magic, from scratch. I don’t like magic because when it breaks i can’t fix it, and it requires putting complicated stuff in my .emacs that i don’t understand.
My preferred way:
- `M-x clojure-jack-in` (swank-clojure)
- this is from:
other, less easy (imo) ways:
- `M-x slime` (slime.el, inferior-lisp) - http://technomancy.us/126
- `M-x swank-clojure-project` (swank-clojure.el)
- `M-x slime-connect` with `lein swank` (lein-swank)
approaches i have not looked in to (due to less control and more magic)
I don’t recommend cloning one of many emacs configurations on github. They may not be using the best tools and they will have lots of other dependencies, custom keybindings, etc. However they are useful to look at if you get stuck. Here are two configurations from PHL Clojure Club members:
- leiningen - clojure dependency management tool
- clojure-mode - emacs plugin for editing clojure source. syntax highlighting, tabs, paren balancing
- paredit - emacs minor mode for editing parens
- swank - emacs utility, provides backend lisp interpreter as backend process
- slime - emacs plugin, front-end for live-coding that connects to swank
- swank-clojure - a lein plugin with emacs bindings that handles all the slime/swank stuff for us.
- incantor - “Incanter is a Clojure-based, R-like platform for statistical computing and graphics.” - bundles clojure and clojure-contrib - we don’t need it.
- manually downloaded files, cloned git repos, etc go in subfolder of ~/opt
- symlink to them from appropriate place
get a working clojure repl
- install lein, its super easy - https://github.com/technomancy/leiningen
- lein will manage our clojure installation, we don’t need to install clojure seperately.
- this is sufficient to run & develop clojure programs, use this to make new projects.
configure emacs to edit clojure source
emacs plugins are loaded via ~/.emacs or ~/.emacs.d/init.el. I don’t know the difference, I’m using init.el.
(add-to-list 'load-path "~/.emacs.d/")
(defun turn-on-paredit () (paredit-mode 1))
(add-hook 'clojure-mode-hook 'turn-on-paredit)
configure emacs to run and debug clojure
- lein plugin install swank-clojure 1.4.0
- `M-x clojure-jack-in`
- link to hotkeys
- paredit won’t let you have unbalanced parens - you can’t backspace some random paren. use C-q to override paredit to insert a paren. C-u <backspace> to delete paren. the constraint that parens are always balanced means we can use things like kill-sexpr - so we can edit s-expressions instead of edit text. so C-k turns into “kill sexpr”. see header comments in http://mumble.net/~campbell/emacs/paredit.el