Having a Clojure REPL (Read Eval Print Loop) right inside Vim makes it easier to test ideas, get documentation, and explore your code. There are a few hoops that you need to jump through to enable it, but the payoff is worth it.
Leiningen isn’t required, but it makes managing the classpath for your REPL quite a bit easier and automates the inclusion of the files in your project so that they can be used in the REPL.
If you’ve already got clojure installed and are managing your classpath some other way, you’ll want to modify the nailgun server script below to remove the call to
lein and ensure you’re getting clojure and other classes in the ng-server’s classpath.
Install Leiningen if you don’t have it already.
Put it somewhere on your
PATH (such as
Set it to be executable:
chmod +x lein
Then, tell it to self-install with this command:
Now you should have a working
And you can create a new clojure project skeleton, with clojure 1.3.0 all ready to go with:
lein new myproj
It creates a skeleton project rectory and a
project.clj file that you can use to hold lib dependencies.
Go into that project and you can use lein to go into a repl, get the project’s classpath, run tests, etc. Use
lein help to see the full list of commands.
Install VimClojure in Vim
Install the VimClojure plugin in vim.
Hopefully, you’re already using Tim Pope’s vim script management script Pathogen.
If so, you should be able to just clone VimClojure into your bundle ectory:
cd .vim/bundle git clone git://github.com/vim-scripts/VimClojure.git
If you’re not using Pathogen, install the plugin with your normal process.
.vimrc, make sure you have these settings if they’re not already there (they need to be after the method that calls pathogen to install bundles):
filetype off call pathogen#runtime_append_all_bundles() ... filetype plugin indent on syntax on
and add these items to your
let g:vimclojure#HighlightBuiltins = 1 let g:vimclojure#ParenRainbow = 1
To test that VimClojure is installed OK, edit a clojure file (like this sample one modified from
(defn myplus ( 0) ([x] (cast Number x)) ([x y] (. clojure.lang.Numbers (add x y))) ([x y & more] (reduce myplus (myplus x y) more)))
If the parenthesis are differently colored in matched pairs, that means that “rainbow” parenthesis are enabled and the plugin is working. It should look something like this:
You’ll also want to update the helptags documentation for VimClojure:
Now you can lookup help for VimClojure:
You’ve now got a functioning VimClojure installation that can already be pretty helpful. If you want to get an integrated REPL installed, there’s a bit more to do.
Setting up Nailgun to work with VimClojure
This part is the trickiest part (in the github docs, they say “Here be Dragons”). I think the biggest difficulty is that they don’t show you how to configure/launch the nailgun server, we’ll go through those steps.
Nailgun is a server that runs an instance of the JVM. On startup, you tell it what classpath this JVM should run with. Then, with a nailgun client, you can send it additional classes to execute within that JVM and it can show you the output.
It makes things much faster as the Nailgun server is already running hot when you send it things to execute. You don’t pay any JVM startup penalty.
Warning: If you’ve previously tried to install nailgun through homebrew, it will not work with clojure. The server jar that homebrew uses is half the size of the server jar that we’re going to be using for clojure. Uninstall it or put the things below earlier in the classpath.
Compile the VimClojure nailgun client
hg clone https://bitbucket.org/kotarak/vimclojure
Go into the client directory and
make the ng client executable:
cd vimclojure/client # or cd vimclojure-nailgun-client make
This will create an executable called
ng in the current directory. Copy that somewhere in your path (likely the same place you put
You should now be able to type
ng and have it spit out help text.
% ng Usage: ng class [--nailgun-options] [args] (to execute a class) or: ng alias [--nailgun-options] [args] (to execute an aliased class) or: alias [--nailgun-options] [args] (to execute an aliased class, where "alias" is both the alias for the class and a symbolic link to the ng client) where options include: --nailgun-D
= set/override a client environment variable --nailgun-version print product version and exit --nailgun-showversion print product version and continue --nailgun-server to specify the address of the nailgun server (default is localhost) --nailgun-port to specify the port of the nailgun server (default is 2113) --nailgun-help print this message and exit
Setting up Nailgun Server
Put that jar somewhere that you won’t delete it, and then add an export for that location in your .bashrc/.vimrc, ex:
Now save this script as
ng-server and put it somewhere in your path and make it executable:
#! /bin/bash if [ -z $VIMCLOJURE_SERVER_JAR ]; then echo "Error! Need to define location of VimClojure nailgun server jar with:" echo "export VIMCLOJURE_SERVER_JAR=
" exit 1 fi if [ ! -f $VIMCLOJURE_SERVER_JAR ]; then echo "Error! Unable to find VimClojure nailgun server jar at '$VIMCLOJURE_SERVER_JAR'" exit 1 fi LEIN_CLASSPATH=$(lein classpath) if [ ! $LEIN_CLASSPATH ]; then echo "Warning! Unable to get classpath from lein, just using existing classpath, expecting clojure jars to be available" fi NG_CLASSPATH="$VIMCLOJURE_SERVER_JAR:$LEIN_CLASSPATH:$CLASSPATH" echo java -server -cp "$NG_CLASSPATH" vimclojure.nailgun.NGServer java -server -cp "$NG_CLASSPATH" vimclojure.nailgun.NGServer
Then add this to your .vimrc setup:
" this should only be necessary if you don't have the ng client in your PATH let vimclojure#NailgunClient = "/path/to/your/ng" let vimclojure#WantNailgun = 1
Now, from the root of a lein project, make sure you’re dependencies are updated:
lein deps // puts things defined in project.clj into ./lib by default
Without additional configuration, you’ll likely just have the clojure-1.3.0.jar in there.
The script above leverages lein to create a classpath that the nailgun server can use. If you run
lein classpath, you’ll see what it will use:
% lein classpath /Users/tnaleid/Documents/workspace/clojure-test/myproj/test:/Users/tnaleid/Documents/workspace/clojure-test/myproj/test-resources:/Users/tnaleid/Documents/workspace/clojure-test/myproj/src:/Users/tnaleid/Documents/workspace/clojure-test/myproj/classes:/Users/tnaleid/Documents/workspace/clojure-test/myproj/resources:/Users/tnaleid/Documents/workspace/clojure-test/myproj/lib/clojure-1.3.0.jar
Now, you should be able to start up a nailgun server from the root of a lein project and have it automatically pull in all dependencies, ready to recieve client requests.
Open up the src/leinprojectname/core.clj file in vim. Then press
to get a REPL window that you can interact with. (if you’ve remapped localleader to something else, replace
\ with your custom key)
There are quite a few other things you can do with the REPL, check out
:help VimClojure and go down to
Keybindings for more details.
Here are some good starter ones:
\el - eval current line \eb - eval current visual block selected \ef - eval current file \sr - start interactive REPL \sR - start interactive REPL initialized to have same namespace as current buffer \si - prompt for input and lookup with (source) \fd - prompt for input and lookup with (find-doc)
The Pain is Over, Now Reap the Rewards
Once all this configuration is done, it should be as easy as running the server in a lein project:
And then editing your files in vim accessing the embedded REPL whenever you need it.