diff --git a/src/runestone.jl b/src/runestone.jl index 47910ae..bfda2ff 100644 --- a/src/runestone.jl +++ b/src/runestone.jl @@ -337,6 +337,10 @@ function spaces_in_listlike(ctx::Context, node::Node) x -> !(JuliaSyntax.is_whitespace(x) || kind(x) === K","), @view(kids[(opening_leaf_idx + 1):(closing_leaf_idx - 1)]), ) + first_item_idx = findnext(x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), kids, opening_leaf_idx + 1) + if first_item_idx >= closing_leaf_idx + first_item_idx = nothing + end last_item_idx = findprev(x -> !(JuliaSyntax.is_whitespace(x) || kind(x) in KSet", ;"), kids, closing_leaf_idx - 1) if last_item_idx <= opening_leaf_idx last_item_idx = nothing @@ -354,7 +358,8 @@ function spaces_in_listlike(ctx::Context, node::Node) # - node is a single item tuple which is not from an anonymous fn (Julia-requirement) # - the closing token is not on the same line as the last item (Runic-requirement) require_trailing_comma = false - if kind(node) === K"tuple" && n_items == 1 && ctx.lineage_kinds[end] !== K"function" + if kind(node) === K"tuple" && n_items == 1 && ctx.lineage_kinds[end] !== K"function" && + kind(kids[first_item_idx::Int]) !== K"parameters" # TODO: May also have to check for K"where" and K"::" in the lineage above require_trailing_comma = true elseif kind(node) in KSet"bracescat block" diff --git a/test/runtests.jl b/test/runtests.jl index db56f7b..d6eeff9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -261,6 +261,16 @@ end @test format_string("f($(sp)a$(sp)...,$(sp))") == "f(a$(sp)...)" @test format_string("f($(sp)a$(sp)...;$(sp)b$(sp)...$(sp))") == "f(a$(sp)...; b$(sp)...)" end + # Named tuples + for sp in ("", " ", " "), a in ("a", "a = 1") + @test format_string("($(sp);$(sp)$(a)$(sp))") == + format_string("($(sp);$(sp)$(a)$(sp),$(sp))") == "(; $(a))" + for b in ("b", "b = 2") + @test format_string("($(sp);$(sp)$(a)$(sp),$(sp)$(b)$(sp))") == + format_string("($(sp);$(sp)$(a)$(sp),$(sp)$(b)$(sp),$(sp))") == + "(; $(a), $(b))" + end + end # Curly (not as extensive testing as tuple/call/dotcall above but the code path is the # same) for x in ("", "X"), sp in ("", " ", " "), a in ("A", "<:B", "C <: D"), b in ("E", "<:F", "G <: H")