Pretty-printing

Configuring a printing function

CIDER relies on nREPL’s own value printing mechanism. Refer to nREPL’s documentation for details.

You can configure the function used by CIDER for pretty-printing evaluation results and other data using the option cider-print-fn, which can take the following possible values:

  • nil to defer to nREPL to choose the printing function. This will use the bound value of nrepl.middleware.print/*print-fn*, which defaults to the equivalent of clojure.core/pr.

  • pr to use the equivalent of clojure.core/pr.

  • pprint to use the classic clojure.pprint printer (this is the default).

  • orchard to use orchard.pp, a fast pretty-printer bundled with cider-nrepl. See below for why you might want it.

  • fipp to use the Fast Idiomatic Pretty-Printer. This is approximately 5-10x faster than clojure.core/pprint.

  • puget to use Puget, which provides canonical serialization of data on top of fipp, but at a slight performance cost.

  • zprint to use zprint, a fast and flexible alternative to the libraries mentioned above.

For fipp, puget, and zprint printers to work, you need to add the respective dependency in your project explicitly.

Give orchard.pp a try

The default pprint printer produces the clojure.pprint output everyone knows, but orchard.pp fits a tooling context better in a few ways:

  • it’s noticeably faster

  • it doesn’t realize lazy seqs in full as it prints, so an infinite or huge lazy sequence won’t hang the printer or trigger its side effects mid-print

  • it honors *print-length* and *print-level* and bounds the total size of what it prints, so a deeply nested value won’t flood the REPL buffer

Its output differs slightly from clojure.pprint in places, which is why it hasn’t been made the default (yet), but it’s well worth a try:

(setq cider-print-fn 'orchard)

Like the default printer, it requires no extra dependencies - it ships with cider-nrepl.

Alternatively, cider-print-fn can be set to the namespace-qualified name of a Clojure var whose function takes three arguments:

  • the object to print

  • the java.io.PrintWriter to print on

  • a (possibly nil) map of options.

(setq cider-print-fn "user/my-pprint")

Here’s one example:

(ns cider.pprint
  (:require
   [clojure.pprint :as pp]))

(defn pprint
  "A simple wrapper around `clojure.pprint/write`.

  Its signature is compatible with the expectations of nREPL's wrap-print
  middleware."
  [value writer options]
  (apply pp/write value (mapcat identity (assoc options :stream writer))))
You can also pick a printer for a single evaluation, without changing cider-print-fn: the pretty-print menu (C-c C-v f) has a -p (--print-fn=) argument accepting pr, pprint, orchard, fipp, puget, zprint or the name of a custom var, honored by the pretty-printing commands invoked from the menu.

Limiting printed output

You can set cider-print-quota to limit the number of bytes that will be returned by any printing operation. This defaults to one megabyte, and can be set to nil if no limit is desired. Note well that if no quota is set some printing operations may never terminate — you can still use cider-interrupt to halt them.

Your configured printing function might also support limiting the length and depth of printed objects — either using clojure.core/*print-length* and clojure.core/*print-level* or in the provided options map.

You can pass an options map to the print function by setting cider-print-options. Here’s an example:

(setq cider-print-options '(("length" 50) ("right-margin" 70)))
Each print engine has its own configuration options, so you’ll have to be sure to set cider-print-options accordingly.

Here’s a table describing the differences in the names for the most common print options supported by every print engine.

clojure.core/pr clojure.pprint Fipp & Puget zprint

clojure.core/*print-length*

length

print-length

max-length

clojure.core/*print-level*

level

print-level

max-depth

clojure.pprint/*print-right-margin*

right-margin

width

width

Not all printing engines use (or default to) the dynamic variables in all cases, so setting them at the REPL may or may not have the intended effect. See the respective documentation of each engine:

Width of printed output

If you’re using one of the printing engines provided with CIDER, the value of fill-column will be used for the relevant width option in the options map. You can override this by hardcoding the relevant option in cider-print-options.