Skip to content

align-match-case ​

A match whose case bodies all collapse to a single expression reads naturally as a dispatch table, with patterns on the left and results on the right.

gathers consecutive single-expression cases into a shared column for the post-pattern : separator, so the pattern column flushes left and the body column flushes right, and the reader reads the table by scanning rows rather than tracing each case body.

The rule fires only on runs of single-expression cases at the same indentation. A multi-statement case body, a comment between cases, or a nested match breaks the run and leaves the surrounding cases aligned in isolation. Pair with

to skip padding on one-arm matches and with to align separators inside dict-returning case bodies.

Configuration ​

KeyTypeDefaultMeaning
enabledbooltrueToggles the rule on or off.
max-shiftpositive int | 0 | false16The width-spread budget a contiguous run may shift to reach the shared column. A positive N caps the spread, 0 forbids any shift so every row sits flush, and false lifts the cap so a contiguous run folds into one column. To hold one row out of an otherwise-aligned group, mark it with # prose: skip.

max-shift bounds how far the post-pattern : may shift to align. The rule walks each run of arms in source order and grows a column while its width spread stays within the cap, breaking a fresh column at the first arm that would exceed it. A max-shift of false lifts the cap so a contiguous run folds into one column, and 0 forbids any shift so every : sits flush. The per-rule facets reference covers the full semantics.

The Canonical Case ​

A match whose arms carry a variety of collapsible body kinds, from pass and break to raise and return, all aligning on the post-pattern : separator.

def dispatch(token):
    match token:
        case "noop" : pass
        case "skip" : continue
        case "stop" : break
        case "boom" : raise RuntimeError("boom")
        case "echo" : log(token)
        case _      : return None
python

More Examples ​

One arm's case pattern spans several lines, so its : lands on a different line from where the pattern opens. The multi-line pattern disqualifies the arm, leaving it untouched, while the lone single-line sibling collapses without padding.

Arms carry case A | B alternations of differing width. The widest third arm exceeds max-shift and breaks into its own sub-group, dropping out of the alignment with its : hugging the pattern while the narrower arms share one column.

Five multi-line arms test the 88-column collapse budget. Arms collapse only when the one-line form fits, so the under-88 and exactly-88 arms fold while the 89-column arm, the far-wider arm, and the arm whose if guard pushes it over all stay multi-line. The gate measures guard width alongside pattern width.

A standalone # comment line sits between two arms. The comment rides through unchanged while the arms on either side collapse and align their : to one shared column around it.

The first arm's body is a single assignment whose right-hand side spans several lines across a parenthesized +. The multi-line right-hand side disqualifies the arm even though it is structurally one statement, leaving it untouched. The remaining arm is alone in its sub-group and collapses without padding.

A two-statement arm sits second in a four-arm match. The multi-statement body disqualifies that arm and splits the match into sub-groups, so the lone arm before it collapses without padding and the two arms after it align together at the wider of their patterns. The two-statement arm itself stays multi-line.

An outer arm whose body is itself a match disqualifies and stays multi-line, while the lone sibling arm collapses without padding. The inner match is visited as its own group, collapsing and aligning its three single-statement arms on a separate : column.