Skip to content

Commit

Permalink
Fix formatting of multiline triple strings with \-escaped newlines
Browse files Browse the repository at this point in the history
Closes #29.
  • Loading branch information
fredrikekre committed Aug 1, 2024
1 parent 21265f7 commit 3474907
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
44 changes: 38 additions & 6 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2792,18 +2792,50 @@ function indent_multiline_strings(ctx::Context, node::Node)
kid = kids[idx]
if state === :expect_something
if kind(kid) === itemkind
if indented && read_bytes(ctx, kid)[end] == UInt8('\n')
if indented && span(kid) > 0 && read_bytes(ctx, kid)[end] == UInt8('\n')
state = :expect_indent_ws
end
accept_node!(ctx, kid)
any_changes && push!(kids′, kid)
elseif kind(kid) === K"Whitespace"
# Delete this one
replace_bytes!(ctx, "", span(kid))
if kids′ === kids
kids′ = kids[1:(idx - 1)]
bytes = read_bytes(ctx, kid)
# Multiline strings with trailing \ will have non-space characters in the
# Whitespace node. These should be preserved.
# TODO: Maybe this should be continue-indent to highlight the continuation?
if length(bytes) == 2 + indent_span && bytes[1] === UInt8('\\') && bytes[2] === UInt8('\n')
@assert all(x -> x in (UInt8(' '), UInt8('\t')), @view(bytes[3:end]))
# This node is correct
accept_node!(ctx, kid)
any_changes && push!(kids′, kid)
elseif length(bytes) >= 2 && bytes[1] === UInt8('\\') && bytes[2] === UInt8('\n')
@assert all(x -> x in (UInt8(' '), UInt8('\t')), @view(bytes[3:end]))
if length(bytes) < 2 + indent_span
# Insert the missing spaces
while length(bytes) < 2 + indent_span
push!(bytes, UInt8(' '))
end
else
@assert length(bytes) > 2 + indent_span
# Truncate spaces
resize!(bytes, 2 + indent_span)
end
replace_bytes!(ctx, bytes, span(kid))
if kids′ === kids
kids′ = kids[1:(idx - 1)]
end
kid′ = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), length(bytes))
accept_node!(ctx, kid′)
push!(kids′, kid′)
any_changes = true
else
# Delete this node completely
@assert all(x -> x in (UInt8(' '), UInt8('\t')), bytes)
replace_bytes!(ctx, "", span(kid))
if kids′ === kids
kids′ = kids[1:(idx - 1)]
end
any_changes = true
end
any_changes = true
else
accept_node!(ctx, kid)
any_changes && push!(kids′, kid)
Expand Down
5 changes: 5 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -926,5 +926,10 @@ end
"begin\n $(otriple)a\n a\n b\n $(ctriple)\nend"
@test format_string("begin\n$(sp)$(otriple)\n$(sp)a\$(b)c\n$(sp)$(ctriple)\nend") ===
"begin\n $(otriple)\n a\$(b)c\n $(ctriple)\nend"
# Line continuation with `\`
@test format_string("$(otriple)\n$(sp)a\\\n$(sp)b\n$(sp)$(ctriple)") ===
"$(otriple)\na\\\nb\n$(ctriple)"
@test format_string("begin\n$(otriple)\n$(sp)a\\\n$(sp)b\n$(sp)$(ctriple)\nend") ===
"begin\n $(otriple)\n a\\\n b\n $(ctriple)\nend"
end
end

0 comments on commit 3474907

Please sign in to comment.