Skip to main content

Preserve Breaks

Config key: preserveBreaks (enum: off, breaks_only, breaks_and_alignment).

Mental model

When preserveBreaks is on, any newline between comma-separated items forces the whole list vertical, and the specific mix of newlines/blank-lines between items is preserved exactly. No other user-layout signals are read.

The signal model is per-gap between consecutive items: SAME_LINE (no newline), NEW_LINE (single newline), or BLANK_LINE (double newline / section boundary). Each list resolves independently.

Gotchas

  • AND/OR expressions are exempt. x > 1 and\n y < 2 does NOT force the enclosing clause vertical. AND/OR layout is controlled by andOrPosition, not per-gap signals.
  • Line comments count as a newline signal. A trailing -- note between items implicitly carries a newline and will expand the list.
  • Block comments with internal newlines also count. /* line1\n line2 */ between items expands the list. /* inline note */ (no newline) does not.
  • Outer inline context does not override inner breaks. If you write breaks inside a subquery that would fit inline, those breaks are honored (D5 fix). This guarantees format(format(x)) == format(x) inside nested contexts.

Interaction

Preserve-breaks works together with preserve-breaks tiers: tiers control the clause-level layout (inline vs indented), while preserve-breaks controls whether the user's item-level layout decisions are preserved within each clause.

SELECT compact stays compact

select a, b, c from t
select a, b, c from t

SELECT vertical preserved

User wrote items on separate lines. preserveBreaks detects comma newlines and prevents inlining.

select a,
b,
c from t
select
a,
b,
c
from t

SELECT vertical with longer content

select customer_id,
customer_name,
customer_email,
customer_phone from customers where status = 'active'
select
customer_id,
customer_name,
customer_email,
customer_phone
from customers
where status = 'active'

SELECT vertical with leading commas

select a
, b
, c from t
select
a
, b
, c
from t

Each clause independent

SELECT compact (no comma newlines). WHERE body stays inline when it fits — AND/OR are keyword separators, not comma separators, so they don't trigger preserveBreaks.

select a, b from customers where status = 'active' and region = 'US' and created_at > '2024-01-01'
select a, b
from customers
where
status = 'active' and region = 'US' and created_at > '2024-01-01'

Subquery — inner user breaks are honored

When the user writes line breaks inside a subquery's SELECT list, preserveBreaks keeps them even if the subquery would fit inline. Outer Group flattening no longer silently erases inner user layout — this guarantees idempotency inside nested contexts.

select a from t where a in (select b,
c from t2)
select a
from t
where a in (
select
b,
c
from t2
)

GROUP BY compact stays compact

select count(*) from t group by a, b, c
select count(*) from t group by a, b, c

GROUP BY vertical preserved

select count(*) from t group by a,
b,
c
select count(*)
from t
group by
a,
b,
c

ORDER BY compact stays compact

select a from t order by a, b
select a from t order by a, b

ORDER BY vertical preserved

select a from t order by a,
b desc
select a
from t
order by
a,
b desc

CTE body respects user breaks independently of main query

When the user wrote breaks inside the CTE's SELECT list, they are preserved. The main query is independent — it stays compact because its own lists have no user breaks.

with cte as (select a,
b from t) select a, b from cte
with cte as (
select
a,
b
from t
)
select a, b
from cte

IN-list compact stays compact

select * from t where x in (1, 2, 3, 4, 5)
select * from t where x in (1, 2, 3, 4, 5)

IN-list with newlines — items break

User wrote values with newlines. preserveBreaks detects this through the paren group.

select * from t where x in (1, 2, 3, 4,
5, 6, 7, 8)
select *
from t
where
x in (
1, 2, 3, 4,
5, 6, 7, 8
)

INSERT SELECT — vertical SELECT preserved

The SELECT inside INSERT has newlines between items → preserveBreaks keeps vertical layout. Width forced narrow to prevent shortStatementsOneLine from collapsing.

insert into t select customer_id,
customer_name,
customer_email from customers
insert into
t
select
customer_id,
customer_name,
customer_email
from customers

UNION branches — consistent siblings

First branch has user breaks → expands. Under preserveBreaks, the second branch breaks consistently even though it would fit inline — set-op siblings render with the same shape to keep the layout readable and idempotent.

select customer_id,
customer_name from t1 union all select a, b from t2
(
select
customer_id,
customer_name
from t1
) union all (
select a, b
from t2
)

Alignment auto-detected

User manually padded spaces before AS to align. preserveBreaks detects the extra padding and auto-enables alignment — no alignTokens config needed.

select
customer_id as cust,
customer_name as name,
customer_email as email
from t
select
customer_id as cust,
customer_name as name,
customer_email as email
from t

Idempotency — compact stays compact

select a, b, c from t where x > 1
select a, b, c from t where x > 1

Idempotency — expanded stays expanded

Pre-formatted output with items on separate lines. Re-formatting produces identical output.

select
a,
b,
c
from t
where x > 1
select
a,
b,
c
from t
where x > 1