fix(formatter): align CL/Elisp indentation with Emacs conventions - #144
Merged
Conversation
- Add Elisp dialect routing (elisp_style_for_head) recognizing 14 operators (defvar, defconst, defcustom, save-excursion, while, condition-case, etc.) - Add 13 missing CL operators to string-match fallback (progv, multiple-value-call, return-from, throw, generic-flet, etc.) - Implement Emacs align-under-first-arg convention in format_general_list - Expand reindenter BODY_FORMS from 30 to 70 entries covering all cl-indent.el specs and Emacs Lisp lisp-mode.el put declarations
…fix_body - Add ListStyle::IfAligned for Common Lisp if with all branches at the same distinguished column (+2*indent), matching Emacs common-lisp-indent-function's (&rest nil) convention - Route CL if to IfAligned, keep Elisp if on ListStyle::If - Add distinguished_column to format_prefix_body: the child at position prefix_len breaks to +4 (distinguished) instead of body_column (+2) when it does not fit inline - Update test expectations for the new if layout
- Route defvar/defconstant/defparameter/defglobal/defstruct/define-condition to DefinitionNameBody (name on head line, rest at body-indent) - Route defpackage/in-package/provide/require/use-package/import to General - Remove unreachable 'defpackage' entry from string-match fallback (D-8) - Change loop continuation_column from head_end+1 to base+6 matching Emacs default lisp-loop-keyword-indentation - Update test expectations for define-condition and defvar Closes all 7 deferred divergence patterns (D-4, D-8 through D-13). All 41 divergence patterns now resolved (36 fixed, 5 not-applicable).
treefmt-pr-check caught unformatted output on these 3 files.
… sole argument format_general_list's new "align subsequent siblings under the first argument" step (this PR) decided whether that first argument fits on the head line by measuring only the argument's own text. When it is also the list's last child, the list's own closing delimiter lands on that same line immediately afterward and was never charged against the width budget — a compact form exactly one column over the budget could still be chosen, breaking the documented `<=` boundary (core-syntax's cjk_width_one_column_over_the_max_width_boundary_wraps). Reserve one column for the trailing delimiter when the first argument is also the last child, matching the already-passing cjk_width_fits_exactly_at_the_max_width_boundary case. This shifted the CL/Elisp alignment for `list`-shaped calls that break (subsequent siblings now align under the first argument's column instead of one column past the opening delimiter, per this PR's own stated goal), which is why the remove-unused-binding fixtures asserting that shape's *exact* rewritten text needed their expected strings updated to match — nextest's fail-fast in CI only surfaced one of these four; this run used --no-fail-fast to find the rest.
takeokunn
added a commit
that referenced
this pull request
Aug 8, 2026
Minor release: `paredit editor <file>` is a new interactive terminal editor command (#143); `paredit edit format`/`paredit fix` also align Common Lisp and Emacs Lisp indentation with Emacs/SLIME conventions across 36 divergence patterns (#144). No removed or renamed stable surface — the capabilities catalog diff against v1.5.0 is purely additive (the new `editor` command only).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Aligns
paredit edit formatoutput for Common Lisp and Emacs Lisp withEmacs/SLIME indentation conventions. 36 divergence patterns fixed across
operator table, layout algorithms, and reindenter.
Changes (13 files, 3 commits)
Wave 1: Operator table + reindenter + general_list alignment
elisp_style_for_head()) recognizing 14 operatorsformat_general_list()to align subsequent arguments under the firstwhen it shares the head's line (Emacs convention)
BODY_FORMSfrom 30 to 70 entriesWave 2: CL
ifalignment + distinguished columnListStyle::IfAligned— all branches at the same column (+2*indent),matching Emacs
common-lisp-indent-function's(&rest nil)forifdistinguished_columntoformat_prefix_body— the child atposition
prefix_lenbreaks to +4 when it doesn't fit inlineWave 3: Remaining 7 deferred patterns
defvar/defparameter/defconstant/defglobal/defstruct/define-conditionto
DefinitionNameBodydefpackage/in-package/provide/require/use-package/importtoGeneraldefpackageentry from string-match fallbackcontinuation_columnfromhead_end+1tobase+6Test Results