Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Base.@kwdef struct Options
yas_style_nesting::Bool = false
short_circuit_to_if::Bool = false
disallow_single_arg_nesting::Bool = false
preserve_single_line_if::Bool = false

function Options(args...)
opts = new(args...)
Expand Down
57 changes: 49 additions & 8 deletions src/styles/default/pretty.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1852,27 +1852,68 @@ function p_if(
return t
end

preserve_single_line =
s.opts.preserve_single_line_if &&
on_same_line(s, s.offset, s.offset + span(cst) - 1)

is_first = true

for c in children(cst)
if kind(c) in KSet"if elseif else"
if !haschildren(c)
add_node!(t, pretty(style, c, s, ctx, lineage), s; max_padding = 0)
if preserve_single_line && !is_first
add_node!(t, Whitespace(1), s)
end
add_node!(
t,
pretty(style, c, s, ctx, lineage),
s;
max_padding = if preserve_single_line
-1
else
0
end,
join_lines = preserve_single_line && !is_first,
)
else
len = length(t)
n = pretty(style, c, s, ctx, lineage)
add_node!(t, n, s)
if preserve_single_line && !is_first
add_node!(t, Whitespace(1), s)
end
add_node!(t, n, s; join_lines = preserve_single_line && !is_first)
t.len = max(len, length(n))
end
is_first = false
elseif kind(c) === K"end"
add_node!(t, pretty(style, c, s, ctx, lineage), s)
elseif kind(c) === K"block"
s.indent += s.opts.indent
if preserve_single_line
add_node!(t, Whitespace(1), s)
end
add_node!(
t,
pretty(style, c, s, newctx(ctx; ignore_single_line = true), lineage),
pretty(style, c, s, ctx, lineage),
s;
max_padding = s.opts.indent,
join_lines = preserve_single_line,
)
s.indent -= s.opts.indent
elseif kind(c) === K"block"
if preserve_single_line
add_node!(t, Whitespace(1), s)
add_node!(
t,
pretty(style, c, s, ctx, lineage),
s;
join_lines = true,
)
else
s.indent += s.opts.indent
add_node!(
t,
pretty(style, c, s, newctx(ctx; ignore_single_line = true), lineage),
s;
max_padding = s.opts.indent,
)
s.indent -= s.opts.indent
end
elseif !JuliaSyntax.is_whitespace(c)
add_node!(t, Whitespace(1), s)
add_node!(t, pretty(style, c, s, ctx, lineage), s; join_lines = true)

@penelopeysm penelopeysm May 28, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If you agree with (2), then I believe this is the appropriate fix:)

Suggested change
add_node!(t, pretty(style, c, s, ctx, lineage), s; join_lines = true)
ctx2 = preserve_single_line_if ? newctx(ctx; nonest=true) : ctx
add_node!(t, pretty(style, c, s, ctx2, lineage), s; join_lines = true)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(1) looks trickier to accomplish to me. I haven't attempted to figure out how that would be done.

Expand Down
71 changes: 71 additions & 0 deletions test/options.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2644,4 +2644,75 @@
"""
@test fmt(s1, 2, 1; disallow_single_arg_nesting = true) == s2
end

@testset "preserve single line if" begin
# Basic single-line if is preserved
str = "if x > 0 return 1 end"
@test fmt(str; preserve_single_line_if = true) == str

# Single-line if is expanded when option is false (default)
str_ = "if x > 0 return 1 end"
str = """
if x > 0
return 1
end"""
@test fmt(str_; preserve_single_line_if = false) == str
@test fmt(str_) == str

# Multi-line if is not affected by the option
str = """
if x > 0
return 1
end
"""
@test fmt(str; preserve_single_line_if = true) == str

# Single-line if-else
str = "if x > 0 1 else 2 end"
@test fmt(str; preserve_single_line_if = true) == str

# Single-line if-elseif-else
str = "if x > 0 1 elseif x < 0 2 else 0 end"
@test fmt(str; preserve_single_line_if = true) == str

# Multi-line if-else is not affected
str = """
if x > 0
return 1
else
return 2
end
"""
@test fmt(str; preserve_single_line_if = true) == str

# Nested single-line if
str = "if x > 0 if y > 0 return 1 end end"
@test fmt(str; preserve_single_line_if = true) == str

# Inside a function
str = """
function f()
if rand() < 0.5 return 2 end
0
end
"""
@test fmt(str; preserve_single_line_if = true) == str

# Inside a function, expanded when option is false
str_ = """
function f()
if rand() < 0.5 return 2 end
0
end
"""
str = """
function f()
if rand() < 0.5
return 2
end
0
end
"""
@test fmt(str_; preserve_single_line_if = false) == str
end
end
Loading