Emacs Clojure IDE based on UNREPL
Switch branches/tags
Nothing to show
Clone or download
Latest commit 907b979 Jan 26, 2018
Failed to load latest commit information.
gifs Update README and add new gifs Jan 6, 2018
parseclj @ f87278a Update `parseclj` reference to `clojure-emacs/parseclj` Jan 14, 2018
tests Revert "Try out undercover" Dec 29, 2017
tools Behold the genesis of SPIRAL Dec 26, 2017
unrepl @ d8c24e1 Update unrepl submodule and blob.clj to include new spiral ns Dec 26, 2017
.dir-locals.el Minor typo fix Nov 28, 2017
.gitignore Add Cask Dec 3, 2017
.gitmodules Update `parseclj` reference to `clojure-emacs/parseclj` Jan 14, 2018
.travis.yml Add and setup linting in CI Dec 29, 2017
Cask Revert "Try out undercover" Dec 29, 2017
LICENSE Rework README file a bit more. Nov 16, 2017
README.org Update README and add new gifs Jan 6, 2018
blob.clj Update UNREPL blob Feb 23, 2018
documentation.org Behold the genesis of SPIRAL Dec 26, 2017
session-actions.edn Behold the genesis of SPIRAL Dec 26, 2017
spiral-ast.el Place cursor over elision buttons when loading more data Jan 4, 2018
spiral-attachment.el Behold the genesis of SPIRAL Dec 26, 2017
spiral-button.el Behold the genesis of SPIRAL Dec 26, 2017
spiral-loop.el Enable asynchronous print-settings update again Jan 4, 2018
spiral-mode.el Avoid "ensuring" connection when using completion Jan 24, 2018
spiral-overlay.el Behold the genesis of SPIRAL Dec 26, 2017
spiral-project.el Dry out templated actions with `spiral-project-templated-action` Dec 31, 2017
spiral-repl.el Implement REPL buttons navigation with `avy` Jan 4, 2018
spiral-socket.el Add `spiral-disconnect` function Dec 28, 2017
spiral-stacktrace.el First approach to accommodate to Clojure's Throwable->map breakage Dec 29, 2017
spiral-util.el Add a couple of new utility functions Dec 31, 2017
spiral.el Add `avy` as a dependency Jan 4, 2018


SPIRAL (beta)

https://img.shields.io/badge/Emacs-25-8e44bd.svg https://travis-ci.org/Unrepl/spiral.svg?branch=master https://melpa.org/packages/spiral-badge.svg

Emacs >= 25.1, Clojure >= 1.8.0

Pick your definition:

  • SPIRAL is a Clojure IDE for Emacs.
  • SPIRAL is a client interface to a Clojure’s Socket REPL through the UNREPL protocol.


Both definitions above are correct and complement each other.

SPIRAL started as a simple experiment for using the UNREPL protocol as the communication method between an Emacs buffer and a Clojure Socket REPL. With the pass of time, it has been evolving into a baby Clojure IDE. Currently it has a fair amount of Features.

SPIRAL’s UI is meant to rely heavily on the REPL buffer for displaying any kind of data that may be too big or complex to display in the Echo Area or as an overlay. The main idea is to allow you maintain focus on only two things during your development workflow: Your Clojure code (in clojure-mode buffers) and the REPL buffer. SPIRAL will try, whenever possible and reasonable, to favor displaying data in the REPL buffer over using external temporary buffers.

SPIRAL is of the same nature as CIDER. In fact, SPIRAL takes a lot of inspiration from CIDER’s features, but both differ in certain UI decisions (included the aforementioned.)

Another important difference is that SPIRAL is meant to be used to connect to Socket REPLs, where CIDER is built to connect to nREPL. Both Socket REPLs and nREPL serve the purpose of allowing you to connect to a running Clojure process, send it stuff to be evaluated and get data back. If you want to get deeper into these concepts, I encourage you to go read Arne Brasseur’s The Ultimate Guide To Clojure REPLs.

Lastly, SPIRAL is a young project, so if you are new to Clojure development in Emacs, for now I would recommend to start with CIDER, since it’s more stable, more & better documented, and has a bigger community behind it.

Quick Start



SPIRAL is available in MELPA, and it’s the recommended way to install it. Simply run:

M-x package-install [RET] spiral [RET]

Manual installation

  1. Install a.el, clojure-mode, and treepy. All available in MELPA.
  2. Download this repository, or clone it with its submodules:
    $ git clone --recursive https://github.com/unrepl/spiral
  3. Then place this repository, and its parseclj submodule copy, somewhere in your load-path. Or just paste this in your emacs configuration and evaluate it:
    (let ((spiral-dir "/path/to/your/copy/of/spiral/"))
      (add-to-list 'load-path spiral-dir)
      (add-to-list 'load-path (expand-file-name "parseclj" spiral-dir))
      (require 'spiral))

Connecting to a Socket REPL

The main way to connect to a Socket REPL in SPIRAL is by issuing: M-x spiral-connect.

When this command is executed in a buffer that belongs to a Clojure project, it will automagically create a Socket REPL for it and connect. Right now, SPIRAL supports only automatic connection in projects using Leiningen or Boot >= 2.7.2.

If you already have a Socket REPL running, you can prefix the connect command (C-u M-x spiral-connect) or issue M-x spiral-connect-to to get a prompt for inserting your Socket’s host and port.

There are several ways to create your own Socket REPL, here are some examples:

# clojure 1.9.0
$ clj -J-Dclojure.server.myrepl="{:port 5555,:accept,clojure.core.server/repl}"
# lein:
$ JVM_OPTS='-Dclojure.server.myrepl={:port,5555,:accept,clojure.core.server/repl}' lein repl
# or boot < 2.7.2:
$ boot -i "(do (require 'clojure.core.server) (clojure.core.server/start-server {:port 5555 :name :repl :accept 'clojure.core.server/repl}))" wait
# or boot >= 2.7.2:
$ boot socket-server --port 5555 wait
# or plain Clojure jar:
$ java -Dclojure.server.myrepl="{:port 5555,:accept,clojure.core.server/repl}" -jar ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar

After SPIRAL successfully connects to a Socket REPL you will be greeted with a REPL Buffer, and all your Clojure buffers related to the project you just connected will have the spiral-mode activated automatically.


Besides the REPL Buffer, SPIRAL enables a few commands in each Clojure Buffer running spiral-mode:

  • Autocompletion with company-mode.
  • C-c C-z: Switch to REPL buffer
  • C-x C-e: Evaluate expression before point.
  • C-c C-c: Evaluate top level expression.
  • C-c C-r: Send last evaluation to the REPL buffer.
  • C-c C-b: Evaluate buffer.
  • C-c C-g: Interrupt current evaluation.
  • M-s-.: Easy jumping through buttons with avy.
  • C-c q: Quit SPIRAL.


Automatically create a Socket REPL using your project’s build tool

SPIRAL currently supports Leiningen, Boot >= 2.7.2, or Clojure’s clj CLI. In this example, the project has both a `build.boot` file and a `deps.edn` file, so `spiral-connect` prompts for a way to run the project.


Connect to an existing Socket REPL


Elided data structures

Taking advantage of one of UNREPL’s nice features, the REPL buffer will elide big or complex data structures with clickable buttons.


Easy shortcut to navigate buttons

Making use of the awesome avy library, SPIRAL provides a REPL shortcut to jump to any button in the screen. Bound to M-s-.. Watch how easy is to jump to the 1st, 3rd, and 5th button on the screen.


Playing with Images? why not opening them in the REPL?

SPIRAL supports displaying buffered images directly in the REPL.


Standard output strings can be grouped into their respective REPL entries

This is a customizable feature, you can turn it off by setting spiral-repl-group-stdout to nil.


In place documentation

A la Unravel. Hit C-c C-d to get in-place documentation of the symbol at point.


Pretty (and elided) stacktraces

For now, stacktraces show differently between Clojure 1.8.0 and 1.9.0, due to a breaking change in Clojure. See also unrepl#27.


Even for lazy errors

Lazy errors are reduced to a minimum expression, with a button to inspect further.


Interactive evaluation results overlays

Same as CIDER and LightTable.


Is the result too big? Inspect it in the REPL

When interactive results are too big for in-buffer overlays, you can just move them to the REPL buffer and inspect them there.

SPIRAL will also copy/paste the evaluated expression and add it to the REPL history.


Interactive Exception happened? Inspect it in the REPL

Exceptions are shown in the REPL buffer, no matter where they come from. SPIRAL will try to figure out which expression caused the exception and will copy it to the REPL buffer as well.



Please refer to CONTRIBUTING.org.


  • UNREPL: the protocol.
  • Unravel: an UNREPL terminal-based client.
  • The Ultimate Guide To Clojure REPLs on the Socket REPL.
  • replicant: proof of concept of using Socket REPL for tooling

Join the #unrepl channel in the Clojurians slack!


© 2017 Daniel Barreto

Distributed under the terms of the GNU GENERAL PUBLIC LICENSE, version 3.