Clojure and Vim: An overview
It's very possible


I want to encourage Vim users to continue using Vim as their primarydriver, even for Clojure. This isn’t about Emacs vs Vim, it is aboutencouraging people to not change editor because they’ve changedlanguage.
Vim is a very capable editor. I want to give you an overview of theplugin set I use to work with Clojure every day.
The core toolset
These are the central parts of my workflow that I build all else from.
Neovim
At the start of my journey, I switched to Neovim from Vim. Neovim is afork of Vim that aims to refactor the legacy code base, and bring modernfeatures.
The first innovation from Neovim is async. These have permitted pluginslikeasync-clj-omni toappear for asynchronous auto-completion, and async repl plugins such asacid for non-blockingevaluations.
Another innovation of Neovim’s is the fluent RPC api and plugin hostcapabilities. These allow you to write plugins in any language for vim.In fact,snoe wroteclj-refactor.nvim inClojurescript, taking advantage of libraries such asrewrite-cljs, for REPL-lessrefactoring for Clojure.
Writing plugins for a language, in that language, is the way to go
- Case Nelson, author ofclj-refactor.nvim
nREPL middleware
Both CIDER & clj-refactor.el are extremely popular within the Emacscommunity. Powering both are editor-agnostic APIs available through thenREPL as middleware. This means I get access to much of the samefunctionality in Vim directly from the same code base.
Due to the accessibility and usefulness of these APIs, they are used inmany Clojure plugins. Amongst the many features the middleware providesare:
Syntax aware completions
Code refresh (without a dependency)
An Enhanced doc API including information such as specs
Locate uses of a var
Format code
Locate file for dependency (jump to source into jars)
Fireplace.vim
Thefireplace plugin is annREPL client. It’s purpose is to integrate Vim with your REPL. It’s avery simple plugin, providing a light interface over the nREPL andcommon interactions with it. It’s the centerpiece of my REPL workflow.
It provides a number of features:
Evaluation in the buffer
cppCommand to run arbitary code
:Eval (+ 1 1)Manual omni-completion you can activate with
<C-x><C-o>Automatic nREPL connection
Docs for symbol under cursor
KJump to definition
[<C-D>
My secret weapon from fireplace iscp. It can evaluate a text object(region of text) you give it. Many overlook the usefulness of thislittle operation, but it’s extremely handy when composed with vim-sexp.
Fireplace takes advantage of CIDER-nREPL for a number of features (e.g.the completion, and augmenting minor functionality), displaying thenon-specificity of the middleware.
Sexp
vim-sexp is the paredit of the Vimworld. It would be amiss to not mentionvim-sexp-mappings-for-regular-peoplewhich adds mappings that are easier to use, but override built-ins.
It has support for a number of operations (slurpage, barfage, raiseparent, etc.). It provides text objects which make it easy to refer tosections of code, and there are motions for navigating quickly.
The text objects for referring to parts of s-expressions are anoverlooked part of Sexp. I’ll use an example where| is my cursor inthe snippet:
(def price 500.0)(defn enterprise-price [] (* pr|ice 10))Withie refers to the “element” I’m on, this is a special meaning invim-sexp (see the readme for moredetails on what an element is in sexp). In this case, it refers toprice, so combined with fireplace, I can docpie to evaluatepriceand see500.0 printed at the bottom.
iecpie will evaluateprice and print out10.0 at the bottomof the screen.
afcpaf will evaluate(* price 10) and print out5000.0 at thebottom of the screen
aFcpaF will re-evaluate thedefn and update the functiondefinition
Of course, all these objects are compatible with the operators youalready know likeyankdelete
20% improvements
These are some plugins which don’t form the backbone of my workflow, butmake a 20% improvement.
Deoplete
Deoplete provides as-you-typeasyncronous omnicompletion. Usingasync-clj-omni you canextend Deoplete’s completion to include Clojure. I found the defaultfireplace completion (combined with auto-completion) would slow downduring mass typing and cause the editor to lock up whilst it caught up.
Custom Bindings
Vim’s built-in extensibility means you can very easily add mappings todo things like a reset with,rs:
nnoremap <localleader>rs :Eval (dev/reset)<CR>I find that I have a number of minor bindings that are useful forautomating repetitive evaluations on a project. They really augment theREPL workflow in their nature.
Parinfer
parinfer is a great system forediting Lisp code which uses your indentation level to figure out thecorrect parens to insert. Changing the indentation of your code changeswhere the parens are placed.
nvim-parinfer.js is avim plugin written in Clojurescript which addsparinfer support using theoriginal javascript library. It was one of the earliest plugins and is agreat way to edit Sexps.
clj-refactor.nvim
Another plugin bysnoe, this plugin adds manyof the features fromclj-refactor.el toNeovim. Many of the refactorings don’t even need a REPL to function. Theplugin is, written in Clojurescript, so it can take advantage of theClojure ecosystem’s libraries which have been written to manipulatecode.rewrite-cljs, andcljfmt both underly thisplugin.
Future adventures
Acid
Here be dragons, only for the truest of heart.
acid is an upcoming plugin forNeovim that absolutely deserves a mention. It’s attempting to rebuildthe fireplace you know and love in Python, to add a fully asyncinterface to it. The plugin is in alpha, but is something to keep an eyeon.
neovim-client
neovim-client is aclient for Neovim, written in Clojure. The idea is to provide make itsimpler to run the JVM clojure as a plugin language for Neovim.
One of the included examples is asocket REPLclient, which isa very impressive display of how this library could be used to buildplugins for Vim.
Next Post(s)
Some of my current ideas for future posts:
A detailed beginner setup guide for all these tools
Some information on how I have built out my environment, and myfavorite mappings
Me
I share my dotfiles publicly, particularly of interest is probably myclojurefolder.Please peruse them, copy from them, learn from them.
You can come bother me in#vim-fireplace asdominicm in theClojurians Slack, and I’ll try my best to helpyou with Vim.



