kkinnear / zprint

Executables, uberjar, and library to beautifully format Clojure and Clojurescript source code and s-expressions.
MIT License
547 stars 46 forks source link

zprint

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.

cljdoc badge

Quickstart

Overview

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))))

Recent Additions!

See zprint:

In addition, zprint is very handy to use at the REPL.

Use zprint:

Get zprint:

Get something other than the default formatting:

Without learning how to configure zprint:

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:

Learn how to alter zprint's formatting behavior:

I want to change...

Usage

cljdoc badge

bb compatible

Clojure 1.9, 1.10, 1.10.3, 1.11.1, 1.12.0-alpha8:

Leiningen (via Clojars)

Clojars Project

Clojurescript:

zprint has been tested in each of the following environments:

It requires tools.reader at least 1.0.5, which all of the environments above contain.

Clojure 1.8:

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"]

The zprint Reference

Testing and Development

Information on testing and development can be found here.

Note: Changed the default branch to main.

Contributors

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!

Thanks 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!

Acknowledgements

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.

License

Copyright © 2016-2023 Kim Kinnear

Distributed under the MIT License. See the file LICENSE for details.