Skip to content

Commit

Permalink
Fix multiple spaces after let (#117)
Browse files Browse the repository at this point in the history
This patch ensures that a single space is used also after `let` like
other keywords.
  • Loading branch information
fredrikekre authored Dec 3, 2024
1 parent f9212e7 commit 38335d6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 2 deletions.
20 changes: 18 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 39 additions & 0 deletions src/runestone.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1107,13 +1107,52 @@ 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
# named function), `if`, `elseif`, `catch` and `return` (if followed by something), local,
# 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
Expand Down
2 changes: 2 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand Down

0 comments on commit 38335d6

Please sign in to comment.