Skip to content

Adopt modern indent spec format from clojure-ts-mode#702

Merged
bbatsov merged 5 commits intomasterfrom
new-indent-spec-format
Mar 24, 2026
Merged

Adopt modern indent spec format from clojure-ts-mode#702
bbatsov merged 5 commits intomasterfrom
new-indent-spec-format

Conversation

@bbatsov
Copy link
Copy Markdown
Member

@bbatsov bbatsov commented Mar 24, 2026

Adopt the explicit tuple-based indent spec format from clojure-ts-mode, while retaining full backward compatibility with the legacy format. The legacy format will be removed in clojure-mode 6.

The modern format uses named rules instead of positional lists:

  • ((:block N)) — N special args, then body (replaces integer N)
  • ((:inner 0)) — body-style indentation (replaces :defn)
  • ((:inner D I)) — body-style at depth D, position I
  • Multiple rules can be combined: ((:block 1) (:inner 2 0))

The backtracking indent engine is unchanged — conversion functions bridge the two formats transparently. CIDER integration is unaffected since clojure-get-indent-function accepts both formats and converts automatically.

Fixes nothing specific — this is groundwork for format unification across clojure-mode and clojure-ts-mode.

bbatsov added 5 commits March 24, 2026 11:15
Introduce the modern tuple-based indent spec format shared with
clojure-ts-mode, alongside conversion functions between modern and
legacy formats.

Modern format uses explicit rule tuples:
- ((:block N)) — N special args, then body
- ((:inner D)) — body-style at nesting depth D
- ((:inner D I)) — body-style at depth D, only at position I

The legacy positional format will be removed in clojure-mode 6.

New functions:
- clojure--modern-indent-spec-p: detect modern format
- clojure--indent-spec-to-modern: legacy → modern conversion
- clojure--indent-spec-to-legacy: modern → legacy conversion
- clojure--unwrap-legacy-spec: helper for nested spec unwrapping
put-clojure-indent now:
- Accepts both modern and legacy indent spec formats
- Stores the modern format canonically on 'clojure-indent-spec
- Stores the legacy format on 'clojure-indent-function for the
  backtracking engine

Validation functions updated to accept modern tuple rules
((:block N), (:inner D), (:inner D I)) for safe-local-eval.

clojure--get-indent-method converts modern-format specs from
clojure-get-indent-function to legacy format before returning
them to the backtracking engine.
Rewrite all define-clojure-indent specs using the modern tuple
format. The put-clojure-indent function automatically converts to
legacy format for the backtracking engine, so indentation behavior
is unchanged.

Notable conversion details:
- reify: (:defn (1)) → ((:inner 0) (:inner 1)), legacy becomes
  (:defn (:defn)) which produces identical indentation
- deftype/defrecord: (2 nil nil (:defn)) → ((:block 2) (:inner 1)),
  legacy becomes (2 (:defn)) — equivalent since the backtracking
  engine uses the last element for overflow positions
Update README to present the modern tuple format as primary, with
legacy format noted for backward compatibility (to be removed in
clojure-mode 6). Rewrite backtracking section examples using
modern format.

Update clojure-get-indent-function docstring to note that both
formats are accepted and converted automatically.
Returns the modern-format indent spec for a symbol. If only a
legacy-format spec exists, it is converted automatically. This
provides a clean API for tools that want to inspect indent specs
in the modern format.
@bbatsov bbatsov merged commit d6a9568 into master Mar 24, 2026
6 of 7 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