The zprint auto-formatter for Clojure comes with built-in defaults, but it is also highly customizable. The docs can be a bit daunting, so in what follows I will explain how to set some configuration options that are commonly used.
By default, zprint will move the arg vector of defn
forms to a separate line:
$ zprintm-0.4.12 <<< $'(defn discombobulate-widget [x]\n(foo foo foo foo foo)\n(bar bar bar bar bar bar bar))'
(defn discombobulate-widget
[x]
(foo foo foo foo foo)
(bar bar bar bar bar bar bar))
The default for defn
is :arg1-body
.
You can make zprint keep the first argument on the same line as the function
name (if it fits) by setting the "defn" key in :fn-map
to :arg2
:
$ zprintm-0.4.12 '{:fn-map {"defn" :arg2}}' <<< $'(defn discombobulate-widget [x]\n(foo foo foo foo foo)\n(bar bar bar bar bar bar bar))'
(defn discombobulate-widget [x]
(foo foo foo foo foo)
(bar bar bar bar bar bar bar))
In Hiccup, Reagent or Sablono, HTML elements are represented by a vector:
(defn nav-ui
[]
[:nav
[:a {:href "#/"} "Home"]
[:span " "]
[:a {:href "#/users"} "Users"]
[:span " "]
[:a {:href "#/users/1"} "User #1"]
[:span " "]
[:a {:href "#/users/999"} "Invalid user"]
[:span " "]
[:a {:href "#/clock"} "Clock"]])
With default settings, zprint will will reformat the vector as if it were pure data, trying to fill the page width with elements:
$ zprintm-0.4.12 <<< $'(defn nav-ui [x]\n [:nav\n [:a {:href "#/"} "Home"]])'
(defn nav-ui [x] [:nav [:a {:href "#/"} "Home"]])
To avoid this, you can instruct zprint to respect newlines in vectors starting with a keyword:
$ zprintm-0.4.12 '{:style :keyword-respect-nl}' <<< $'(defn nav-ui [x]\n [:nav\n [:a {:href "#/"} "Home"]])'
(defn nav-ui
[x]
[:nav
[:a {:href "#/"} "Home"]])
You can also apply this setting for only a single form.
By default, zprint assumes a line width of 80 characters. The top-level option
:width
allows you to customize this number. This can be useful for experimenting
with options. Often formatting becomes interesting as soon as a form doesn't fit
in a single line. For example, this is boring:
$ zprintm-0.4.12 '{}' <<< $'(defn square [n] (* n n))'
(defn square [n] (* n n))
But by setting an artificially short line width, we can cause zprint to introduce newlines:
$ zprintm-0.4.12 '{:width 15}' <<< $'(defn square [n] (* n n))'
(defn square
[n]
(* n n))
Zprint newline handling may seem confusing at first glance but makes sense once you understand it.
A source file is a sequence of top-level forms (such as defns) separated by newlines. In general, zprint's newline philosophy can be summarized like this. On the one hand, it doesn't touch the whitespace outside the top-level forms. Newlines and other whitespace inside the forms, on the other hand, is mostly ignored and reformatted using its layouting algorithm. That's a powerful property: you can write function definitions without any regard to style or indentation. You can be confident that zprint will clean up after you.
So re-organizing top-level newlines is not part of zprint's primary job. If you still want to
use it to normalize newlines, see the :parse
option contained in this answer.
By default, zprint separates k/v-pairs in maps with commas. But you can turn that behavior off:
Before:
$ zprintm-0.4.12 <<< $'{"a" "b" "c" "d"}'
{"a" "b", "c" "d"}
After:
$ zprintm-0.4.12 '{:map {:comma? false}}' <<< $'{"a" "b" "c" "d"}'
{"a" "b" "c" "d"}
This is great! The only thing I can see is that
defn
could be:arg2
to keep the arg vector on the same line (or try to). But:fn
is probably as good. I don't know if you want to mention thecommunity
style. I don't use it, obviously, but somebody must like it?