zprint is a library and command line tool providing a variety of pretty printing capabilities for both Clojure code and Clojure/EDN structures. It can meet almost anyone's needs. As such, it supports a number of major source code formatting approaches.
zprint does far more than just properly indent code. Before:
(defn change-start-column [new-start-column style-vec [inline-comment-index
start-column spaces-before :as comment-vec]] (if (zero? inline-comment-index)
style-vec (let [delta-spaces (- new-start-column start-column) new-spaces
(+ spaces-before delta-spaces) previous-element-index (dec
inline-comment-index) [s c e :as previous-element] (nth style-vec
previous-element-index) new-previous-element (cond (= e :indent) [(str "\n"
(blanks new-spaces)) c e] (= e :whitespace) [(str (blanks new-spaces))
c e 26] :else nil)] (assoc style-vec previous-element-index
new-previous-element))))
After:
(defn change-start-column
[new-start-column style-vec
[inline-comment-index start-column spaces-before :as comment-vec]]
(if (zero? inline-comment-index)
style-vec
(let [delta-spaces (- new-start-column start-column)
new-spaces (+ spaces-before delta-spaces)
previous-element-index (dec inline-comment-index)
[s c e :as previous-element] (nth style-vec previous-element-index)
new-previous-element
(cond (= e :indent) [(str "\n" (blanks new-spaces)) c e]
(= e :whitespace) [(str (blanks new-spaces)) c e 26]
:else nil)]
(assoc style-vec previous-element-index new-previous-element))))
Important updates and fixes for all comment wrapping. Recommend that
you use 1.2.7
instead of 1.2.6
.
Comment wrapping has been considerably altered. When working
on the stability fixes for 1.2.5
, the largest remaining problem
was comment wrapping causing changes to the formatting in subsequent
runs. In addition, the comment wrapping has been very simplistic
since its inception, leaving wrapped comments looking pretty bad.
There is a new capability called {:comment {:smart-wrap? true}}
which will now word wrap comments cleanly. It will also repair
most of the problems that the simplistic wrapping produced in the
past. It is now the default, in no small part to repair the
problems of the past. If you are working to minimize changes
when running zprint, I would recommend running it once over your
code before you disable it, as will clean up most of the problems
that were added by zprint in the past. You can disable it with
{:comment {:smart-wrap? false}}
. You can also configure it to
minimize the amount of word wrapping it does, while still allowing
it to do much better than the previous default by using {:style :minimal-smart-wrap}
. You need to have {:comment {:smart-wrap? true}}
to use :minimal-smart-wrap
. Smart wrap works hard to
not wrap things like numbered or bulleted lists. If you have a
case where it wraps something that it shouldn't, please submit an
issue. It is likely that it can be fixed with a configuration
change. See the reference manual for more details on how to
configure smart wrap.
You can now specify some keys to come last in a map as well as
some keys to appear first in a sorted map. The {:map {:key-order [...]}}
configuration places all of the keys prior to the distinguished key
:|
at the front of the map, and all of the keys after the :|
key
at the end of the map.
Configurable Styles: As the number of styles that call :option-fn
to return guides or just to do complex things has grown, many of
these styles have also begun to accept a configuration map as
their first argument. This has worked well, but has in turn
required a new style in the :style-map
for every unique combination
of values in the configuration map for the option-fn (or has
required moderately complex configuration in the :fn-map
or
elsewhere). The processing for styles has been enhanced to
allow configuration of styles when they are used, instead of
pre-configuring them as additional styles. See the CHANGELOG
for some details, and the reference manual for many more.
If you were using zprint as a library, and you kept the configuration
you wanted to use with zprint in a file of your own, there was no safe
way to give that configuration to zprint if it contained function
definitions -- which it might need to for :option-fn
values. Now
you can pass a string value of an options map to set-options!
,
and it will read and 'compile' that options map (including any functions)
using the Small Clojure Interpreter (sci) built into zprint, the same
way that zprint handles reading external configuration files.
Made considerable improvements in multi-format-pass "stability". Thus, if
you format the same file multiple times, it is considerably less likely
to change the second time. The biggest issues were when using :repect-nl
,
though some affected every formatting approach. The only downside
is that the tuning for "hangs" had to change a bit -- so now more things
qualify to hang as opposed to flow. The change isn't dramatic, but if you
prefer the previous behavior it is still available (without the new
stability) by using: :style :original-tuning
.
Inline comments (i.e., end of line comments) when aligned in a group
flow left to end up one space beyond the widest code. Single inline comments
did not, yielding odd inconsistencies. Now single line inline comments
also flow left to end up one space beyond the code. You can turn all of
the alignment support for inline comments off by using
:comment {:inline-align-style :none}
if you don't like this approach.
In addition, zprint is very handy to use at the REPL.
Maybe one of the existing "styles" will meet your needs. All you have to
do is put {:style ...}
on the command line or as the third argument
to a zprint call. For example, {:style :community}
or
{:style :respect-bl}
.
Some commonly used styles:
quote
, deref
, var
, unquote
in structuresLeiningen (via Clojars)
zprint has been tested in each of the following environments:
planck
2.26.0 (Clojurescript 1.10.914)It requires tools.reader
at least 1.0.5, which all of the environments
above contain.
The last zprint release built with Clojure 1.8 was [zprint "0.4.15"].
In addition to the zprint dependency, you also need to include the following library when using Clojure 1.8:
[clojure-future-spec "1.9.0-alpha17"]
:style
quote
, deref
, var
, unquote
in structureslet
binding vectorscond
, assoc
pairsInformation on testing and development can be found here.
Note: Changed the default branch to main
.
A number of folks have contributed to zprint, not all of whom show up on GitHub because I have integrated the code or suggestions manually. Thanks for all of the great contributions!
rewrite-cljs
dependency to 0.4.5
@rundis/--url
and --url-only
: @coltnzUTF-8
locale to build the native image: @mynomoto:respect-bl
: @griffis:option-fn
and :fn-format
for enhanced vector formatting: @milankinenspec.cljc
: @Quezionns
macro: @pesterhazyThanks to everyone who has contributed fixes as well as everyone who has reported an issue. I really appreciate all of the help making zprint better for everybody!
At the core of zprint
is the rewrite-clj
library originally
created by Yannick Scherer, ported to Clojurescript by Magnus
Rundberget, and recently merged into a single, supported, documented,
and updated library by Lee Read. This is a great library! I would not have
attempted zprint
if rewrite-clj
didn't exist to build upon.
Additionally, allowing options maps containing functions to be read
from files safely is made possible by sci
, the Small Clojure Interpreter
by Michael Borkent (@borkdude). This is a very well designed and
implemented addition to Clojure that required almost no effort to integrate
into zprint.
Copyright © 2016-2023 Kim Kinnear
Distributed under the MIT License. See the file LICENSE for details.
Can you improve this documentation? These fine people already did:
Kim Kinnear, Brett Rowberry, Quest Yarbrough, vemv, Andrea Richiardi & Brian HurlowEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close