Config-driven Clojure source formatter used by clj/edit for format-on-write
and by the format_code language-surface verb.
TWO backends live here, and the choice is TRANSPARENT to the language surface — callers just format; this namespace picks the formatter from the config files present around the target path:
.zprint.edn/.zprintrc is found walking UP from the
path. The project's zprint options map is applied. This is the
canonical, reflowing formatter — for this repo it is THE
formatter, applied through the repo's own .zprint.edn..cljfmt.edn/.cljfmt.clj is found (no zprint), or
when neither config exists (cljfmt defaults). Conservative:
normalizes indentation + whitespace of MULTI-LINE forms but does
NOT reflow a one-liner into multiple lines.When BOTH configs are present, zprint WINS. Backends and their config loaders are resolved on first use, not while registering the language pack at gateway startup. Registering formatting handlers does not need either implementation.
Failure mode: if a backend refuses (parse error, unfamiliar reader macro, anything that throws), the formatter returns the original source unchanged. We never silently corrupt a file because the formatter choked.
Config-driven Clojure source formatter used by `clj/edit` for format-on-write
and by the `format_code` language-surface verb.
TWO backends live here, and the choice is TRANSPARENT to the language
surface — callers just format; this namespace picks the formatter from the
config files present around the target path:
* zprint — when a `.zprint.edn`/`.zprintrc` is found walking UP from the
path. The project's zprint options map is applied. This is the
canonical, reflowing formatter — for this repo it is THE
formatter, applied through the repo's own `.zprint.edn`.
* cljfmt — when only a `.cljfmt.edn`/`.cljfmt.clj` is found (no zprint), or
when neither config exists (cljfmt defaults). Conservative:
normalizes indentation + whitespace of MULTI-LINE forms but does
NOT reflow a one-liner into multiple lines.
When BOTH configs are present, zprint WINS. Backends and their config loaders
are resolved on first use, not while registering the language pack at gateway
startup. Registering formatting handlers does not need either implementation.
Failure mode: if a backend refuses (parse error, unfamiliar reader macro,
anything that throws), the formatter returns the original source unchanged.
We never silently corrupt a file because the formatter choked.(clear-result-cache!)Forget every cached formatting. Only needed when something outside (source, config-file+mtime) changes the answer — i.e. in tests.
Forget every cached formatting. Only needed when something outside (source, config-file+mtime) changes the answer — i.e. in tests.
(cljfmt-opts-for path)cljfmt options from the nearest .cljfmt.edn/.cljfmt.clj walking UP from
path (a file OR directory path), so project-local indent rules (e.g. the
lazytest it/defdescribe [[:inner 0]] overrides) are honored instead of
cljfmt defaults. Returns nil when no config is found or it can't be read —
callers then fall back to plain defaults. Cached per config-file + mtime.
cljfmt options from the nearest `.cljfmt.edn`/`.cljfmt.clj` walking UP from `path` (a file OR directory path), so project-local indent rules (e.g. the lazytest `it`/`defdescribe` `[[:inner 0]]` overrides) are honored instead of cljfmt defaults. Returns nil when no config is found or it can't be read — callers then fall back to plain defaults. Cached per config-file + mtime.
(format-source source)(format-source source path)Format Clojure source, choosing the backend from the config files present
around path: zprint when a .zprint.edn/.zprintrc is found (its options
applied), otherwise cljfmt (with the nearest .cljfmt.edn opts, or cljfmt
defaults when neither config exists). zprint WINS when both configs are
present. TRANSPARENT to callers — they just format; the magic of which
formatter to run lives here. Either backend is followed by
normalize-top-level-spacing, so a formatted file always carries exactly one
blank line between top-level forms. Returns source unchanged on any failure.
Memoized through result-cache on (backend, config file + mtime, source),
so re-formatting content this JVM has already formatted is a hash, not a
layout search. A computed result is ALSO seeded under its own key: a
formatter is idempotent, so the output is its own fixed point, and the very
common format → write → format again sequence (every re-run of an
edit/format/lint block) then hits instead of paying a second layout search on
content only just produced.
Format Clojure `source`, choosing the backend from the config files present around `path`: zprint when a `.zprint.edn`/`.zprintrc` is found (its options applied), otherwise cljfmt (with the nearest `.cljfmt.edn` opts, or cljfmt defaults when neither config exists). zprint WINS when both configs are present. TRANSPARENT to callers — they just format; the magic of which formatter to run lives here. Either backend is followed by `normalize-top-level-spacing`, so a formatted file always carries exactly one blank line between top-level forms. Returns `source` unchanged on any failure. Memoized through `result-cache` on (backend, config file + mtime, source), so re-formatting content this JVM has already formatted is a hash, not a layout search. A computed result is ALSO seeded under its own key: a formatter is idempotent, so the output is its own fixed point, and the very common `format → write → format again` sequence (every re-run of an edit/format/lint block) then hits instead of paying a second layout search on content only just produced.
(format-string source)(format-string source opts)Return source with cljfmt indentation/whitespace normalization, or
source itself on any failure. opts, when supplied, is a cljfmt
options map merged over cljfmt's defaults.
Return `source` with cljfmt indentation/whitespace normalization, or `source` itself on any failure. `opts`, when supplied, is a cljfmt options map merged over cljfmt's defaults.
(formatter-for path)Which backend format-source picks for path: :zprint when a
.zprint.edn/.zprintrc is found walking UP, otherwise :cljfmt. Callers
surface this so a format result NAMES the provider that actually ran — the
dispatch in format-source is otherwise invisible.
Which backend `format-source` picks for `path`: `:zprint` when a `.zprint.edn`/`.zprintrc` is found walking UP, otherwise `:cljfmt`. Callers surface this so a format result NAMES the provider that actually ran — the dispatch in `format-source` is otherwise invisible.
(normalize-top-level-spacing source)source with exactly ONE blank line between top-level forms. A comment
directly above a form stays attached to it, runs of blank lines collapse to
one, neighbours sharing a line are left alone, and the file starts on its
first form and ends with exactly one newline. Whitespace INSIDE a form is
never touched; returns source unchanged when it does not parse.
`source` with exactly ONE blank line between top-level forms. A comment directly above a form stays attached to it, runs of blank lines collapse to one, neighbours sharing a line are left alone, and the file starts on its first form and ends with exactly one newline. Whitespace INSIDE a form is never touched; returns `source` unchanged when it does not parse.
(zprint-config-file path)The nearest zprint config file (.zprint.edn/.zprintrc) walking UP from
path (a file OR directory path), or nil when none is found. This is the
presence check that decides whether the zprint backend is used at all.
The nearest zprint config file (`.zprint.edn`/`.zprintrc`) walking UP from `path` (a file OR directory path), or nil when none is found. This is the presence check that decides whether the zprint backend is used at all.
(zprint-opts-for path)The zprint options map from the nearest .zprint.edn/.zprintrc walking UP
from path, or nil when none is found or it can't be read (zprint then uses
its built-in defaults). Read through zprint's OWN loader
(zprint.config/get-config-from-file) so :option-fn/:guided forms in the
config are sci-compiled into real functions — a plain edn/read-string would
leave them as bare lists that zprint rejects. Cached per config-file + mtime.
The zprint options map from the nearest `.zprint.edn`/`.zprintrc` walking UP from `path`, or nil when none is found or it can't be read (zprint then uses its built-in defaults). Read through zprint's OWN loader (`zprint.config/get-config-from-file`) so `:option-fn`/`:guided` forms in the config are sci-compiled into real functions — a plain `edn/read-string` would leave them as bare lists that zprint rejects. Cached per config-file + mtime.
(zprint-string source)(zprint-string source opts)Return source reformatted by zprint using opts (the project's zprint
options map, or nil for zprint defaults), or source itself on any
failure.
Return `source` reformatted by zprint using `opts` (the project's zprint options map, or nil for zprint defaults), or `source` itself on any failure.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |