Writing Clojure in Vim

Keith Smiley

Editing Clojure, or any other Lisp dialect, is unlike editing any other language we normally write. We can no longer just make our changes line-wise, instead we must deal with editing s-expressions, or expressions surrounded by parentheses. Let’s look at a small Clojure function.

(defn say-hello
  ([] (println "Hello there"))
  ([name] (println (str "Hello " name))))

Assume we want to remove our single argument variation of this function, and instead just leave the version with no arguments, resulting in a function that looks like this:

(defn say-hello []
  (println "Hello there"))

As you can see there was more to this than just deleting the last line of the function. We also had to worry about maintaining matching groups of parentheses.

When looking for information on editing lisps in Vim we often see people saying “If you’re writing a lisp, you should switch to Emacs.” If you are interested in trying Emacs, with evil-mode of course, there is a great starter kit for writing Clojure. Luckily there are a variety of great plugins to enhance Vim’s editing capabilities for editing Clojure, aside from switching our entire editor.

The most heavy-handed plugin for this is paredit. Based on the Emacs plugin of the same name, paredit aims to be an editor changing plugin that makes editing s-expressions very similar to editing lines of code in other languages. To do this it overrides many normal Vim commands such as D to be aware of balanced sets of parentheses. Personally I find this to work well until paredit starts fighting me. Occasionally you can get to a state where you are unable to delete a parenthesis because it still has a pair. Since paredit also overrides x and nearly every other normal mode command, this can be extremely aggravating.

A slightly less intrusive option for making this easier is vim-sexp. As opposed to remapping typical Vim operations this plugin provides text objects for typical lisps patterns such as compound forms, or an expression enclosed in parentheses or various other delimiters. This means we can use commands such as daf to delete around the current compound form. I find this significantly more pleasant while editing Clojure.

Another common operation while editing lisps is slurping and barfing. Here’s an example:

(map inc (1 2 3) 4)

We can see this is invalid syntax. What we actually want here is this:

(map inc (1 2 3 4))

To do this with typical Vim commands we may delete the parenthesis after the 3 and put it after the 4. Since this slurp operation is common in lisps, along with the opposite barf operation, vim-sexp has a mapping for this too. We can use <M-S-l>, or Option-Shift-l on OS X to slurp the element to the right. Personally I find this mapping extremely unintuitive and difficult to use. Tim Pope created the aptly named vim-sexp-mappings-for-regular-people to solve this problem. This plugin hooks into vim-sexp and provides more sensible mappings for slurping and barfing. It maps >) where the angle bracket is the direction and the parenthesis is the end to operate on. Together these two plugins provide all the editing capabilities that I need to efficiently edit Clojure.

Now that we have some help editing lisps you may want some Clojure specific plugins to improve highlighting in Vim. There is a good set of syntax files for Clojure, which, as we know, can be hard to maintain. The same author also has a plugin for extended highlighting. This plugin actually runs some Clojure to highlight our code.

Talking about Clojure and Vim plugins would not be complete without mentioning vim-fireplace, a plugin for integrating with a REPL and evaluating our code within Vim. Fireplace also provides other useful mappings that you can read about in the documentation. Tim Pope makes another plugin that integrates fireplace with Leiningen projects.

Last but not least is rainbow parentheses. This plugin highlights matching parentheses with different colors so we can tell what matches what. It makes dealing with nested s-expressions much easier.

Depending on how you like to edit Clojure in Vim, some of these may not be for you. But no matter what you can definitely turn Vim into a fully featured Clojure editor.