Unboxing: vim-fireplace

Pete Withers-Jones

on 28-05-13

About Unboxing

Unboxing is our regular feature where someone at Box UK spends a few hours playing with a new framework, library, tool or technique and blogs about his or her experience.

Talk to one of our digital experts

Tom Houdmont

Head of Business Solutions

Do you have an idea or a project you need support with?

Tom leads Box UK’s Business Solutions team and has over 15 years experience in the web industry.  Tom is passionate about creating impactful solutions that solve real problems and deliver the outcomes our clients need.

Or call us on 020 8098 2093

Unboxing vim-fireplace

I’ve been using Vim for a few years now, and love it. When developing with Clojure, however, I’ve always felt like I’ve been missing out on the tight integration my Emacs-touting colleagues seem to enjoy. I’ve tried picking up Emacs a few times, but have always ended up coming back to Vim as I just feel much more productive with my day-to-day languages.

Until now my setup has involved using a Slime plugin to send functions to a REPL running inside a Screen session. This actually works reasonably well; the plugin just grabs chunks of text and pipes them to the screen session. It’s agnostic to the source and destination, so can be useful for many things, but it does lack the aforementioned tight integration so I’ve always hoped for something better…

What is vim-fireplace?

Over the last year the Clojure community has moved away from using Swank/Slime to the nREPL protocol. For Vim, there is a plugin called vim-fireplace (previously vim-foreplay) which provides this functionality. This post is a little different to our usual unboxings where the author has no experience of the tech, as I’ve been using this for a little while, but I want to take you through what vim-fireplace is and how nicely it works.

Getting to grips with vim-fireplace

1. Install your plugins

Installation is pretty straightforward. I use vundle to manage my plugins, so installing vim-fireplace is as easy as adding it to my config:

Bundle ‘guns/vim-clojure-static’Bundle ‘tpope/vim-fireplace’

I’ve also included the vim-clojure-static plugin which provides syntax highlighting, indentation and filetype settings for Clojure and ClojureScript. If you use Pathogen then you can find the repos to clone on Github.

2. Start the REPL

Unlike with Emacs where (as I’m told, anyway) it’ll start an nREPL server for you when you ‘jack in’, we need to start the REPL that Vim is going to connect to. This is easy of course with Leiningen:

$> lein replnREPL server started on port 55983REPL-y 0.1.10Clojure 1.5.1  Exit: Control+D or (exit) or (quit)Commands: (user/help)  Docs: (doc function-name-here)        (find-doc "part-of-name-here")Source: (source function-name-here)        (user/sourcery function-name-here)Javadoc: (javadoc java-object-or-class-here)Examples from clojuredocs.org: [clojuredocs or cdoc]        (user/clojuredocs name-here)        (user/clojuredocs "ns-here" "name-here")user=> 

You’ll see that it prints out the port nREPL is listening on. This has also been written to the file target/repl-port which vim-fireplace will use. There’s no need to start Vim or nREPL before/after each other; any order will work. You can even restart the REPL and vim-fireplace will reconnect to the new one (or even connect to a running application!)To test that it’s working, open a Clojure file from your project and enter :%Eval, which will evaluate the current namespace. You should see a message on the statusline that will be the result of the last expression in the file (probably a function name).

Testing vim fireplace

 

3. Execute your code

Then you can try executing some code. Type an invocation to one of the functions in your namespace, move the cursor to it, and then type :Eval. You should see the result of the function appear in the message window at the bottom of Vim:

Executing code

 

Sweet! Let’s try some other features…

4. Adding key bindings

Using :Eval and :%Eval is fine for a demo, but not for more than a few minutes. So, I added some handy key bindings (ctrl-e, and shift-e, respectively).

nnoremap <C-e> :Eval<CR>nnoremap E :%Eval<CR>

This makes it really quick and easy to compile and evaluate forms, and error messages will be displayed right there in Vim when they occur (so, no need to switch to another application as I had to do before).

5. Accessing documentation and function source code

The next useful feature is the ability to access documentation and function source code. Documentation can be accessed either by using :Doc FUNCTION_NAME, or more handily by using K while the cursor is over a function. This will then display the documentation for that function in a message window at the bottom of the screen. Here’s an example for clojure.core/map.

Accessing documentation

 

This isn’t just limited to the clojure.core docs; it’ll work for all your project code and any libraries you’re using. As you can imagine, having this information one keystroke away saves a lot of time. If the docs are not enough, you can also display the source for a function using [d, like…

Displaying the source function

 

It’s nice to see good example code from clojure.core, but it’s invaluable when looking up that function you just wrote that you now need to reference.

Want to know more?

After using vim-fireplace for a little while now it is such a massive step-up from my Slime + Screen setup it’s not even funny. I don’t know if this is on a par with Emacs’ nREPL yet, but to me it feels really, really well integrated, and I love it. The project is reasonably new and very active on Github, so hopefully it’s got a solid future.

Pete Withers-Jones

Head of Development

Pete Withers-Jones leads Box UK’s Development Practice, and has over 20 years of experience in software development, working across various industries and technologies.

Subscribe now and get our expert articles straight to your inbox!

"*" indicates required fields

Privacy*
This field is for validation purposes and should be left unchanged.

Have a project you’d like to discuss?

Give us a call on 020 8098 2093 or fill in the form and we will get back to you.

This field is for validation purposes and should be left unchanged.