View Source Styler.Zipper (Styler v1.1.1)

Implements a Zipper for the Elixir AST based on Gérard Huet Functional pearl: the zipper paper and Clojure's clojure.zip API.

A zipper is a data structure that represents a location in a tree from the perspective of the current node, also called focus. It is represented by a 2-tuple where the first element is the focus and the second element is the metadata/context. The metadata is nil when the focus is the topmost node

Summary

Functions

Traverses zipper, returning true when fun.(Zipper.node(zipper)) is truthy, or false otherwise

Inserts the item as the rightmost child of the node at this zipper, without moving.

Returns a list of children of the node.

Returns the zipper of the leftmost child of the node at this zipper, or nil if no there's no children.

Returns a zipper to the node that satisfies the predicate function, or nil if none is found.

Inserts the item as the leftmost child of the node at this zipper, without moving.

Inserts the item as the left sibling of the node at this zipper, without moving. Raises an ArgumentError when attempting to insert a sibling at the top level.

Inserts the item as the right sibling of the node at this zipper, without moving. Raises an ArgumentError when attempting to insert a sibling at the top level.

Inserts many siblings to the right.

Returns the zipper of the left sibling of the node at this zipper, or nil.

Returns the leftmost sibling of the node at this zipper, or itself.

Returns the following zipper in depth-first pre-order.

Returns the node at the zipper.

Inserts many siblings to the left.

Returns the previous zipper in depth-first pre-order. Returns nil if the tree is already at the top.

Removes the node at the zipper, returning the zipper that would have preceded it in a depth-first walk.

Replaces the current node in the zipper with a new node.

Returns the zipper with the current children of the node replaced with children

Returns the zipper of the right sibling of the node at this zipper, or nil.

Returns the rightmost sibling of the node at this zipper, or itself.

Walks the zipper all the way up and returns the root node.

Returns the zipper of the right sibling of the node at this zipper, or the next zipper when no right sibling is available.

Walks the zipper all the way up and returns the top zipper.

Traverses the tree in depth-first pre-order calling the given function for each node.

Traverses the tree in depth-first pre-order calling the given function for each node with an accumulator.

Traverses the tree in depth-first pre-order calling the given function for each node.

Traverses the tree in depth-first pre-order calling the given function for each node with an accumulator.

Returns the zipper of the parent of the node at this zipper, or nil if at the top.

Replaces the current node in the zipper with the result of applying fun to the node.

Creates a zipper from a tree node.

Types

@type command() :: :cont | :skip | :halt
@opaque path()
@type t() :: zipper()
@type tree() :: Macro.t()
@type zipper() :: {tree(), path() | nil}

Functions

@spec any?(zipper(), (tree() -> term())) :: boolean()

Traverses zipper, returning true when fun.(Zipper.node(zipper)) is truthy, or false otherwise

Link to this function

append_child(arg, child)

View Source

Inserts the item as the rightmost child of the node at this zipper, without moving.

@spec children(zipper()) :: [tree()]

Returns a list of children of the node.

@spec down(zipper()) :: zipper() | nil

Returns the zipper of the leftmost child of the node at this zipper, or nil if no there's no children.

Link to this function

find(zipper, direction \\ :next, predicate)

View Source
@spec find(zipper(), direction :: :prev | :next, predicate :: (tree() -> any())) ::
  zipper() | nil

Returns a zipper to the node that satisfies the predicate function, or nil if none is found.

The optional second parameters specifies the direction, defaults to :next.

Link to this function

insert_child(arg, child)

View Source

Inserts the item as the leftmost child of the node at this zipper, without moving.

@spec insert_left(zipper(), tree()) :: zipper()

Inserts the item as the left sibling of the node at this zipper, without moving. Raises an ArgumentError when attempting to insert a sibling at the top level.

Link to this function

insert_right(arg, child)

View Source
@spec insert_right(zipper(), tree()) :: zipper()

Inserts the item as the right sibling of the node at this zipper, without moving. Raises an ArgumentError when attempting to insert a sibling at the top level.

Link to this function

insert_siblings(arg, siblings)

View Source
@spec insert_siblings(zipper(), [tree()]) :: zipper()

Inserts many siblings to the right.

Equivalent to

Enum.reduce(siblings, zipper, &Zipper.insert_right(&2, &1))
@spec left(zipper()) :: zipper() | nil

Returns the zipper of the left sibling of the node at this zipper, or nil.

@spec leftmost(zipper()) :: zipper()

Returns the leftmost sibling of the node at this zipper, or itself.

@spec next(zipper()) :: zipper() | nil

Returns the following zipper in depth-first pre-order.

@spec node(zipper()) :: tree()

Returns the node at the zipper.

Link to this function

prepend_siblings(arg, siblings)

View Source
@spec prepend_siblings(zipper(), [tree()]) :: zipper()

Inserts many siblings to the left.

Equivalent to

Enum.reduce(siblings, zipper, &Zipper.insert_left(&2, &1))
@spec prev(zipper()) :: zipper() | nil

Returns the previous zipper in depth-first pre-order. Returns nil if the tree is already at the top.

@spec remove(zipper()) :: zipper()

Removes the node at the zipper, returning the zipper that would have preceded it in a depth-first walk.

@spec replace(zipper(), tree()) :: zipper()

Replaces the current node in the zipper with a new node.

Link to this function

replace_children(arg, children)

View Source
@spec replace_children(zipper(), [tree()]) :: zipper()

Returns the zipper with the current children of the node replaced with children

@spec right(zipper()) :: zipper() | nil

Returns the zipper of the right sibling of the node at this zipper, or nil.

@spec rightmost(zipper()) :: zipper()

Returns the rightmost sibling of the node at this zipper, or itself.

@spec root(zipper()) :: tree()

Walks the zipper all the way up and returns the root node.

Link to this function

skip(zipper, direction \\ :next)

View Source
@spec skip(zipper(), direction :: :next | :prev) :: zipper() | nil

Returns the zipper of the right sibling of the node at this zipper, or the next zipper when no right sibling is available.

This allows to skip subtrees while traversing the siblings of a node.

The optional second parameters specifies the direction, defaults to :next.

If no right/left sibling is available, this function returns the same value as next/1/prev/1.

The function skip/1 behaves like the :skip in traverse_while/2 and traverse_while/3.

@spec top(zipper()) :: zipper()

Walks the zipper all the way up and returns the top zipper.

@spec traverse(zipper(), (zipper() -> zipper())) :: zipper()

Traverses the tree in depth-first pre-order calling the given function for each node.

If the zipper is not at the top, just the subtree will be traversed.

The function must return a zipper.

Link to this function

traverse(zipper, acc, fun)

View Source
@spec traverse(zipper(), term(), (zipper(), term() -> {zipper(), term()})) ::
  {zipper(), term()}

Traverses the tree in depth-first pre-order calling the given function for each node with an accumulator.

If the zipper is not at the top, just the subtree will be traversed.

Link to this function

traverse_while(zipper, fun)

View Source
@spec traverse_while(zipper(), (zipper() -> {command(), zipper()})) :: zipper()

Traverses the tree in depth-first pre-order calling the given function for each node.

The traversing will continue if the function returns {:cont, zipper}, skipped for {:skip, zipper} and halted for {:halt, zipper}

If the zipper is not at the top, just the subtree will be traversed.

The function must return a zipper.

Link to this function

traverse_while(zipper, acc, fun)

View Source
@spec traverse_while(
  zipper(),
  term(),
  (zipper(), term() -> {command(), zipper(), term()})
) ::
  {zipper(), term()}

Traverses the tree in depth-first pre-order calling the given function for each node with an accumulator.

The traversing will continue if the function returns {:cont, zipper, acc}, skipped for {:skip, zipper, acc} and halted for {:halt, zipper, acc}

If the zipper is not at the top, just the subtree will be traversed.

@spec up(zipper()) :: zipper() | nil

Returns the zipper of the parent of the node at this zipper, or nil if at the top.

@spec update(zipper(), (tree() -> tree())) :: zipper()

Replaces the current node in the zipper with the result of applying fun to the node.

@spec zip(tree()) :: zipper()

Creates a zipper from a tree node.