September 10, 2015

Emacs, Cider, nREPL, and Clojure

I remember it being daunting when I first got started using clojure in emacs. Whether you're just getting started, or just need a refresher, here's a quick description of the different pieces that make emacs a great editor for clojure.

  • Emacs - I'm pretty certain it will take me more than my lifetime to learn everything there is to know about emacs. I've been using emacs for several years now. I've learned a ton about software and the history of computers by using emacs. It's a lot of work to get to the point where your comfortable, but as someone who's been through it, I would definitely highly recommend putting in the effort.
  • Clojure REPL - A repl is a Read, Eval, Print, Loop. Fundamentally, a REPL is just a program that reads some input, evaluates it, prints some results and waits for more. It's amazing to me how much this simple concept promotes experimentation, creativity, and exploration. A simple clojure REPL can be started like this
java -cp clojure.jar clojure.main
  • Clojure nREPL - The clojure nREPL is a Networked REPL. The default clojure repl only knows how to communicate by reading strings from standard input. The Network REPL builds on this by introducing the concepts of a REPL client and a REPL server. The tools.nrepl package provides a set of operations and some protocols that describes how a repl client can talk to a repl server. This opens up the possibility for programs to provide REPL like experiences over sockets, http, or whatever! Brilliant!
  • nREPL Middleware - The basic nREPL only provides a few operations such as load-file and eval. But what if you want provide other operations such as code completion, or debug information, or refactor variable names? That's what nRepl Middleware is for. Middlware provides a way that anyone can easily extend and add to the basic nRepl operations and functionality.
  • Cider - Ok, so we have a nREPL server that runs in a JVM. Any sort of client can connect to the nREPL server as long as it knows how to speak nREPL (using the operations in order to communicate with the server running in the JVM). So, wouldn't it be awesome if we could use Emacs as a nREPL client?! And also, wouldn't it be amazing if Emacs knew how display nicely formatted clojure code? Well, that's what Cider does. Cider is an elisp package that tells Emacs how to display and interact with clojure code.
  • cider-nrepl. If you have a nREPL server started in a jvm, and the emacs cider elisp package installed, then that's all you need to get started. The cider package contains a cider-nrepl.el file that knows how to communicate with a nREPL. But, to take full advantage of all the potential goodness that cider is capable of (such as code completion and debugging), you should also instrument the nREPL with some custom middleware. cider-nrepl is clojure code that enhances the nREPL with extra middleware that the cider elisp package knows how to take advantage of. The 2 steps to setup the cider-nrepl middleware are 1) add cider-nrepl as a dependency to your clojure project (usually via lein or boot) and 2) configure the nREPL to use the cider-nrepl middleware (also usually done using lein or boot).
  • clj-refactor elisp. But wait! There's even MORE emacs clojure goodness! The clj-refactor is another elisp package available to install into emacs. It provides even more functionality to your emacs experience such as the ability to quickly search, find, download, and include clojure library dependencies in your projects.
  • refactor-nrepl - After you've installed the clj-refactor elisp package to emacs, it's also necessary to make nREPL aware of the extra operations that the refactor-nrepl elisp code wants to use. In order to do so, you'll need to do 2 steps: 1) add refactor-nrepl clojure package as a dependency inside your project (usually via lein or boot) and 2) configure the refactor-nrepl middleware (also usually via lein or boot).

It's a bit of work and a little overwhelming the first time, but once you have it all setup and working, Emacs + cider + clojure + nrepl is really a super powerful combination.

Tags: clojure emacs tech