Skip to content

Commit

Permalink
Format spaces in export/public expressions, fixes #25
Browse files Browse the repository at this point in the history
  • Loading branch information
fredrikekre committed Jul 23, 2024
1 parent 3f9b692 commit d65bf57
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/Runic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ function format_node!(ctx::Context, node::Node)::Union{Node, Nothing, NullNode}
@return_something spaces_around_ternary(ctx, node)
@return_something spaces_around_keywords(ctx, node)
@return_something spaces_in_import_using(ctx, node)
@return_something spaces_in_export_public(ctx, node)
@return_something no_spaces_around_colon_etc(ctx, node)
@return_something parens_around_op_calls_in_colon(ctx, node)
@return_something for_loop_use_in(ctx, node)
Expand Down
86 changes: 82 additions & 4 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,84 @@ function no_spaces_around_x(ctx::Context, node::Node, is_x::F) where {F}
end
end

function spaces_in_export_public(ctx::Context, node::Node)
if !(kind(node) in KSet"export public" && !is_leaf(node))
return nothing
end
kids = verified_kids(node)
kids′ = kids
any_changes = false
pos = position(ctx.fmt_io)

spacenode = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), 1)

@assert is_leaf(kids[1]) && kind(kids[1]) in KSet"export public"
accept_node!(ctx, kids[1])

# space -> identifier -> comma
state = :expect_space
i = 2
while i <= length(kids)
kid = kids[i]
if state === :expect_space
if kind(kid) === K"NewlineWs" || (kind(kid) === K"Whitespace" && span(kid) == 1)
any_changes && push!(kids′, kid)
accept_node!(ctx, kid)
elseif kind(kid) === K"Whitespace"
kid′ = replace_first_leaf(kid, spacenode)
replace_bytes!(ctx, " ", span(first_leaf(kid)))
any_changes = true
if kids′ === kids
kids′ = kids[1:(i - 1)]
end
accept_node!(ctx, kid′)
push!(kids′, kid′)
else
# Insert a space
any_changes = true
if kids′ === kids
kids′ = kids[1:(i - 1)]
end
replace_bytes!(ctx, " ", 0)
push!(kids′, spacenode)
accept_node!(ctx, spacenode)
state = :expect_identifier
continue # Skip increment of i
end
state = :expect_identifier
elseif state === :expect_identifier
if kind(kid) === K"Identifier"
any_changes && push!(kids′, kid)
accept_node!(ctx, kid)
else
@assert false
end
state = :expect_comma
else
@assert state === :expect_comma
state = :expect_space
if kind(kid) === K","
any_changes && push!(kids′, kid)
accept_node!(ctx, kid)
elseif kind(kid) === K"Whitespace"
# Drop this node
any_changes = true
replace_bytes!(ctx, "", span(kid))
if kids′ === kids
kids′ = kids[1:(i - 1)]
end
state = :expect_comma
else
@assert false
end
end
i += 1
end
# Reset stream
seek(ctx.fmt_io, pos)
return any_changes ? make_node(node, kids′) : nothing
end

function spaces_in_import_using(ctx::Context, node::Node)
if !(kind(node) in KSet"import using" && !is_leaf(node))
return nothing
Expand Down Expand Up @@ -2304,8 +2382,8 @@ function continue_all_newlines(
end
end

function indent_using_import_export(ctx::Context, node::Node)
@assert kind(node) in KSet"using import export"
function indent_using_import_export_public(ctx::Context, node::Node)
@assert kind(node) in KSet"using import export public"
return continue_all_newlines(ctx, node)
end

Expand Down Expand Up @@ -2505,8 +2583,8 @@ function insert_delete_mark_newlines(ctx::Context, node::Node)
return indent_braces(ctx, node)
elseif kind(node) in KSet"|| &&"
return indent_short_circuit(ctx, node)
elseif kind(node) in KSet"using import export"
return indent_using_import_export(ctx, node)
elseif kind(node) in KSet"using import export public"
return indent_using_import_export_public(ctx, node)
elseif is_assignment(node)
return indent_assignment(ctx, node)
elseif kind(node) === K"parameters"
Expand Down
15 changes: 11 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -798,9 +798,16 @@ end
end
end

@testset "spaces in export/public" begin
for sp in ("", " ", " ", "\t"), verb in ("export", "public")
@test format_string("$(verb) $(sp)a") == "$(verb) a"
@test format_string("$(verb)\na") == "$(verb)\n a"
@test format_string("$(verb) $(sp)a$(sp),$(sp)b") == "$(verb) a, b"
@test format_string("$(verb) a$(sp),\nb") == "$(verb) a,\n b"
@test format_string("$(verb) \na$(sp),\nb") == "$(verb)\n a,\n b"
end
end

@testset "parsing new syntax" begin
# Check that it parses
@test format_string("public a,b") == "public a,b"
# But currently not actually getting formatted:
@test_broken format_string("public a,b") == "public a, b"
@test format_string("public a, b") == "public a, b" # Julia 1.11
end

0 comments on commit d65bf57

Please sign in to comment.