Browse Source

Fix multiple spaces after `let`

This patch ensures that a single space is used also after `let` like
other keywords.
pull/117/head
Fredrik Ekre 1 year ago
parent
commit
e23a650220
No known key found for this signature in database
GPG Key ID: DE82E6D5E364C0A2
  1. 20
      CHANGELOG.md
  2. 39
      src/runestone.jl
  3. 2
      test/runtests.jl

20
CHANGELOG.md

@ -8,10 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased changes ## Unreleased changes
### Changed ### Changed
- Fix a bug that caused "single space after keyword" to not apply after the `function` - 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], - 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 [#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 ```diff
let a = 1, let a = 1,
- b = 2 - b = 2

39
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) return no_spaces_around_x(ctx, node, is_x)
end 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: # Single space around keywords:
# Both sides of: `where`, `do` (if followed by arguments) # Both sides of: `where`, `do` (if followed by arguments)
# Right hand side of: `mutable`, `struct`, `abstract`, `primitive`, `type`, `function` (if # Right hand side of: `mutable`, `struct`, `abstract`, `primitive`, `type`, `function` (if
@ -1114,6 +1150,9 @@ end
# global, const # global, const
function spaces_around_keywords(ctx::Context, node::Node) function spaces_around_keywords(ctx::Context, node::Node)
is_leaf(node) && return nothing is_leaf(node) && return nothing
if kind(node) === K"let"
return space_after_let(ctx, node)
end
keyword_set = KSet""" keyword_set = KSet"""
where do mutable struct abstract primitive type function if elseif catch while return where do mutable struct abstract primitive type function if elseif catch while return
local global const module baremodule local global const module baremodule

2
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("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("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") for word in ("local", "global"), rhs in ("a", "a, b", "a = 1", "a, b = 1, 2")
word == "const" && rhs in ("a", "a, b") && continue word == "const" && rhs in ("a", "a, b") && continue
@test format_string("$(word)$(sp)$(rhs)") == "$(word) $(rhs)" @test format_string("$(word)$(sp)$(rhs)") == "$(word) $(rhs)"

Loading…
Cancel
Save