From 5d0295ea459e534f264b3273e241ca6187054893 Mon Sep 17 00:00:00 2001 From: Alex Gunnarson Date: Fri, 8 Aug 2025 13:37:19 -0600 Subject: [PATCH 1/4] Add support for `preserve_single_line_if = x::Bool` --- src/styles/default/pretty.jl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/styles/default/pretty.jl b/src/styles/default/pretty.jl index 3a3fda3ab..2c0b52a87 100644 --- a/src/styles/default/pretty.jl +++ b/src/styles/default/pretty.jl @@ -1622,9 +1622,14 @@ function p_if( add_node!(t, pretty(style, c, s, ctx, lineage), s) elseif kind(c) === K"block" s.indent += s.opts.indent + block_ctx = if s.opts.preserve_single_line_if + ctx + else + newctx(ctx; ignore_single_line = true) + end add_node!( t, - pretty(style, c, s, newctx(ctx; ignore_single_line = true), lineage), + pretty(style, c, s, block_ctx, lineage), s; max_padding = s.opts.indent, ) From 516c505cb05b9042bdb83db557c8b31cd5a7fb1c Mon Sep 17 00:00:00 2001 From: Alex Gunnarson Date: Fri, 8 Aug 2025 13:42:43 -0600 Subject: [PATCH 2/4] Update options.jl --- src/options.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/options.jl b/src/options.jl index 69beb4334..c44c63e71 100644 --- a/src/options.jl +++ b/src/options.jl @@ -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 = true function Options(args...) opts = new(args...) From d9839dfb7cbe150f499c7e1203326786e09494d0 Mon Sep 17 00:00:00 2001 From: Alex Gunnarson Date: Thu, 14 Aug 2025 13:47:23 -0600 Subject: [PATCH 3/4] Keep default --- src/options.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/options.jl b/src/options.jl index c44c63e71..de0362338 100644 --- a/src/options.jl +++ b/src/options.jl @@ -36,7 +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 = true + preserve_single_line_if::Bool = false function Options(args...) opts = new(args...) From cae12ce6e02a077163e02de23b85f957b0b9ee1f Mon Sep 17 00:00:00 2001 From: Alex Gunnarson Date: Thu, 28 May 2026 02:55:27 +0000 Subject: [PATCH 4/4] Fix preserve_single_line_if and add tests - Fix the preserve_single_line_if option which was broken after merging with master. The previous approach only controlled ignore_single_line on the block context, but didn't handle the add_node! calls that force newlines via max_padding. - Now properly checks if the entire if statement is on a single line using on_same_line(), and when preserve_single_line=true: - Adds block content with join_lines=true instead of max_padding - Adds else/elseif/end keywords with join_lines=true - Inserts explicit Whitespace(1) between elements - Skips indent adjustments (not needed for single-line) - Add comprehensive test cases covering: - Basic single-line if - Default behavior (expand single-line if) - Multi-line if unaffected by the option - Single-line if-else - Single-line if-elseif-else - Multi-line if-else unaffected - Nested single-line if - Single-line if inside a function - Expansion when option is false --- src/styles/default/pretty.jl | 60 ++++++++++++++++++++++++------ test/options.jl | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 12 deletions(-) diff --git a/src/styles/default/pretty.jl b/src/styles/default/pretty.jl index 3e9aa1610..dcdd1997c 100644 --- a/src/styles/default/pretty.jl +++ b/src/styles/default/pretty.jl @@ -1852,32 +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 - block_ctx = if s.opts.preserve_single_line_if - ctx - else - newctx(ctx; ignore_single_line = true) + if preserve_single_line + add_node!(t, Whitespace(1), s) end add_node!( t, - pretty(style, c, s, block_ctx, 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) diff --git a/test/options.jl b/test/options.jl index 6aad8c00f..3826dc97d 100644 --- a/test/options.jl +++ b/test/options.jl @@ -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