= Pretty-printing

== Configuring a printing function

NOTE: Pretty-printing was overhauled in CIDER 0.21 to leverage new features introduced in nREPL 0.6.
Refer to https://nrepl.org/nrepl/usage/misc.html#_pretty_printing[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 built-in `clojure.pprint/pprint` (this is the default).
* `fipp` to use the https://github.com/brandonbloom/fipp[Fast Idiomatic
Pretty-Printer]. This is approximately
5-10x faster than `clojure.core/pprint`.
* `puget` to use https://github.com/greglook/puget[Puget], which provides
https://github.com/greglook/puget#canonical-representation[canonical serialization]
of data on top of fipp, but at a slight performance cost.
* `zprint` to use https://github.com/kkinnear/zprint[zprint], a fast and
flexible alternative to the libraries mentioned above.

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, and a (possibly nil) map of options.

[source,lisp]
----
(setq cider-print-fn "user/my-pprint")
----

Here's one example:

[source,clojure]
----
(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))))
----

IMPORTANT: Before Clojure 1.10.2, a
https://clojure.atlassian.net/browse/CLJ-1445[bug] in `clojure.pprint` caused it
to not work properly with `+*print-meta*+`. If you need to print the metadata
you'll have to change the print function or disable pretty-printing.

== 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 <<print-options,options map>>.

== Print options

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

[source,lisp]
----
(setq cider-print-options '(("length" 50) ("right-margin" 70)))
----

NOTE: 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:

* `clojure.core/pr`: https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/+*print-dup*+
* `clojure.pprint`: https://clojuredocs.org/clojure.pprint/write
* Fipp: https://github.com/brandonbloom/fipp/#printer-usage
* Puget: https://github.com/greglook/puget#usage
* zprint: https://github.com/kkinnear/zprint/#what-is-configurable

== 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 <<print-options,options
map>>. You can override this by hardcoding the relevant option in
`cider-print-options`.
