Skip to main content

List Layout

Controls how items in a broken comma-separated list arrange on lines (listLayout) and whether siblings synchronize their internal breaking (consistentSiblings).

STACKED: one per line (default)

Each item's internal Groups decide flat/break based on their own width. A short coalesce(a, b) stays flat while a long one breaks.

select coalesce(a, b, c) as short_one, coalesce(very_long_column_name_here, another_extremely_long_column_name, yet_another_long_column) as long_one, coalesce(x, y, z) as another_short from t
select
coalesce(a, b, c) as short_one,
coalesce(
very_long_column_name_here, another_extremely_long_column_name,
yet_another_long_column
) as long_one,
coalesce(x, y, z) as another_short
from t

consistentSiblings: all siblings break if any breaks

When consistentSiblings is true, if any item breaks internally, all siblings' top-level Groups break too. Works with any listLayout.

select coalesce(a, b, c) as short_one, coalesce(very_long_column_name_here, another_extremely_long_column_name, yet_another_long_column) as long_one, coalesce(x, y, z) as another_short from t
select
coalesce(
a, b, c
) as short_one,
coalesce(
very_long_column_name_here, another_extremely_long_column_name,
yet_another_long_column
) as long_one,
coalesce(
x, y, z
) as another_short
from t

consistentSiblings does not cascade into nested constructs

Sibling consistency only forces each item's outermost Group. AND/OR inside CASE WHEN is not affected.

select case when a > 1 and b > 2 then 'yes' when c > 3 and d > 4 and e > 5 then 'no' else 'maybe' end from t
select
case
when a > 1 and b > 2 then 'yes'
when c > 3 and d > 4 and e > 5 then 'no'
else 'maybe'
end
from t

PACKED: items share lines by width

Short items pack onto the same line. When total width exceeds maxLineWidth, items wrap to the next line.

select alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, kappa from t
select
alpha, beta, gamma, delta, epsilon,
zeta, eta, theta, iota, kappa
from t

AUTO: packed for simple items, stacked for complex

When all items are simple (no aliases, no CASE/subquery), AUTO picks packed layout.

select alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, kappa from t
select
alpha, beta, gamma, delta, epsilon,
zeta, eta, theta, iota, kappa
from t

AUTO stacks when items have AS aliases

Items with AS aliases have Align nodes — AUTO picks stacked. Input must exceed maxLineWidth to force breaking.

select customer_id as cust, total_amount as total, order_date as dt, status_code as status, region_name as region from t
select
customer_id as cust,
total_amount as total,
order_date as dt,
status_code as status,
region_name as region
from t

AUTO stacks when items have structural complexity

A CASE expression causes AUTO to pick stacked for the entire list.

select first_column, case when status = 'active' then 'A' when status = 'inactive' then 'I' else 'X' end as status_code, second_column, third_column from t
select
first_column,
case
when status = 'active' then 'A'
when status = 'inactive' then 'I'
else 'X'
end as status_code,
second_column,
third_column
from t

AUTO packs GROUP BY columns

GROUP BY items are bare identifiers — no aliases, no complexity. Needs enough columns to force breaking.

select count(*) from t group by first_col, second_col, third_col, fourth_col, fifth_col, sixth_col
select count(*)
from t
group by
first_col, second_col, third_col,
fourth_col, fifth_col, sixth_col

Backwards compat: siblingLayout still works

Old siblingLayout: "pack" maps to listLayout: packed.

select alpha, beta, gamma, delta, epsilon, zeta, eta, theta, iota, kappa from t
select
alpha, beta, gamma, delta, epsilon,
zeta, eta, theta, iota, kappa
from t

Backwards compat: siblingLayout consistent

Old siblingLayout: "consistent" maps to consistentSiblings: true.

select coalesce(a, b, c) as short_one, coalesce(very_long_column_name_here, another_extremely_long_column_name, yet_another_long_column) as long_one, coalesce(x, y, z) as another_short from t
select
coalesce(
a, b, c
) as short_one,
coalesce(
very_long_column_name_here,
another_extremely_long_column_name,
yet_another_long_column
) as long_one,
coalesce(
x, y, z
) as another_short
from t

consistentSiblings is idempotent under aggregate expressions

When consistentSiblings=true with narrow width, the sibling propagation must be a fixed point — pass 1 and pass 2 must produce the same layout. Previously the check consulted triviaAnalysis.hasInnerNewline(), which read pass-1-emitted newlines back on pass 2 and produced a different layout on the second pass.

select customer_id, count(order_id) as order_count, sum(total_amount) as total from orders group by customer_id
select
customer_id,
count(order_id) as order_count,
sum(total_amount) as total
from orders
group by customer_id

consistentSiblings is idempotent under CASE expressions

Several CASE expressions in a SELECT list under narrow width must be a fixed point — the same layout must emerge from pass 1 and pass 2. (Note: consistentSiblings forces each item's outermost Group to break, but CASE renders via Doc.Clause which is not driven by siblingForceBreak; the short CASE therefore stays inline while the long CASE breaks. The important property is that both passes produce the same output.)

select case when a > 1 then 'x' else 'y' end, case when b > 2 then 'p' when c > 3 then 'q' else 'r' end from t
select
case when a > 1 then 'x' else 'y' end,
case
when b > 2 then 'p'
when c > 3 then 'q'
else 'r'
end
from t

consistentSiblings is idempotent under preserveBreaks=breaks_and_alignment

The critical regression case: under the preserveBreaks matrix that every FormatMarkdownTest scenario is re-run with, the sibling propagation must still be a fixed point. Bug 4 manifested only when the formatter re-ran the pass-1 output under this matrix mode — pass 1 broke one item organically via width pressure, pass 2 read the pass-1 newlines and propagated further, producing a different (more broken) layout.

select customer_id, count(order_id) as order_count, sum(total_amount) as total from orders group by customer_id
select
customer_id, count(order_id) as order_count, sum(
total_amount
) as total
from orders
group by customer_id