Some tooling considers a trailing newline to start a new (empty) line as
opposed to just ending the previous line. This patch relaxes the input
check of line ranges to allow this.
Fix formatting of floating point literals that use `−` (Unicode U+2212)
instead of the typically used `-` (ASCII/Unicode U+002D). The parser
treats them as synonyms but the former triggered an assertion error in
Runic while formatting. After this change Runic will normalize to `-`
when formatting. Fixes#137.
This patch implements the `--lines=a:b` command line argument for
limiting the formatting to the line range `a:b`. Multiple ranges are
supported. Closes#114.
This patch removes an assertion about whitespace after the `function`
keyword in the indent pass. The core issue is the
`is_longform_anon_function` predicate which is wrong for the testcases,
but the assert is not needed since we can just use the next
non-whitespace noce as the signature in all cases. Fixes#109.
Running testsuite *without* asserts takes roughly 150% or the time to
run it *with* asserts, probably because the compiler is helped by some
of the checks. The toggling is unused anyway, so delete it.
This patch changes the parsed syntax tree normalization with the goal of
simplifying the formatting code. JuliaSyntax is not very consistent with
where whitespace ends up which make formatting tricky since you always
have to "peek" into the next node (sometimes multiple levels) to check
if the next leaf is e.g. whitespace. This patch reworks the
normalization to "bubble up" whitespace so that all nodes start and end
with a non-whitespace node.
For example, given `a + b * c`, the output from JuliaSyntax is:
```
[call]
Identifier
Whitespace
+
[call]
Whitespace
Identifier
Whitespace
*
Whitespace
Identifier
```
and now after normalization the leading whitespace of the `*`-call is
bubbled up:
```
[call]
Identifier
Whitespace
+
Whitespace
[call]
Identifier
Whitespace
*
Whitespace
Identifier
```
As seen from the diff, this make it possible to remove a lot of
complicated code that were necessary to handle the random whitespace
placement. In particular, there is no need to peek into the nodes to
check for whitespace.
As a bonus, this fixes two issues:
- `global\n\n x = 1` would previously not indent correctly because we
had to double-peek (first into the `=` node, then into the LHS node).
- `runic: (off|on) toggling within array literals. Previously the
toggle comments would end up inside the `row` nodes so in the tree
they weren't on the same "level" which is required for the toggling.
Behavior of `..` is more tricky than `:`. Sometimes the space is
required like in e.g. `a .. -b` which, formatted as `a..-b`, would give
`ParseError: invalid operator ..-`.
This reverts commit 7d26dcf268.
This patch relaxes the toggle comments `# runic: (off|on)` such that the
comment may contain more than just the toggle comment. This is useful
when combining with other "pragmas" such as e.g. Literate.jl line
filters. For example, the following now also toggles formatting:
```julia
\# runic: off #src
not = formatted #src
\# runic: on #src
```
This patch make sure that function and macro definitions, as well as
do-blocks, end with an explicit `return` statement before the last
expression in the body. The following exceptions are made:
- If the last expression is a `for` or `while` loop (which both always
evaluate to `nothing`) `return` is added *after* the loop.
- If the last expression is a `if` or `try` block the `return` is only
added in case there is no `return` inside any of the branches.
- If the last expression is a `let` or `begin` block the `return` is
only added in case there is no `return` inside the block.
- If the last expression is a macro call the `return` is only added in
case there is no `return` inside the macro.
- If the last expression is a function call, and the function name is
`throw`, `rethrow`, or `error`, no `return` is added. This is because
it is pretty obvious that these calls terminate the function without
the explicit `return`.
Since adding `return` changes the expression that a macro will see, this
rule is disabled for function definitions inside of macros with the
exception of some known ones from Base (e.g. `@inline`, `@generated`,
...).
Closes#43.
This patch changes where spaces are inserted before comments so that it
is always added as a sibling to the comment instead of as a "uncle" when
a comment is found as the first leaf of a kid.
This patch fixes the usage of trailing commas in implicit tuples when
used in destructuring assignment, e.g. `x, = z`. In this context the
trailing comma is needed to preserve the tuple node, which is different
from e.g. implicit tuples in `do`-blocks. A trailing comma is allowed
(e.g. preserved from the source) for multi-item implicit tuples so that
e.g. `x, y, = z` can be used to signal that z contains more than two
items. Closes#58.
This patch adds trimming of trailing whitespace inside of comments in
addition to the trimming of trailing whitespace in code. Note that
trailing whitespace inside of multiline is not trimmed since doing so
would change the content of the string.
Closes#50.
This patch removes trailing semicolons in blocklike contexts (`for`,
`if`, ...). Semicolons are left alone in top level contexts since they
are sometimes used there for output suppression (e.g. Documenter
examples or scripts that are copy-pasted/included in the REPL).
Semicolons before comments are replaced with a single space instead of
removed so that if the comments are aligned before, they will be aligned
after, for example
```julia
begin
x = 1; # This is x
y = 2 # This is y
end
```
will become
```julia
begin
x = 1 # This is x
y = 2 # This is y
end
```
Closes#34.
This patch introduces formatting for all blocklike constructs
(`if`/`try`/`function`/`begin`/`for`/`while`/...) such that inner block
always start and end with a newline character.
For example,
```julia
if x print("x") else print("y") end
```
will be reformatted as
```julia
if x
print("x")
else
print("y")
end
```
An exception is (currently) made for comments, for example
```julia
if x # comment
print("x")
end
```
will *not* be formatted as
```julia
if x
# comment
print("x")
end
```
even though the comment is technically inside the block.
Closes#35.
This patch introduces line continuation based indent for triple strings,
which typically span multiple lines without any explicit newlines in the
syntax tree (since they are hidden inside the string).
This result in the following changes, some of which are clearly
bugfixes:
Operator chains:
```diff
"""
abc
""" * """
-def
-"""
+ def
+ """
```
Operator chain as assignment right hand side:
```diff
x = """
-abc
-""" * """
-def
-"""
+ abc
+ """ * """
+ def
+ """
```
Implicit tuples:
```diff
"""
abc
""",
"""
-def
-"""
+ def
+ """
```
Note that single triple strings as a right hand side is excluded from
the indent rule, similar to having `if/try/let/...` blocks as a right
hand side.
This patch implements `# runic: on` and `# runic: off` toggle comments
that can be included in the source to toggle formatting on/off.
The two comments i) must be placed on their own lines, ii) must be on
the same level in the expression tree, and iii) must come in pairs. An
exception to condition iii) is made for top level toggle comments so
that formatting for a whole file can be disabled by a `# runic: off`
comment at the top without having to add one also at the end of the
file.
For compatibility with JuliaFormatter, `#! format: (on|off)` is also
supported but it is not possible to pair e.g. a `# runic: off` comment
with a `#! format: on` comment.
Closes#12, closes#41.