View Source Quokka.Style behaviour (Quokka v2.4.1)

A Style takes AST and returns a transformed version of that AST.

Because these transformations involve traversing trees (the "T" in "AST"), we wrap the AST in a structure called a Zipper to facilitate walking the trees.

Summary

Callbacks

run will be used with Zipper.traverse_while/3, meaning it will be executed on every node of the AST.

Functions

Gets all comments in range start_line..last_line, and any comments immediately before start_line.s

Returns all comments "for" a node, including on the line before it. see comments_for_lines for more

Set the line of all comments with line in range_start..range_end to instead have line range_start

Returns the current node (wrapped in a __block__ if necessary) if it's a valid place to insert additional nodes

Returns a zipper focused on the nearest node where additional nodes can be inserted (a "block").

Takes a list of nodes and clumps them up, setting end_of_expression: [newlines: x] to 1 for all but the final node, which gets 2 instead, (hopefully!) creating an empty line before whatever follows.

Recursively sets :line meta to line. Deletes :newlines unless delete_lines: false is passed

Perform a series of shifts in a single pass.

Change the line of all comments with line in range by adding delta to it. A positive delta will move the lines further down a file, while a negative delta will move them up.

Recursively updates :line meta by adding delta

Traverses an ast node, updating all nodes' meta with meta_fun

prewalks ast and sets all meta to nil. useful for comparing AST without meta (line numbers, etc) interfering

Types

@type context() :: %{comments: [map()], file: :stdin | String.t()}

Callbacks

run will be used with Zipper.traverse_while/3, meaning it will be executed on every node of the AST.

You can skip traversing parts of the tree by returning a Zipper that's further along in the traversal, for example by calling Zipper.skip(zipper) to skip an entire subtree you know is of no interest to your Style.

Functions

Link to this function

comments_for_lines(comments, start_line, last_line)

View Source

Gets all comments in range start_line..last_line, and any comments immediately before start_line.s

  1. code
  2. a

  3. b

  4. code # c
  5. d

  6. code
  7. e

here, comments_for_lines(comments, 4, 6) is "a", "b", "c", "d"

Link to this function

comments_for_node(node, comments)

View Source

Returns all comments "for" a node, including on the line before it. see comments_for_lines for more

Link to this function

displace_comments(comments, range)

View Source

Set the line of all comments with line in range_start..range_end to instead have line range_start

Link to this function

ensure_block_parent(zipper)

View Source
@spec ensure_block_parent(Quokka.Zipper.t()) :: {:ok, Quokka.Zipper.t()} | :error

Returns the current node (wrapped in a __block__ if necessary) if it's a valid place to insert additional nodes

Link to this function

find_nearest_block(zipper)

View Source
@spec find_nearest_block(Quokka.Zipper.t()) :: Quokka.Zipper.t()

Returns a zipper focused on the nearest node where additional nodes can be inserted (a "block").

The nearest node is either the current node, an ancestor, or one of those two but wrapped in a new :__block__ node.

Link to this function

order_line_meta_and_comments(nodes, comments, first_line)

View Source

Takes a list of nodes and clumps them up, setting end_of_expression: [newlines: x] to 1 for all but the final node, which gets 2 instead, (hopefully!) creating an empty line before whatever follows.

Link to this function

reset_newlines(list, acc)

View Source
Link to this function

set_line(ast_node, line, opts \\ [])

View Source

Recursively sets :line meta to line. Deletes :newlines unless delete_lines: false is passed

Link to this function

shift_comments(comments, shifts)

View Source

Perform a series of shifts in a single pass.

When shifting comments from block A to block B, naively using two passes of shift_comments/3 would result in all comments ending up in either region A or region B (because A would move to B, then all B back to A) This function exists to make sure that a comment is only moved once during the swap.

Link to this function

shift_comments(comments, range, delta)

View Source

Change the line of all comments with line in range by adding delta to it. A positive delta will move the lines further down a file, while a negative delta will move them up.

Link to this function

shift_line(ast_node, delta)

View Source

Recursively updates :line meta by adding delta

Link to this function

update_all_meta(node, meta_fun)

View Source

Traverses an ast node, updating all nodes' meta with meta_fun

prewalks ast and sets all meta to nil. useful for comparing AST without meta (line numbers, etc) interfering