Browse Source

No leading and a single trailing newline for files

pull/19/head
Fredrik Ekre 1 year ago
parent
commit
afa4252db2
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 12
      src/Runic.jl
  2. 63
      src/chisels.jl
  3. 1
      src/debug.jl
  4. 43
      src/runestone.jl
  5. 8
      test/runtests.jl

12
src/Runic.jl

@ -125,6 +125,7 @@ mutable struct Context @@ -125,6 +125,7 @@ mutable struct Context
debug::Bool
check::Bool
diff::Bool
filemode::Bool
# Global state
indent_level::Int # track (hard) indentation level
call_depth::Int # track call-depth level for debug printing
@ -138,7 +139,7 @@ end @@ -138,7 +139,7 @@ end
function Context(
src_str::String; assert::Bool = true, debug::Bool = false, verbose::Bool = debug,
diff::Bool = false, check::Bool = false, quiet::Bool = false,
diff::Bool = false, check::Bool = false, quiet::Bool = false, filemode::Bool = true,
)
src_io = IOBuffer(src_str)
src_tree = Node(
@ -165,7 +166,7 @@ function Context( @@ -165,7 +166,7 @@ function Context(
lineage_kinds = JuliaSyntax.Kind[]
return Context(
src_str, src_tree, src_io, fmt_io, fmt_tree, quiet, verbose, assert, debug, check,
diff, call_depth, indent_level, prev_sibling, next_sibling, lineage_kinds,
diff, filemode, call_depth, indent_level, prev_sibling, next_sibling, lineage_kinds,
)
end
@ -297,9 +298,10 @@ function format_node!(ctx::Context, node::Node)::Union{Node, Nothing, NullNode} @@ -297,9 +298,10 @@ function format_node!(ctx::Context, node::Node)::Union{Node, Nothing, NullNode}
# Go through the runestone and apply transformations.
ctx.call_depth += 1
@return_something no_leading_and_single_trailing_newline(ctx, node)
@return_something max_three_consecutive_newlines(ctx, node)
@return_something insert_delete_mark_newlines(ctx, node)
@return_something trim_trailing_whitespace(ctx, node)
@return_something max_three_consecutive_newlines(ctx, node)
@return_something format_hex_literals(ctx, node)
@return_something format_oct_literals(ctx, node)
@return_something format_float_literals(ctx, node)
@ -371,8 +373,8 @@ end @@ -371,8 +373,8 @@ end
Format string `str` and return the formatted string.
"""
function format_string(str::AbstractString)
ctx = Context(str)
function format_string(str::AbstractString; filemode::Bool = false)
ctx = Context(str; filemode = filemode)
format_tree!(ctx)
return String(take!(ctx.fmt_io))
end

63
src/chisels.jl

@ -187,30 +187,30 @@ function make_node(node::Node, kids′::Vector{Node}, tags = node.tags) @@ -187,30 +187,30 @@ function make_node(node::Node, kids′::Vector{Node}, tags = node.tags)
return Node(head(node), span′, kids′, tags)
end
function first_leaf(node::Node)
if is_leaf(node)
return node
else
return first_leaf(first(verified_kids(node)))
end
end
# TODO: Remove?
first_leaf(node::Node) = nth_leaf(node, 1)
function second_leaf(node::Node)
function nth_leaf(node::Node, nth::Int)
leaf, n_seen = nth_leaf(node, nth, 0)
return n_seen == nth ? leaf : nothing
end
function nth_leaf(node::Node, nth::Int, n_seen::Int)
if is_leaf(node)
return nothing
return node, n_seen + 1
else
kids = verified_kids(node)
if length(kids) == 0
return nothing
elseif !is_leaf(kids[1])
return second_leaf(kids[1])
elseif length(kids) > 1
@assert is_leaf(kids[1])
return first_leaf(kids[2])
else
@assert false
for kid in kids
leaf, n_seen = nth_leaf(kid, nth, n_seen)
if n_seen == nth
return leaf, n_seen
end
end
return nothing, n_seen
end
end
function second_leaf(node::Node)
return nth_leaf(node, 2)
end
# Return number of non-whitespace kids, basically the length the equivalent
@ -258,8 +258,33 @@ function last_leaf(node::Node) @@ -258,8 +258,33 @@ function last_leaf(node::Node)
if is_leaf(node)
return node
else
return last_leaf(last(verified_kids(node)))
kids = verified_kids(node)
if length(kids) == 0
return nothing
else
return last_leaf(last(kids))
end
end
end
function second_last_leaf(node::Node)
node, n = second_last_leaf(node, 0)
return n == 2 ? node : nothing
end
function second_last_leaf(node::Node, n_seen::Int)
if is_leaf(node)
return node, n_seen + 1
else
kids = verified_kids(node)
for i in reverse(1:length(kids))
kid, n_seen = second_last_leaf(kids[i], n_seen)
if n_seen == 2
return kid, n_seen
end
end
end
return nothing, n_seen
end
function has_newline_after_non_whitespace(node::Node)

1
src/debug.jl

@ -31,4 +31,3 @@ function macroexpand_assert(expr) @@ -31,4 +31,3 @@ function macroexpand_assert(expr)
msg = string(expr)
return :($(esc(expr)) || throw(AssertionError($msg)))
end

43
src/runestone.jl

@ -1316,8 +1316,49 @@ function parens_around_op_calls_in_colon(ctx::Context, node::Node) @@ -1316,8 +1316,49 @@ function parens_around_op_calls_in_colon(ctx::Context, node::Node)
end
end
# No newline at the beginning and single newline at the end of the file
function no_leading_and_single_trailing_newline(ctx::Context, node::Node)
if !(ctx.filemode && length(ctx.lineage_kinds) == 0)
return nothing
end
@assert kind(node) === K"toplevel"
@assert !is_leaf(node)
@assert position(ctx.fmt_io) == 0
changed = false
while (l = first_leaf(node); l !== nothing && kind(l) === K"NewlineWs" && length(verified_kids(node)) > 1)
changed = true
replace_bytes!(ctx, "", span(l))
node = replace_first_leaf(node, nullnode)
end
accept_node!(ctx, node)
l = last_leaf(node)
if l === nothing || kind(l) !== K"NewlineWs"
kids′ = copy(verified_kids(node))
push!(kids′, Node(JuliaSyntax.SyntaxHead(K"NewlineWs", JuliaSyntax.TRIVIA_FLAG), 1))
replace_bytes!(ctx, "\n", 0)
changed = true
node = make_node(node, kids′)
else
ll = second_last_leaf(node)
while ll !== nothing && kind(l) === kind(ll) === K"NewlineWs"
changed = true
seek(ctx.fmt_io, position(ctx.fmt_io) - span(l))
# replace_bytes!(ctx, "", span(l))
node = replace_last_leaf(node, nullnode)
@assert last_leaf(node) === ll
l = ll
ll = second_last_leaf(node)
end
end
if changed
return node
else
seek(ctx.fmt_io, 0)
return nothing
end
end
# Remove more than two newlines in a row
# Remove more than three newlines in a row
function max_three_consecutive_newlines(ctx::Context, node::Node)
is_leaf(node) && return nothing
kids = verified_kids(node)

8
test/runtests.jl

@ -749,3 +749,11 @@ end @@ -749,3 +749,11 @@ end
"function f()" * nl^2 * " x = 1" * nl^m * "end"
end
end
@testset "leading and trailing newlines in filemode" begin
for n in 0:5
nl = "\n"^n
@test format_string("$(nl)f()$(nl)"; filemode = true) == "f()\n"
@test format_string("$(nl)"; filemode = true) == "\n"
end
end

Loading…
Cancel
Save