From e23a65022009ae1f7ebd4cdc9204095ebfac459f Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Tue, 3 Dec 2024 10:27:24 +0100 Subject: [PATCH] Fix multiple spaces after `let` This patch ensures that a single space is used also after `let` like other keywords. --- CHANGELOG.md | 20 ++++++++++++++++++-- src/runestone.jl | 39 +++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 2 ++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e50c0..faa955e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased changes ### Changed - Fix a bug that caused "single space after keyword" to not apply after the `function` - keyword in non-standard function definitions. ([#113]) + keyword in non-standard function definitions ([#113]). This bug is classified as a + [spec-bug] and the fix will result in diffs like the following: + ```diff + -function() + +function () + # ... + end + ``` + - Fix a bug that caused "single space after keyword" to not apply after `let` ([#117]). + This bug is classified as a [spec-bug] and the fix will result in diffs like the + following when `let` is followed by multiple spaces in the source: + ```diff + -let a = 1 + +let a = 1 + a + end + ``` - Fix a bug that caused multiline variable blocks in `let` to not indent correctly ([#97], [#116]). This bug is classified as a [spec-bug] and the fix will result in diffs like the - following: + following whenever multiline variable blocks exist in the source: ```diff let a = 1, - b = 2 diff --git a/src/runestone.jl b/src/runestone.jl index 5b492e1..8d0c95d 100644 --- a/src/runestone.jl +++ b/src/runestone.jl @@ -1107,6 +1107,42 @@ function no_spaces_around_colon_etc(ctx::Context, node::Node) return no_spaces_around_x(ctx, node, is_x) end +function space_after_let(ctx, node) + @assert kind(node) === K"let" && !is_leaf(node) + p = position(ctx.fmt_io) + kids = verified_kids(node) + let_node = kids[1] + @assert kind(let_node) === K"let" + accept_node!(ctx, let_node) + vars_idx = 2 + vars_node = kids[vars_idx] + @assert kind(vars_node) === K"block" + vars_kids = verified_kids(vars_node) + if length(vars_kids) == 0 + @assert span(vars_node) == 0 + seek(ctx.fmt_io, p) + # Empty block, but where are spaces and comments? + return nothing + end + # First node *must* be a space (?) + vars_kid = vars_kids[1] + @assert kind(vars_kid) === K"Whitespace" + if span(vars_kid) == 1 + seek(ctx.fmt_io, p) + return nothing + else + replace_bytes!(ctx, " ", span(vars_kid)) + ws = Node(JuliaSyntax.SyntaxHead(K"Whitespace", JuliaSyntax.TRIVIA_FLAG), 1) + vars_kids′ = copy(vars_kids) + vars_kids′[1] = ws + vars_node′ = make_node(vars_node, vars_kids′) + kids′ = copy(kids) + kids′[vars_idx] = vars_node′ + seek(ctx.fmt_io, p) + return make_node(node, kids′) + end +end + # Single space around keywords: # Both sides of: `where`, `do` (if followed by arguments) # Right hand side of: `mutable`, `struct`, `abstract`, `primitive`, `type`, `function` (if @@ -1114,6 +1150,9 @@ end # global, const function spaces_around_keywords(ctx::Context, node::Node) is_leaf(node) && return nothing + if kind(node) === K"let" + return space_after_let(ctx, node) + end keyword_set = KSet""" where do mutable struct abstract primitive type function if elseif catch while return local global const module baremodule diff --git a/test/runtests.jl b/test/runtests.jl index b491339..bee4b60 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -552,6 +552,8 @@ end @test format_string("function f()\n return$(sp)\nend") == "function f()\n return\nend" @test format_string("module$(sp)A\nend") == "module A\nend" @test format_string("module$(sp)(A)\nend") == "module (A)\nend" + @test format_string("let$(sp)x = 1\nend") == "let x = 1\nend" + @test format_string("let$(sp)\nend") == "let\nend" for word in ("local", "global"), rhs in ("a", "a, b", "a = 1", "a, b = 1, 2") word == "const" && rhs in ("a", "a, b") && continue @test format_string("$(word)$(sp)$(rhs)") == "$(word) $(rhs)"