Skip to content



Folders and files

Last commit message
Last commit date

Latest commit


Repository files navigation

It takes a Miracle to reach Arcadia

Miracle - an Arcadia nREPL client

Miracle is a fork of Monroe, which in turn is a nREPL client for Emacs. Miracle is meant to be used with ClojureCLR in general, and Arcadia in particular.

Since Arcadia runs on CLR there are some things that needed to be changed in Monroe in order for e.g. jump to definiton to work.

If you are not familiar with nREPL, it is protocol for accessing Clojure REPL over the network.

The name comes from Marilyn Monroe's sister, who's last name is Miracle.

Below follows a description of Monroe, which currently applies to Miracle as well.

About Monroe

In short, Monroe aims to have:

  • easy access to Clojure REPL via nREPL protocol
  • simple installation without any dependencies, except Emacs
  • REPL with colors and history support
  • generic approach - you can use it with other languages than Clojure
  • only REPL for interaction with shortcuts - no funny windows or buffers with errors, messages and other distractions

On other hand, Monroe is not:

  • Clojure IDE like Cider
  • Kitchen sink that will do Clojure work for you


Install Arcadia. Might work with other ClojureCLR nREPLs, but Arcadia is Miracle's primary focus.

Make sure you have clojure-mode.el installed first. You can get it from Marmalade repository, melpa or directly from here.

Clone this repository into .emacs.d, it's currently not on melpa.

cd ~/.emacs.d
git clone

In your Emacs init file, put:

(add-to-list 'load-path "~/.emacs.d/miracle")
(require 'miracle)
(add-hook 'clojure-mode-hook 'clojure-enable-miracle)

Then either evaluate the rows or restart Emacs.

Then, in Emacs:

M-x miracle [RET]

and follow the question about nREPL server location and port. The defaults are the same as Arcadia's defaults.

To configure autocomplete, head on down.

Keys and shortcuts

Miracle shortcuts for code buffer

These shortcuts are valid from code buffer where you edit Clojure code and where miracle-interaction-mode is activated.

Keys Description
C-c C-c Evaluate expression at point.
C-c C-r Evaluate region.
C-c C-k Evaluate current buffer contents.
C-c C-l Load current file from disk.
C-c C-d Describe symbol at point, showing documentation in REPL window.
C-c C-n Evaluate namespace.
C-c C-b Interrupt running job.
M-. Jump to definition of var at point.
M-, Jump back to where you were before you did M-.

Note the difference between C-c C-k and C-c C-l; the former loads the contents of the buffer and sends them directly over the wire; this can differ from the state of the namespace on disk, and doesn't always convey line number information. It loads each top-level form in the file individually, and if one of them fails it will continue compiling the rest. The second one tells the server to load the whole file from its disk, so if you are connected to a remote server and have made changes to your local copy, they will not be loaded. However, a single exception will halt the whole thing.

Miracle shortcuts for REPL buffer

These shortcuts are valid in REPL buffer; also, most of the standard comint-mode shortcuts should work without problems.

Keys Description
C-c C-d Describe symbol at point, showing documentation in REPL window.
C-c C-c Interrupt running job.
M-. Jump to definition of var at point.
C-c C-f Replaces the last result with a pretty printed version of it. f is for formatting.

For autocompletion, use the following (thanks sogaiu)


Installation instructions for clojure-complete:

# in your Unity project directory
cd Assets
git clone
cd clojure-complete
git checkout clr-support

Put the following in your init.el.

(with-eval-after-load "miracle"
  (defun miracle-eval-string (s callback)
     (lambda (response)
             (miracle-dbind-response response (id value status)
                                     (when (member "done" status)
                                       (remhash id miracle-requests))
                                     (when value
                                       (funcall callback nil value))))))

  (defun miracle-get-completions (word callback)
     (format "(do (require '[%s]) (%s/completions \"%s\"))"
             "complete.core" "complete.core" word)
     (lambda (err s)
              ;; XXX
              (message (format "received str: %s" s))
              (message (format "err: %s" err))
              (when (not err)
                (funcall callback (read-from-whole-string s)))))))

  (defun company-miracle (command &optional arg &rest ignored)
    (interactive (list 'interactive))
    (cl-case command
             (interactive (company-begin-backend 'company-miracle))
             (prefix (and (or ;;(eq major-mode 'clojurec-mode)
                           ;;(eq major-mode 'clojure-mode)
                           (eq major-mode 'miracle-mode))
                          (get-buffer "*miracle-connection*")
                          (substring-no-properties (company-grab-symbol))))
             (candidates (lexical-let ((arg (substring-no-properties arg)))
                                      (cons :async (lambda (callback)
                                                           (miracle-get-completions arg callback)))))))

  ;; XXX: problems w/o the following when invoking company-grab-symbol
  (setq cider-mode nil)

  (add-to-list 'company-backends 'company-miracle)

Bug reports & patches

Feel free to report any issues you find or you have suggestions for improvements.


Arcadia opiniated Clojure nREPL client for Emacs






No packages published


  • Emacs Lisp 96.5%
  • Makefile 3.5%