How can I format a map over several lines with pprint?

clojure, pprint

Solution

You can set the `*print-right-margin*` binding:

Clojure=> (binding [*print-right-margin* 7] (pprint {:a 1 :b 2 :c 3}))
{:a 1,
 :b 2,
 :c 3}

Not exactly what you're looking for, but it might be enough?

BTW, the best way to figure this out —or at least the approach I took— is to use

Clojure=> (use 'clojure.contrib.repl-utils)
Clojure=> (source pprint)
(defn pprint 
  "Pretty print object to the optional output writer. If the writer is not provided, 
print the object to the currently bound value of *out*."
  ([object] (pprint object *out*)) 
  ([object writer]
     (with-pretty-writer writer
       (binding [*print-pretty* true]
         (write-out object))
       (if (not (= 0 (.getColumn #^PrettyWriter *out*)))
         (.write *out* (int \newline))))))
nil

Hmmrmmm.. what does `with-pretty-writer` do to `*out*`?

Clojure=> (source clojure.contrib.pprint/with-pretty-writer)
(defmacro #^{:private true} with-pretty-writer [base-writer & body]
  `(let [new-writer# (not (pretty-writer? ~base-writer))]
     (binding [*out* (if new-writer#
                      (make-pretty-writer ~base-writer *print-right-margin* *print-miser-width*)
                      ~base-writer)]
       ~@body
       (if new-writer# (.flush *out*)))))
nil

Okay, so `*print-right-margin*` sounds promising...

Clojure=> (source clojure.contrib.pprint/make-pretty-writer)
(defn- make-pretty-writer 
  "Wrap base-writer in a PrettyWriter with the specified right-margin and miser-width"
  [base-writer right-margin miser-width]
  (PrettyWriter. base-writer right-margin miser-width))
nil

Also, this is pretty informative:

Clojure=> (doc *print-right-margin*)
-------------------------
clojure.contrib.pprint/*print-right-margin*
nil
  Pretty printing will try to avoid anything going beyond this column.
Set it to nil to have pprint let the line be arbitrarily long. This will ignore all 
non-mandatory newlines.
nil

Anyway —and perhaps you already knew even this— if you really want to customize the way that `pprint` works, you can `proxy` `clojure.contrib.pprint.PrettyWriter` and pass that down by binding it to `*out*`. The PrettyWriter class is pretty large and intimidating, so I'm not sure if this was what you originally meant by your "brick wall" comment.

Problem

`pprint`'s docs are kind of a brick wall. If you pprint a map, it comes out on one line like so: `{:a "b", :b "c", :d "e"}`. Instead, I'd like to be pprinted like this, optionally with commas: ``` {:a "b" :b "c" :d "e"} ``` How would one do that with pprint?

Original source