API Documentation

Public API

JuliaFormatter.format — Function
JuliaFormatter.format(
    path,
    style::Union{Nothing,AbstractStyle} = nothing;
    throw_on_error::Bool = false,
    format_markdown::Union{Nothing,Bool} = nothing,
    ignore::Union{Nothing,Vector{String}} = nothing,
    overwrite::Union{Nothing,Bool} = nothing,
    verbose::Union{Nothing,Bool} = nothing,
    formatting_options...,
)::Bool

Recursively traverse path and format all Julia source files inside, or format path if it is itself a Julia source file.

Returns true if no files were modified (NOTE: when throw_on_error is false (the default), this can include the case where formatting errored, in which case files will not be modified!), and false if any files were modified.

See Formatting Options for details on the formatting options. Extra keyword arguments are the following. Note that the default values documented here are only used if they are not specified in either a configuration file or as keyword arguments to format().

  • throw_on_error: If true, errors encountered while formatting individual files will be rethrown instead of being caught and logged as warnings. Default is false.

  • format_markdown: If true, additionally formats Julia code blocks inside .md, .jmd, and .qmd files. Defaults to false.

  • ignore: A vector of glob patterns to ignore. Default is String[].

  • overwrite: If true, overwrite the original files with the formatted code. Default is true.

  • verbose: If true, print the names of files being formatted. Default is false.

Errors

By default, format() does not throw errors. It is intended for "batch" use where you just want to format a bunch of files at a go. Warnings will be issued in lieu of any errors.

Set throw_on_error = true to let errors propagate instead.

Configuration files

format() will automatically search for .JuliaFormatter.toml configuration files upwards from the directory of each file being formatted.

Options specified as keyword arguments to format() will override any options specified in configuration files. Likewise if the style positional argument is specified, it will override any style specified in configuration files.

Output

Returns a boolean indicating whether the files were already formatted (true) or not (false).

source
JuliaFormatter.format_text — Function
JuliaFormatter.format_text(
    text::AbstractString,
    style::AbstractStyle = DefaultStyle();
    lines::Union{Nothing,Vector{Tuple{Int,Int}}} = nothing,
    options...,
)::String

Formats a string containing Julia code, returning the formatted code as another string. See Formatting Options for details on available options.

Line-range formatting

Pass lines to restrict formatting to a set of line ranges, emitting everything else verbatim. lines is a Vector{Tuple{Int,Int}} of inclusive, 1-based (start, stop) line ranges, e.g. format_text(text; lines = [(1, 10), (42, 47)]). Overlapping and adjacent ranges are merged. A range that begins or ends in the middle of a multi-line expression is formatted on a best-effort basis.

This function can throw the following errors

  • If text is not valid Julia code, it will throw a JuliaSyntax.ParseError.

  • If any other error happens during the formatting, it will throw a JuliaFormatter.FormattingError.

  • If the formatted text is not valid Julia code, it will throw an JuliaFormatter.InvalidFormattedTextError.

source
JuliaFormatter.format_file — Function
JuliaFormatter.format_file(args...; kwargs...)
Deprecated

format_file is deprecated. Use format instead, which has the same behaviour but handles both files and directories.

source

Internal API

Note that these are subject to change in any version (even patches), and the docstrings are not necessarily up to date!

JuliaFormatter.AlignGroup — Type
AlignGroup

Group of FST node indices and required metadata to potentially align them.

  • node_inds. Indices of FST nodes affected by alignment.
  • nodes. FST nodes affected by alignment.
  • line_offsets. Display line offset of the character nodes may be aligned to in the source file.
  • lens. Length of the FST node prior to the alignment character. Used to calculate extra whitespace padding.
  • whitespaces. Number of whitespaces between the alignment character and the prior FST node. If this is > 1 it signifies additional whitespace was manually added by the user since the formatter would only use 0 or 1 whitespaces.
source
JuliaFormatter.Configuration — Type
Configuration

A Configuration represents a collection of both formatting options and file options.

Configurations can be constructed from:

  • default values.
  • keyword arguments passed to format();
  • a .JuliaFormatter.toml configuration file; or
  • arguments passed on the command-line to jlfmt.
source
JuliaFormatter.FormattingError — Type
FormattingError(line, column, original_error)

Error thrown when formatting fails. The line and column fields indicate the location of the error in the source code.

source
JuliaFormatter.Options — Type
Options{T<:_Unset}

Struct containing all the options for formatting.

The type parameter T is used to indicate whether the option is allowed to be unset. By default, T is Union{}.

  • Options{Union{}} indicates that all options MUST be set to some value. For example,

    Options(; always_use_return=true)

    creates a set of default options but with always_use_return set to true.

  • Options{_Unset} indicates that all options are allowed to be unset. For example.

    Options{_Unset}(; always_use_return=true)

    creates a set of empty options but with always_use_return set to true.

This allows us to perform a merge on two Options objects which can be partially populated.

source
JuliaFormatter._contains_return — Method

Recursively check whether a CST node contains a return node anywhere inside it. Used to avoid prepending return to expressions like x > 0 ? (return 1) : (return 2).

source
JuliaFormatter._format_line_ranges — Method
_format_line_ranges(
    text::AbstractString,
    style::AbstractStyle,
    lines::Vector{Tuple{Int,Int}};
    kwargs...,
) -> String

Format only the lines of text covered by lines (a vector of inclusive, 1-based (start, stop) line ranges), emitting all other lines verbatim. See the comment at the top of this file for the overall strategy.

source
JuliaFormatter._format_text — Method
_format_text(
    text::AbstractString, style::AbstractStyle, opts::Options{Union{}};
    check_output::Bool=true,
    maxiters::Int=1,
    ensure_trailing_newline::Bool=false
)

The lower-level entry point for text formatting.

check_output is a boolean flag that indicates whether the output should be checked for validity. If set to true, the function will attempt to parse the formatted text and throw an InvalidFormattedTextError if it is not valid Julia code. If false it will just return the formatted text, which may be invalid!

The maxiters keyword argument is specified in order to allow the formatting algorithm to iterate to a fixed point. This is a hack and should really not be used, but currently SciMLStyle is not idempotent and requires multiple iterations to reach a fixed point. By default maxiters is set to 1, i.e., only one pass.

If ensure_trailing_newline is set to true, the function will ensure that the formatted text ends with a single newline character. This might be either CRLF or LF depending on the line ending normalization settings. If set to false, the function will not modify the trailing newline character(s) in the formatted text. This option is useful when formatting files.

source
JuliaFormatter.add_hasheq_comment! — Method

Add a #= =# comment node to the FST. Returns false if n is not a HASHEQCOMMENT.

When force_join is true, the comment is always joined to the previous node (used by contexts like hcat where the nesting phase manages line breaks). When false (the default), a comment that appears on its own line in the source is placed on a new line instead of being merged onto the previous statement.

source
JuliaFormatter.add_line_range_markers — Method
add_line_range_markers(text::AbstractString, ranges::Vector{UnitRange{Int}}) -> String

Return a copy of text with LINE_RANGE_MARKER_BEGIN / LINE_RANGE_MARKER_END comment lines inserted just before and just after each range in ranges (a normalized vector of UnitRange{Int}). Throws an ArgumentError if a range is out of bounds.

source
JuliaFormatter.add_node! — Method
add_node!(
    t::FST,
    n::FST,
    s::State;
    join_lines::Bool = false,
    max_padding::Int = -1,
    override_join_lines_based_on_source::Bool = false,
)

Appends n to t.

  • join_lines: if true, n is placed on the same line as the previous node. If false (the default), a NEWLINE is inserted before n so it appears on the next line.

  • max_padding: controls how n's length contributes to t.len, if n is not the first node being added.

    • When negative (the default), n's length is added: t.len += length(n). This is appropriate for nodes that continue the current line (e.g. an argument in a call).

    • When non-negative, we calculate npad = length(n) + max_padding (i.e., the horizontal extent of n plus some specified padding) and set t.len = max(t.len, npad). For example, in p_if, when adding the if/elseif/else keywords, we use max_padding = 0. This means that that t.len extends only up to the end of the keyword. That's because the keyword starts a new line and we don't want it to inflate the length of the parent.

    For the first node that's added, it always contributes its full length to t.len regardless of the value of max_padding.

  • override_join_lines_based_on_source: when the join_lines_based_on_source option is true, this flag overrides it so that n is added as if join_lines_based_on_source were false.

source
JuliaFormatter.align_binaryopcalls! — Method
align_binaryopcalls!(fst::FST, op_inds::Vector{Int})

Aligns binary operator expressions.

Additionally handles the case where a keyword such as const is used prior to the binary op call.

source
JuliaFormatter.block_arg_forces_nest — Method
block_arg_forces_nest(arg::JuliaSyntax.GreenNode, offset::Integer, s::State, style, ctx)::Bool

Whether arg – the sole argument of a bracketed construct such as (BLOCK) or [BLOCK for x in y], starting at byte offset of the source – is a block that will be expanded onto multiple lines, in which case the brackets must always nest. With preserve_single_line_blocks, a block that is kept on a single line does not force nesting.

source
JuliaFormatter.block_has_statements — Method
block_has_statements(cst) -> Bool

Whether the block node cst contains any statements.

Semicolons don't count. They are only statement separators and are dropped when the block is printed (see p_block), so function f(); end is just as empty as function f() end and both are printed the same way. Counting the ; as a statement would instead give function f()\nend on the first pass, which the empty-block handling then collapses to function f() end on the second — i.e. not idempotent.

source
JuliaFormatter.boundary_token_text — Method
boundary_token_text(s::State, child::JuliaSyntax.GreenNode, child_offset::Integer, rightmost::Bool)

Return the text that will be emitted for the token of child that sits directly next to a binary operator: the last non-whitespace leaf of the left operand (rightmost = true) or the first non-whitespace leaf of the right operand (rightmost = false). This text is fed to gluing_changes_tokenization to decide whether the whitespace around the operator can be removed.

source
JuliaFormatter.can_transform_syntax — Method
can_transform_syntax(s::State, allow_in_macros::Bool)

Check whether according to the current state we are allowed to perform a syntax transformation. The allow_in_macros argument indicates whether the syntax transformation should be allowed inside macros when s.opts.transform_syntax_in_macros is true. Some syntax transformations are simply not safe to perform inside macros so are disabled even if s.opts.transform_syntax_in_macros is true.

source
JuliaFormatter.chain_continuation_indent — Method
chain_continuation_indent(fst::FST, s::State)

Indentation used for the continuation lines of operator chains, comparisons and binary operator calls.

By default these are aligned to the column at which the expression starts:

x = (aaa |>     bbb |>     ccc)

When the indent_binary_continuations option is enabled they instead receive one indent level relative to the indentation of the expression itself (see #592):

x = (aaa |>    bbb |>    ccc)
source
JuliaFormatter.find_config_file — Method
find_config_file(path::AbstractString)::Union{Nothing,AbstractString}

Search for a .JuliaFormatter.toml configuration file in the directory of path and its ancestors. Returns the path to the configuration file if found, or nothing if not found.

source
JuliaFormatter.first_nonws_leaf_and_offset — Function
first_nonws_leaf_and_offset(
    node::JuliaSyntax.GreenNode,
)::Union{Nothing,Tuple{JuliaSyntax.GreenNode,Integer}

Return the first non-whitespace leaf node in node plus its offset from the beginning of node, or nothing if there are no non-whitespace leaves.

source
JuliaFormatter.gluing_changes_tokenization — Method
gluing_changes_tokenization(left, op, right)::Bool

For a binary operator op, check whether emitting left, op, and right with no spaces in between produces a different token stream than emitting them separated by spaces.

left and right are the text of the tokens immediately adjacent to the operator. Note that this is not necessarily equal to the text of the full left and right operands (we only take the extreme tokens).

left and/or right may be nothing, meaning that the token on that side cannot lexically merge with an operator (see boundary_token_text). Such a side is stood in for by the neutral identifier x. Using the actual text of such tokens would produce false positives. For example, if the binary expression was "a" * "b", then naively passing the extreme tokens would lead to "*".

source
JuliaFormatter.has_delimiters — Method
has_delimiters(cst::JuliaSyntax.GreenNode)

cst is assumed to be a single child node. Returns true if the node is of the syntactic form {...}, [...], or (...).

source
JuliaFormatter.has_more_args_to_come — Method
has_more_args_to_come

Searches childs[start_index:end] for the first non-whitespace node and returns whether it is not of kind stop_kind.

If the first non-whitespace node is of kind stop_kind, that implies that there are no more arguments to process in the current argument list / indexing expression / etc.

source
JuliaFormatter.hcat_allow_boundary_newlines — Method
hcat_allow_boundary_newlines(style::AbstractStyle)

Determine whether newlines are allowed immediately after the opening [ and immediately before the closing ] of an hcat node.

Most styles allow this, but YAS doesn't (and SciML too, since it dispatches to YAS).

In principle this can be generalised to vcat and ncat as well; I just haven't done so.

source
JuliaFormatter.is_column_aligned — Method
is_column_aligned(fst::FST)

Whether YASStyle lays out the continuation lines of fst relative to the column at which fst itself starts, rather than relative to the start of the line it appears on.

Iterables are column-aligned, because their arguments line up with the bracket that opens them, as is where, whose type parameters line up with the {:

f(aaaaaaaaaaaaaaaaaaaaaa,  bbbbbbbbbbbbbbbbbbbbbb)Foo{A} where {Aaaaaaaaaaaaaaa<:Xxxxxxxxxxxx,              Bbbbbbbbbbbbbbb<:Yyyyyyyyyyyy}

Block-like constructs are not, because their bodies are indented by one level from the start of the line, regardless of where function f() starts:

function f()    bodyend

For nested constructs we might need to inspect their children. For example in

@mymacro [aaaaaaaaaaaaaaaaaaaa,          bbbbbbbbbbbbbbbbbbbb]

the second line is indented according to the [ iff the last argument of the macro is column-aligned.

A binary call is column-aligned unless its operator is one of those that indents the RHS from the start of the line instead (see is_indent_nest).

Chain, Comparison and Conditional are column-aligned in YASStyle too, but they are deliberately not listed here because the only caller (n_binaryopcall!) accounts for their full width before it will consider undoing a nesting, so it never has to move one of them that has already been split over several lines.

source
JuliaFormatter.is_formattable_file — Method
is_formattable_file(filename) -> Bool

Check whether filename is a file that JuliaFormatter can format, based on its extension or the presence of a Julia shebang line (e.g. #!/usr/bin/env julia).

source
JuliaFormatter.is_indent_nest — Method
is_indent_nest(fst::FST)

Whether nesting the binary call fst at its operator indents the RHS by one level from the start of the line:

aaaaaaaaaaaa =>    rhs

as opposed to bringing it back to the column the LHS starts at, which is what every other operator does:

aaaaaaaaaaaa inrhs

True for assignments, =>, -> and standalone short-circuits.

source
JuliaFormatter.is_iterable_arg — Method

Returns whether fst can be an iterable argument. For example in the case of a function call, which is of type Call:

(a, b, c; k1=v1)

This would return true for a, b, c and k1=v1 and false for all other nodes.

source
JuliaFormatter.is_newline_after_2semicolons — Method
is_newline_after_2semicolons(cst::JuliaSyntax.GreenNode, i::Integer)

Detect if child node i of cst is a newline that follows two semicolons. For example, this will detect the newline in constructs such as

[a b;; c d]
source
JuliaFormatter.is_opaque_string — Method
is_opaque_string(fst::FST)::Bool

Whether fst is a StringN node built from a non-triple-quoted multiline literal, whose interior lines must be emitted verbatim (see the is_opaque_string field of Metadata).

source
JuliaFormatter.isignored — Method
isignored(path::AbstractString, config::Configuration)::Bool

Determine if the given path should be ignored based on the ignore patterns in the config. Returns true if the path matches any of the ignore patterns.

source
JuliaFormatter.keep_single_line — Method
keep_single_line(cst::JuliaSyntax.GreenNode, s::State, ctx::PrettyContext; offset = s.offset)::Bool

Whether the block construct cst, which starts at byte offset of the source, is written entirely on a single source line and should therefore be kept on a single line (see the preserve_single_line_blocks option).

A construct containing a docstring ("doc" x) is never kept on one line, since the docstring is always emitted on its own line. The elseif/else/catch/finally sub-nodes of an if/try don't decide for themselves but follow the enclosing construct (via ctx.parent_keep_single_line), since their own span covers neither the start of the construct nor its end.

IMPORTANT: unless offset is given explicitly, this must be called when s.offset is still positioned at the start of cst (i.e. before any of its children have been prettified), since it compares the source line of the first and last byte of cst.

source
JuliaFormatter.last_nonws_leaf_and_offset — Function
last_nonws_leaf_and_offset(
    node::JuliaSyntax.GreenNode,
)::Union{Nothing,Tuple{JuliaSyntax.GreenNode,Integer}

Return the last non-whitespace leaf node in node plus its offset from the beginning of node, or nothing if there are no non-whitespace leaves. This is the mirror image of first_nonws_leaf_and_offset.

source
JuliaFormatter.move_at_sign_to_the_end — Method
move_at_sign_to_the_end(fst::FST, s::State)

NOTE: Assumes fst is the caller name of a macrocall such as @macro or Module.@macro.

Moves @ to the last identifier.

Example:

@Module.macro

to

Module.@macro
source
JuliaFormatter.nest_if_over_margin! — Method
nest_if_over_margin!(
    style,
    fst::FST,
    s::State,
    idx::Int;
    stop_idx::Union{Int,Nothing} = nothing,
)::Bool

Converts the node at idx to a NEWLINE if the current margin plus the additional margin from fst[idx:stop_idx-1] is greater than the allowed margin.

If stop_idx == nothing the range is fst[idx:end].

Returns whether nesting occurred.

source
JuliaFormatter.normalize_line_ranges — Method
normalize_line_ranges(lines::Vector{Tuple{Int,Int}}) -> Vector{UnitRange{Int}}

Convert the user-supplied lines (inclusive, 1-based (start, stop) line ranges) into a sorted vector of non-overlapping, non-adjacent UnitRange{Int}s.

Overlapping and adjacent ranges are merged rather than rejected: this keeps the core API robust for callers such as LSP rangesFormatting, which may legitimately hand us touching or overlapping ranges. Bounds against the actual file length are checked later, in add_line_range_markers.

source
JuliaFormatter.normalize_number_literal — Method
normalize_number_literal(k::JuliaSyntax.Kind, val::AbstractString, trailing_zero::Bool)

Add leading zeroes, and trailing zeros if trailing_zero is true, to float literals.

              trailing_zero = true     trailing_zero = false`1.`     -->   `1.0`                    `1.``.5`     -->   `0.5`                    `0.5`

Other literals are unchanged.

source
JuliaFormatter.p_pipe_to_call — Method
p_pipe_to_call

Take a CST of the form x |> y or x .|> y, but return a FST with the equivalent function call y(x) or y.(x) instead.

Note that this function is only called for certain pipe-applications. See the call site in p_binaryopcall for details.

source
JuliaFormatter.prepend_return_fst! — Method
prepend_return_fst!(fst::FST, s::State)

Prepends return to the last expression of a block if applicable.

Note: This function is only called when a short-form function definition is converted to a long-form one, AND always_use_return is true. For ordinary, pre-existing long-form function definitions, the implementation of always_use_return is in p_block in default/pretty.jl. This is done to avoid post-FST passes which tend to cause idempotence issues.

function foo()    a = 2 * 3    a / 3end

to

function foo()    a = 2 * 3    return a / 3end
source
JuliaFormatter.remove_line_range_markers — Method
remove_line_range_markers(marked_src::AbstractString, formatted::AbstractString) -> String

Splice the formatted in-range blocks back into the original source. marked_src is the marker-annotated source produced by add_line_range_markers and formatted is the result of formatting it. The two streams are walked line by line in lockstep:

  • outside a marker pair we keep the (verbatim) marked_src line,
  • inside a marker pair we keep the formatted line,
  • marker lines themselves are dropped.

Both streams contain the same markers in the same order, so the begin/end markers act as synchronization points between them.

source
JuliaFormatter.separate_kwargs_with_semicolon! — Method
separate_kwargs_with_semicolon!(fst::FST)

Ensures keyword arguments are separated by a ";".

Examples

Replace "," with ";".

a = f(x, y = 3)->a = f(x; y = 3)

Move ";" to the prior to the first positional argument.

a = f(x = 1; y = 2)->a = f(; x = 1, y = 2)
source
JuliaFormatter.source_begins_with_op_needing_parens — Method

sourcebeginswithopneeding_parens(s, cst, offset)

Check whether the first token of cst is an operator. Used in p_kw: if the value on the rhs of kwarg=value begins with an operator, then we parenthesise value to avoid ambiguity.

Note that the behaviour of this differs from unary_info(cst): for example, unary_info(cst) does not pick up expressions such as >=(1), which is interpreted as a function call, not an application of a unary operator. However, these are exactly the sort of things that we want to parenthesise in p_kw – hence this function.

source
JuliaFormatter.source_op_kind_from_offset — Method
source_op_kind_from_offset(s, cst, offset)::Union{Nothing,JuliaSyntax.Kind}

Return the operator kind of cst, using the source text at offset if necessary to help determine this. If cst is not an operator, returns nothing.

Note that this function may still return a K"Identifier"! This is because Julia allows some weird postfix operators. See the comments in the function for more info.

The check against the source is needed because JuliaSyntax v1 can encode source operators as Identifier leaves in call forms. For example:

julia> JuliaSyntax.parseall(JuliaSyntax.GreenNode, "+y")     1:2      │[toplevel]     1:2      │  [call]     1:1      │    Identifier           ✔     2:2      │    Identifier           ✔

See https://github.com/JuliaLang/JuliaSyntax.jl/issues/548 for more information.

source
JuliaFormatter.starts_with_semicolon — Method
starts_with_semicolon(fst::FST)::Bool

Whether the first leaf of fst is a semicolon. Used when joining a single-line block onto the line of its parent construct: in try; isfile(x); catch; false end the body block starts with a ;, and no space should be inserted between the try keyword and the ; (try; isfile(x) rather than try ; isfile(x)).

source
JuliaFormatter.unary_info — Method
unary_info(x::JuliaSyntax.GreenNode)::Union{Bool,Nothing}

Returns:

  • true if x is a prefix unary operator application, such as +x or <:x

  • false if x is a postfix unary operator application, such as x' or x...;

  • nothing if x is not an application of a unary operator.

source
JuliaFormatter.walk — Method
walk(f, fst::FST, s::State)

Walks fst calling f on each node.

In situations where descending further into a subtree is not desirable f should return a value other than nothing.

Note

This function mutates the State's (s) line_offset. If this is not desired you should save the value before calling this function and restore it after.

source
JuliaFormatter.Shims.is_caller_in_function_def — Method
is_caller_in_function_def(t::JuliaSyntax.GreenNode) -> Bool

Identify the caller in a function definition, i.e., the f(...) part in

function f(...)    bodyend

This may be more complicated than just is_function_call, because the caller may be f(...)::T, f(...) where T, or (f(...)) (or combinations thereof).

source
JuliaFormatter.Shims.is_function_call — Method

Determine if a CST represents a function call, i.e., F(X1, X2, ...) syntactically.

This covers, for example:

  • f(x) -> K"call"
  • f.(x) -> K"dotcall"
  • <=(x) -> K"call"
  • .<=(x) -> K"call" (with a dotted caller)
  • <:(x) -> K"<:", caught by istypeoperator
  • .<:(x) -> K"call" (with a dotted caller)

<: and >: are special-cased by JuliaSyntax to return K"<:" and K">:" nodes rather than K"call", but from a syntax perspective we want to treat them the same as any other function.

We then need to exclude a few things:

  • applications of unary operators, for example, +x, -x, and <:x. These are still parsed as K"call" but these can be identified by the fact that JuliaSyntax.is_prefix_op_call returns true for these. BUT, we don't want to exclude the parenthesised versions +(x), -(x) since these do look like function calls (and we only care about the syntax, not the semantics)! So need some custom logic to identify these...

  • bare operators, easily identified by is_leaf.

  • infix operators, for which JuliaSyntax.is_infix_op_call USUALLY returns true (but not for a <: b –- hence why we instead do a check for K"(").

Note: JuliaSyntax.is_prefix_call sounds like the right thing to check, but for some reason this returns true for tons of things we don't care about. For example:

julia> JS.is_prefix_call(JS.parseall(JS.GreenNode, "1")[1])true
source
JuliaFormatter.Shims.is_really_whitespace — Method
is_really_whitespace(cst::JS.GreenNode) -> Bool

Check whether a CST node is really whitespace, i.e., either K"Whitespace" or K"NewlineWs". Note that JuliaSyntax.is_whitespace returns true for K"Comment" as well, which we don't want here.

source