Skip to content

Indent block forms like cljfmt and clojure-mode - #170

Merged
bbatsov merged 3 commits into
mainfrom
block-body-like-cljfmt
Nov 1, 2026
Merged

bbatsov merged 3 commits into
mainfrom
block-body-like-cljfmt

Conversation

@bbatsov

@bbatsov bbatsov commented Nov 1, 2026

Copy link
Copy Markdown
Member

A form with a :block rule whose body starts on the first line is now indented like a call, and #_ forms count as its arguments, the way clojure-mode does it. cljfmt agrees except that it skips #_ when counting the position of the line itself, which looks accidental (it came with the #_ support in maps), so lines like the body of (do #_x follow clojure-mode. Also adds let* from cljfmt's defaults.

cljfmt indents a form with a :block rule as a body only when the first
form of the body starts its own line.  When it doesn't, the whole form
is indented like a function call, and clojure-mode does the same:

    (if (pos? x) :pos
        :neg)

The :block rules indented every form past the special arguments by 2
regardless, so the else branch above ended up under the `f' of `if'.
Check where the body starts, for (:block 0) too, which had its own
version of this check that didn't treat metadata on the first line as
the start of the body.
The :block rules skipped forms discarded with #_ when counting special
arguments, while the call argument rule aligns with them.  clojure-mode
counts them everywhere, and so does cljfmt when deciding where the body
starts and what to align with, so a #_ form on the first line made
these come out differently in clojure-ts-mode:

    (when #_debug ready?        (let [a 1] #_(prn a)
          (go))                      a)

Count them for the :block rules, like clojure-mode.  cljfmt doesn't
count them for the position of the line being indented, which looks
accidental (it came with the support for #_ between map keys and
values), so the body of (do #_x still indents as in clojure-mode.

The index of an :inner rule still counts values only, as in cljfmt,
which keeps the functions of (letfn #_[...] [...] indented as bodies.
cljfmt indents let* like let, as [[:block 1]], and so does clojure-mode,
through the rule for symbols that start with let.
@bbatsov
bbatsov force-pushed the block-body-like-cljfmt branch 2 times, most recently from ded7beb to d8c8cc0 Compare November 1, 2026 09:59
@bbatsov
bbatsov merged commit 577bab1 into main Nov 1, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant