Width-sensitive formatter for Julia code. Inspired by gofmt and refmt.
]add https://github.com/domluna/JLFmt.jl
JLFmt
exports format
and format_file
:
format(text::String, indent_size, print_width)
format_file(text::String, indent_size, print_width; overwrite=false)
indent_size
- the number of spaces used for an indentation.print_width
- the maximum number of characters of code on a single line. Lines over the limit will be nested if possible.overwrite
- if the file should be overwritten by the formatted output. Currently the ouput is written to a separate file.
JLFmt
parses the .jl
source file into a Concrete Syntax Tree (CST) using CSTParser
.
The CST is "prettified", creating a PTree
. The printing output of a PTree
is a canonical representation of the code removing unnecessary whitespace and joining or separating lines of code. The pretty
testset displays these transformations.
Example:
function foo
end
->
function foo end
In the nesting phase lines going over the print width are split into multiple lines such that they fit within the allowed width. All expressions are nested front to back with the exception of binary operations and conditionals.
Examples:
arg1 + arg2
->
arg1 +
arg2
foo() = body
->
# The indentation of the body is based on `indent_size`
foo() =
body
Conditionals
cond ? e1 : e2
->
cond ? e1 :
e2
->
cond ?
e1 :
e2
Calls (also applies to {}, (), [], etc)
f(arg1, arg2, arg3)
->
f(
arg1,
arg2,
arg3
)
function longfunctionname_that_is_long(lots, of, args, even, more, args)
body
end
->
function longfunctionname_that_is_long(
lots,
of,
args,
even,
more,
args
)
body
end
S <: Union{Type1,Type2,Type3}
->
S <: Union{
Type1,
Type2,
Type3
}
Finally, the PTree
is printed to an IOBuffer
. Prior to returning the formatted text a final validity
check is performed.
If you wish to not format a file this can be done by writing "nofmt" in a comment on the first line
of the file. Suppose this is the content of foo.jl
:
# nofmt
module Foo
...
end
JLFmt
will see the comment on the first line, notice it contains "nofmt", and return the original text.
Inline comments inside of a nestable types are removed.
Example:
function foo(
a, # a does ...
b, # b does ...
c
)
body
end
When formatted will produce:
function foo(
a,
b,
c
)
body
end