Code Evaluation

Code evaluation is at the heart of interactive programming. CIDER provides a ton of evaluation-related commands that can cover just about any use-case one can possibly imagine.

All evaluation commands are defined in cider-eval.el.

Terminology

CIDER’s evaluation commands use a terminology that’s popular within Emacs, but somewhat confusing to people not familiar with it. Let’s take a look at it:

  • defun - top-level expression

  • sexp - s-expression, form

  • last-sexp - the form preceding the cursor (point in Emacs lingo)

  • sexp-at-point - the form under/around the cursor

  • buffer - the abstraction used by Emacs to represent any content; most often backed by a file.

  • region - the selected part of a buffer

  • load - a synonym for "evaluate"; most often used in the context of buffers/files

Basic Evaluation

As CIDER derives almost all of its functionality by inspecting the runtime (REPL) state of your application, you need to evaluate something before functionality like code completion, eldoc or definition lookup would work.

Typically the first think you’d do when visiting a Clojure buffer would be to load (evaluate) the buffer with cider-load-buffer (C-c C-k).

Afterwards most of the time you’d be evaluating expressions one at a time either using cider-eval-last-sexp (C-c C-e or C-x C-e) or cider-eval-defun-at-point (C-c C-c or C-M-x).

What happens if I don’t evaluate the entire buffer first?

You might be wondering why do you need to evaluate the entire source buffer. After all, won’t be it be nice if you could just start evaluating only the forms you’re interested in?

Technically speaking you’re not required to evaluate the entire source buffer first, but not doing so introduces some subtleties and a bit of complexity. In general the only part that’s really essential for subsequent code evaluations is the ns declaration. As expressions within the buffer are evaluated in the context of its namespace and you have to create that namespace first.

In the early days of CIDER, when a namespace didn’t exist CIDER would just throw an error. A lot of people were confused by this behavior and unhappy about it. Eventually CIDER became smarter and now it always knows whether the ns form in some source buffer has been evaluated or changed after it was originally evaluated. With that knowledge in hand CIDER will auto-eval ns forms that were changed prior to evaluating code in that namespace, if you don’t evaluate them yourselves. That behavior is controlled via the variable cider-auto-track-ns-form-changes.

Typically this type of evaluation commands would provide you with dual feedback - you’d see the results in both the Emacs minibuffer and in an inline overlay in the source buffer.

In case the result of the evaluation is big (e.g. a map with dozens of keys) it might be best to display it in a dedicated buffer. You can do this with cider-pprint-eval-last-sexp (C-c C-p). As a bonus - the result will be pretty-printed in the result buffer.

Why aren’t results always pretty-printed?

Many people might be wondering why doesn’t CIDER pretty-print all of the results all of the time. After all - pretty-printed results are always easier to read, right?

The reason for not doing this is pretty simple - multi-line results don’t look very good in the minibuffer and overlays. That’s why there’s little point in pretty-printing results there.

As most of the time you’ll know in advance what kind of result to expect, we feel it’s best to leave it to you to decide which evaluation command to use depending on the situation.

Exotic Evaluation Commands

WIP

While the basic evaluation commands discussed earlier should be enough for most people, CIDER features a ton of additional evaluation commands. Some of them are so peculiar that one can easily label them "exotic". This section will briefly go over some of them.

Broadly speaking the exotic evaluation commands can be grouped in the following categories:

  • commands that are a variation of some basic commands (e.g. cider-eval-list-at-point and cider-eval-sexp-at-point)

  • commands that insert the result in the current buffer (e.g. cider-eval-last-sexp-and-replace)

  • commands that evaluate an expression in a different context (e.g. with user-supplied bindings)

  • commands that evaluate some particular part of a buffer (e.g. cider-eval-ns-form)

Most of the exotic evaluation commands don’t have "top-level" keybindings and should be accessed via CIDER’s evaluation commands keymap (cider-eval-commands-map), meaning that they share the standard prefix C-c C-v. On top of this - several related commands that pretty-print their result are grouped under C-c C-v C-f.

Evaluating Clojure Code in the Minibuffer

You can evaluate Clojure code in the minibuffer at almost any time using M-x cider-read-and-eval (bound in cider-mode buffers to C-c M-:). TAB completion will work in the minibuffer, just as in REPL and source buffers.

Typing C-c C-v . in a Clojure buffer will insert the defun at point into the minibuffer for evaluation. This way you can pass arguments to the function and evaluate it and see the result in the minibuffer.

You can also enable other convenient modes in the minibuffer. For instance, you might want to have both eldoc-mode and paredit-mode available to you:

(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode)
(add-hook 'eval-expression-minibuffer-setup-hook #'paredit-mode)

Evaluation Hooks

You can use cider-file-loaded-hook to trigger some action after a file has been evaluated.

cider-auto-test-mode is implemented in terms of this hook - tests are re-run every time you evaluate a file.

You can use cider-before-eval-hook to trigger some action before eval request is sent to nrepl server.

You can use cider-after-eval-done-hook to trigger some action after the eval response was received from nrepl server with status "done".

Synchronous vs Asynchronous Evaluation

nREPL has an asynchronous evaluation model, where eval requests are enqueued and the responses are sent back to the clients when available. This model works great most of the time as doesn’t require clients to block while waiting for responses, but it also requires the clients to able to handle comfortably response callbacks.

Unfortunately, some of Emacs’s internal APIs don’t play well with asynchronous evaluation (e.g. completion, eldoc, etc) and in those cases CIDER simulates synchronous evaluation instead. It’s important to understand several things:

  • CIDER’s sync eval commands should be used sparingly

  • The most common use case for the sync eval API is evaluating some simple and fast to run tooling-related code

  • Sync eval may result in client lock-ups, as Emacs is (mostly) single-threaded by design

CIDER tries to mitigate the latter by imposing a 10 second eval request timeout for sync eval. You can adjust this default if needed:

;; increase the sync request timeout to 1 minute
(setq nrepl-sync-request-timeout 60)

;; disable sync request timeout
(setq nrepl-sync-request-timeout nil)
CIDER internally increases the timeout to 30 seconds for the first sync eval request it does, as it might require a lot of namespaces and take more time to complete. See cider—​prep-interactive-eval for details.

Configuration

Enable evaluation interrupts on Java 21 and newer

The configuration variable cider-enable-nrepl-jvmti-agent has to be enabled for interrupts to work properly on Java 21+. See JVMTI agent section.

Display Spinner During Evaluation

Some evaluation operations take a while to complete, so CIDER will display a visual indicator (a spinner) in the modeline to indicate this. The evaluation-in-progress spinner can be controlled by several variables:

  • cider-eval-spinner-type (default value 'progress-bar) - controls the appearance of the spinner. See `spinner-types for all possible options.

  • cider-eval-spinner-delay controls the time (in seconds) after which to show the spinner. The default value is 1 second.

  • cider-show-eval-spinner controls whether to show the spinner at all. Set this variable to nil to disable it.

CIDER uses internally the excellent package spinner.el.

Overlays

When you evaluate code in Clojure files, the result is displayed in the buffer itself, in an overlay right after the evaluated code. If you want this overlay to be font-locked (syntax-highlighted) like Clojure code, set the following variable.

(setq cider-overlays-use-font-lock t)

Overlays will be shown for errors, as long as they are not already displayed by cider-stacktrace-mode. In order to always favor error overlays over the *cider-error* buffer, please customize:

(setq cider-show-error-buffer nil)

If you only want to see overlays for errors (and not for successful evaluations), you can restrict overlays to only be shown for errors (and display non-error results in the echo area at the bottom) by customizing the cider-use-overlays variable:

(setq cider-use-overlays 'errors-only)

You can disable overlays entirely (and display results in the echo area at the bottom) with the cider-use-overlays variable:

(setq cider-use-overlays nil)

Overlays that indicate errors are by default trimmed of file/line/phase information.

(Example: the entire Syntax error compiling at (src/ns.clj:227:3). preamble)

You can prevent any trimming by customizing instead:

(setq cider-inline-error-message-function #'identity)

By default, result overlays are displayed at the end of the line. You can set the variable cider-result-overlay-position to display results at the end of their respective forms instead. Note that this also affects the position of debugger overlays.

(setq cider-result-overlay-position 'at-point)

You can also customize how overlays are persisted using the variable cider-eval-result-duration.

By default, its value is 'command, meaning that result overlays disappear after the next user-executed command, such as moving the point or scrolling.

Setting the variable to a number represents the duration in seconds until overlays are removed, while setting it to ’change' persists overlays until the next change to the buffer contents.

(setq cider-eval-result-duration 5.0)
(setq cider-eval-result-duration 'change)

Auto-Save Clojure Buffers on Load

Normally, CIDER prompts you to save a modified Clojure buffer when you type C-c C-k (cider-load-buffer). You can change this behavior by adjusting cider-save-file-on-load.

Don’t prompt and don’t save:

(setq cider-save-file-on-load nil)

Just save without prompting:

(setq cider-save-file-on-load t)

Change the Result Prefix for Interactive Evaluation

Change the result prefix for interactive evaluation (not the REPL prefix). By default the prefix is `⇒ `.

(setq cider-eval-result-prefix ";; => ")

To remove the prefix altogether, just set it to the empty string ("").

Change the Output Destination

By default CIDER will display the output produced by some evaluation in the REPL buffer, but you can also funnel the output to a dedicated buffer. You can configure this behavior via cider-interactive-eval-output-destination.

(setq cider-interactive-eval-output-destination 'output-buffer)

Additionally, there’s the variable cider-redirect-server-output-to-repl that captures output that would normally end up in the *nrepl-server* buffer (provided it has been started via cider-jack-in) and redirects it to the REPL buffer. You can disable this redirection like this:

(setq cider-redirect-server-output-to-repl nil)
The redirection functionality is implemented in cider-nrepl as nREPL middleware. If you’re using CIDER without cider-nrepl no output redirection is going to take place.

Storing eval results

By default CIDER stores the return value of the most recent evaluation command in the text register e. You can access these contents via insert-register (C-x r i).

This is often useful for closer inspection or textual manipulation of a transiently displayed eval result, without having to re-evaluate the form with a specialized command like cider-insert-last-sexp-in-repl.

You can customize which register is used with the variable cider-eval-register, or set it to nil to disable the feature.

(setq cider-eval-register nil)
The built-in inspector can be used to view and navigate through complex nested results.

You can also use the command cider-kill-last-result(C-c C-v k) after any eval command to store its result in the kill ring. This works even when the cider-eval-register feature is disabled.

Evaluating code inside comments

By default, when using the defun-level eval commands inside a top-level comment form the return value is always nil. Calling cider-eval-defun-up-to-point with point at <point> also returns nil:

(comment
  (let [b "str"]
    (-> b
        keyword<point> ;;=> nil
        name))
  *e)

That’s not a bug, that’s simply how the comment form works (it simply returns nil when evaluated). However, it is often desirable to treat the form the point is in as if was not inside a comment. To help with this clojure-mode supplies the variable clojure-toplevel-inside-comment-form. If this variable is set to t then defun-level commands will ignore the comment wrapper. Let’s revisit the previous example:

(comment
  (let [b "str"]
    (-> b
        keyword<point> ;;=> :str
        name))
  *e)

With cider-eval-defun-at-point we get:

(comment
  (let [b "str"]
    (-> b
        keyword<point>
        name)) ;;=> "str"
  *e)

Keybindings

You might have noticed that CIDER typically has 2-3 different keybindings for many evaluation commands. In case you’ve been wondering "Why?" the answer is pretty simple - legacy. The principle sources of inspiration for CIDER, Emacs and SLIME, provide more or less the same functionality, but use different keybindings. CIDER tried to find a common ground by adopting them both.

On top of this, at some when it became clear that CIDER has set the world record for evaluation command, we’ve introduced a dedicated keymap for all eval commands (that’s everything with the prefix C-c C-v). This leads to funny situations like cider-eval-defun-at-point having 3 keybindings:

  • C-M-x (Emacs style)

  • C-c C-c (SLIME style)

  • C-c C-v (C-)d (CIDER style)

Okay, those are technically 4 keybindings, but who’s counting!

Some of you are probably wonder why C-c C-v instead of C-c C-e, right? Again - legacy. Historically C-c C-e was mapped to cider-eval-last-sexp, otherwise we would have picked this binding. It’s still possible to recycle it down the road, as most people are probably using C-x C-e for cider-eval-last-result and good keybindings are too precious to be wasted like this.

Below is a listing of most keybindings for evaluation commands:

Command Keyboard shortcut Description

cider-eval-last-sexp

C-x C-e
C-c C-e

Evaluate the form preceding point and display the result in the echo area and/or in an buffer overlay (according to cider-use-overlays). If invoked with a prefix argument, insert the result into the current buffer.

cider-tap-last-sexp

C-c C-v q
C-c C-v C-q

Like cider-eval-last-sexp but also taps the result.

cider-eval-last-sexp-and-replace

C-c C-v w

Evaluate the form preceding point and replace it with its result.

cider-eval-last-sexp-to-repl

C-c M-e

Evaluate the form preceding point and output it result to the REPL buffer. If invoked with a prefix argument, takes you to the REPL buffer after being invoked.

cider-insert-last-sexp-in-repl

C-u C-c M-p

Load the form preceding point in the REPL buffer and eval.

cider-pprint-eval-last-sexp

C-c C-p
C-c C-v C-f e

Evaluate the form preceding point and pretty-print the result in a popup buffer. If invoked with a prefix argument, insert the result into the current buffer as a comment.

cider-pprint-eval-defun-at-point

C-c C-v C-f d

Evaluate the top level form under point and pretty-print the result in a popup buffer. If invoked with a prefix argument, insert the result into the current buffer as a comment.

cider-eval-defun-at-point

C-M-x
C-c C-c

Evaluate the top level form under point and display the result in the echo area.

cider-eval-list-at-point

C-c C-v l
C-c C-v C-l

Evaluate the list around point.

cider-eval-sexp-at-point

C-c C-v v
C-c C-v C-v

Evaluate the form around point.

cider-eval-defun-at-point

C-u C-M-x
C-u C-c C-c

Debug the top level form under point and walk through its evaluation

cider-tap-sexp-at-point

C-c C-v t
C-c C-v C-t

Evaluate and tap the form around point.

cider-eval-defun-up-to-point

C-c C-v z

Evaluate the preceding top-level form up to the point.

cider-eval-region

C-c C-v r

Evaluate the region and display the result in the echo area.

cider-interrupt

C-c C-b

Interrupt any pending evaluations.

cider-eval-ns-form

C-c C-v n

Eval the ns form.

cider-load-buffer-and-switch-to-repl-buffer

C-c M-z

Load (eval) the current buffer and switch to the relevant REPL buffer. Use a prefix argument to change the namespace of the REPL buffer to match the currently visited source file.

cider-load-buffer

C-c C-k

Load (eval) the current buffer.

cider-load-file

C-c C-l

Load (eval) a Clojure file.

cider-load-all-files

C-c C-M-l

Load (eval) all Clojure files below a directory.

cider-kill-last-result

C-c C-v k

Save the last evaluated result into the kill ring.

You’ll find all evaluation commands and their keybindings in the CIDER Eval menu.