View Source Dmp.Cursor (diff_match_patch v0.2.0)

A container for Elixir lists, that can be used to iterate forward and backward, with a focused "current" item in the list, and "prev" and "next" lists of items that come before and after the current item.

In Elm this has been described as a "Zipper".

Link to this section Summary

Types

Use position: 0 for example, to set the initial position of the Cursor to the first item.

A value used to set the Cursor position.

t()

Functions

Returns true if the Cursor is positioned after the last item.

Returns true if the Cursor is positioned before the first item.

Returns the total number of items in the Cursor.

Remove items at the Cursor's current position, leaving the previous items alone.

Remove items before the Cursor's current position, leaving the current and next items alone.

Returns true if there are no items in the Cursor.

Moves the position of the Cursor back through the "prev" list to the given item.

Moves the position of the Cursor back through the "prev" list until the given item is found. Returns nil and if the item cannot be found.

Moves the position of the Cursor forward through the "next" list until the given item is found. Returns nil and if the item cannot be found.

Create a Cursor from a list of items.

Create a Cursor from two lists.

Return a 3-tuple of the previous, current, and next items relative to the Cursor's current position.

Returns false if the Cursor is positioned at or after the last item.

Returns false if the Cursor is positioned at or before the first item.

Insert items at the Cursor's current position, leaving the previous items alone.

Insert items at the Cursor's head position, leaving the current position pointer alone.

Insert items before the Cursor's current position, leaving the current and next items alone.

Moves the position of the Cursor back a number of steps.

Moves the position of the Cursor to the first item. An alias of Cursor.move_to(c, 0).

Moves the position of the Cursor forward a number of steps.

Changes the current position of the Cursor.

Create a Cursor containing no items.

Returns the current position of the Cursor.

Resets the position of the Cursor to before the first item. An alias for Cursor.move_to(c, -1).

Extract the list from a Cursor.

Link to this section Types

@type init_option() :: {:position, position_value()}
@type init_options() :: [init_option()]

Use position: 0 for example, to set the initial position of the Cursor to the first item.

@type position_value() :: -1 | non_neg_integer() | :last | :tail

A value used to set the Cursor position.

  • -1 means before the first item in the container.
  • 0 means at the first item.
  • :last means at the last item.
  • :tail means after the last item.
@type t() :: %Dmp.Cursor{current: term(), next: list(), prev: list()}

Link to this section Functions

@spec after_last?(t()) :: boolean()

Returns true if the Cursor is positioned after the last item.

examples

Examples

iex> Cursor.from_list([1, 2]) |> Cursor.after_last?()
false

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(2) |> Cursor.after_last?()
false

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(3) |> Cursor.after_last?()
true
@spec before_first?(t()) :: boolean()

Returns true if the Cursor is positioned before the first item.

examples

Examples

iex> Cursor.from_list([1, 2, 3]) |> Cursor.before_first?()
true

iex> Cursor.from_list([1, 2, 3]) |> Cursor.move_forward() |> Cursor.before_first?()
false
@spec count(t()) :: non_neg_integer()

Returns the total number of items in the Cursor.

examples

Examples

iex> Cursor.from_list([1, 2, 3]) |> Cursor.count()
3
Link to this function

delete(cursor, count \\ 1)

View Source
@spec delete(t(), integer()) :: t()

Remove items at the Cursor's current position, leaving the previous items alone.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.delete(1)
%Cursor{current: 4, next: [5], prev: [2, 1]}
Link to this function

delete_before(cursor, count \\ 1)

View Source
@spec delete_before(t(), integer()) :: t()

Remove items before the Cursor's current position, leaving the current and next items alone.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.delete_before(1)
%Cursor{current: 3, next: [4, 5], prev: [1]}
@spec empty?(t()) :: boolean()

Returns true if there are no items in the Cursor.

examples

Examples

iex> Cursor.from_list([]) |> Cursor.empty?()
true

iex> Cursor.from_list([1, 2, 3]) |> Cursor.empty?()
false
@spec find_back!(t(), term()) :: t()

Moves the position of the Cursor back through the "prev" list to the given item.

Raises if the item cannot be found.

@spec find_back(t(), term()) :: nil | t()

Moves the position of the Cursor back through the "prev" list until the given item is found. Returns nil and if the item cannot be found.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_back(1)
%Cursor{current: 1, next: [2, 3, 4, 5], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_back(5)
nil

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_back(3)
nil
@spec find_forward(t(), term()) :: nil | t()

Moves the position of the Cursor forward through the "next" list until the given item is found. Returns nil and if the item cannot be found.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_forward(5)
%Cursor{current: 5, next: [], prev: [4, 3, 2, 1]}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_forward(1)
nil

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.find_forward(3)
nil
Link to this function

from_list(items, opts \\ [])

View Source
@spec from_list(list(), init_options()) :: t()

Create a Cursor from a list of items.

  • opts - The keyword :position can specify a position value, such as -1, 0, 1, :last, or tail in order to set the position of the created Cursor.

examples

Examples

iex> Cursor.from_list([1, 2, 3])
%Cursor{current: nil, next: [1, 2, 3], prev: []}

iex> Cursor.from_list([1, 2, 3]) |> Cursor.move_forward()
%Cursor{current: 1, next: [2, 3], prev: []}

iex> Cursor.from_list([1, 2, 3], position: 1)
%Cursor{current: 2, next: [3], prev: [1]}
Link to this function

from_split(prev, next, opts \\ [])

View Source
@spec from_split(list(), list(), init_options()) :: t()

Create a Cursor from two lists.

  • opts - the keyword :position can specify a position value, such as -1, 0, 1, :last, or tail in order to set the position of the created Cursor.

examples

Examples

iex> Cursor.from_split([1, 2, 3], [4, 5, 6])
%Cursor{current: 4, next: [5, 6], prev: [3, 2, 1]}
@spec get(t()) :: {term(), term(), term()}

Return a 3-tuple of the previous, current, and next items relative to the Cursor's current position.

Any elements of the tuple may be nil.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.get()
{2, 3, 4}

iex> Cursor.from_list([]) |> Cursor.get()
{nil, nil, nil}

iex> Cursor.from_list([1, 2]) |> Cursor.get()
{nil, nil, 1}

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward() |> Cursor.get()
{nil, 1, 2}

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(2) |> Cursor.get()
{1, 2, nil}

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(3) |> Cursor.get()
{2, nil, nil}
@spec has_next?(t()) :: boolean()

Returns false if the Cursor is positioned at or after the last item.

examples

Examples

iex> Cursor.from_list([1, 2]) |> Cursor.has_next?()
true

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(2) |> Cursor.has_next?()
false

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(3) |> Cursor.has_next?()
false
@spec has_previous?(t()) :: boolean()

Returns false if the Cursor is positioned at or before the first item.

examples

Examples

iex> Cursor.from_list([1, 2]) |> Cursor.has_previous?()
false

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward() |> Cursor.has_previous?()
false

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(2) |> Cursor.has_previous?()
true

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(3) |> Cursor.has_previous?()
true
@spec insert(t(), list()) :: t()

Insert items at the Cursor's current position, leaving the previous items alone.

After the insertion, the Cursor points to the first inserted item.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.insert([10, 11])
%Cursor{current: 10, next: [11, 3, 4, 5], prev: [2, 1]}
Link to this function

insert_at_head(c, items)

View Source
@spec insert_at_head(t(), list()) :: t()

Insert items at the Cursor's head position, leaving the current position pointer alone.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.insert_at_head([10, 11])
%Cursor{current: 3, next: [4, 5], prev: [2, 1, 11, 10]}
@spec insert_before(t(), list()) :: t()

Insert items before the Cursor's current position, leaving the current and next items alone.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.insert_before([10, 11])
%Cursor{current: 3, next: [4, 5], prev: [11, 10, 2, 1]}
Link to this function

move_back(cursor, count \\ 1)

View Source
@spec move_back(t(), integer()) :: t()

Moves the position of the Cursor back a number of steps.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_back(1)
%Cursor{current: 2, next: [3, 4, 5], prev: [1]}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_back(2)
%Cursor{current: 1, next: [2, 3, 4, 5], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_back(3)
%Cursor{current: nil, next: [1, 2, 3, 4, 5], prev: []}
@spec move_first(t()) :: t()

Moves the position of the Cursor to the first item. An alias of Cursor.move_to(c, 0).

examples

Examples

iex> Cursor.new() |> Cursor.move_first()
%Cursor{current: nil, next: [], prev: []}

iex> Cursor.from_list([1]) |> Cursor.move_first()
%Cursor{current: 1, next: [], prev: []}

iex> Cursor.from_list([1, 2]) |> Cursor.move_first()
%Cursor{current: 1, next: [2], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_first()
%Cursor{current: 1, next: [2, 3, 4, 5], prev: []}
Link to this function

move_forward(cursor, count \\ 1)

View Source
@spec move_forward(t(), integer()) :: t()

Moves the position of the Cursor forward a number of steps.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_forward()
%Cursor{current: 4, next: [5], prev: [3, 2, 1]}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_forward(2)
%Cursor{current: 5, next: [], prev: [4, 3, 2, 1]}

iex> Cursor.from_list([1, 2, 3, 4, 5]) |> Cursor.move_forward(3)
%Cursor{current: 3, next: [4, 5], prev: [2, 1]}

iex> Cursor.from_list([1, 2, 3, 4, 5]) |> Cursor.move_forward(5)
%Cursor{current: 5, next: [], prev: [4, 3, 2, 1]}

iex> Cursor.from_list([1, 2, 3, 4, 5]) |> Cursor.move_forward(6)
%Cursor{current: nil, next: [], prev: [5, 4, 3, 2, 1]}

iex> %Cursor{current: {:delete, "abc"}, next: [{:equal, "xxx"}, {:insert, "def"}], prev: []} |> Cursor.move_forward(1)
%Cursor{current: {:equal, "xxx"}, next: [{:insert, "def"}], prev: [{:delete, "abc"}]}

iex> %Cursor{current: {:delete, "abc"}, next: [{:equal, "xxx"}, {:insert, "def"}], prev: []} |> Cursor.move_forward(2)
%Cursor{current: {:insert, "def"}, next: [], prev: [{:equal, "xxx"}, {:delete, "abc"}]}

iex> %Cursor{current: {:delete, "abc"}, next: [{:equal, "xxx"}, {:insert, "def"}], prev: []} |> Cursor.move_forward(3)
%Cursor{current: nil, next: [], prev: [{:insert, "def"}, {:equal, "xxx"}, {:delete, "abc"}]}
@spec move_to(t(), position_value()) :: t()

Changes the current position of the Cursor.

  • pos - The desired position.

  • -1 means the Cursor is positioned before the first item.

  • 0 means the Cursor is positioned at the first item (if it is not empty).

  • :last means the Cursor is positioned at the last item (if it is not empty).

  • :tail means the Cursor is positioned after the last item.

examples

Examples

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_to(-1)
%Cursor{current: nil, next: [1, 2, 3, 4, 5], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_to(0)
%Cursor{current: 1, next: [2, 3, 4, 5], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_to(1)
%Cursor{current: 2, next: [3, 4, 5], prev: [1]}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_to(:last)
%Cursor{current: 5, next: [], prev: [4, 3, 2, 1]}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.move_to(:tail)
%Cursor{current: nil, next: [], prev: [5, 4, 3, 2, 1]}
@spec new() :: t()

Create a Cursor containing no items.

examples

Examples

iex> Cursor.new()
%Cursor{current: nil, next: [], prev: []}
@spec position(t()) :: integer()

Returns the current position of the Cursor.

A return value of -1 means the Cursor is positioned before the first item. A return value of Cursor.count(c) means the Cursor is positioned after the last item.

examples

Examples

iex> Cursor.from_list([1, 2]) |> Cursor.position()
-1

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward() |> Cursor.position()
0

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(2) |> Cursor.position()
1

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(3) |> Cursor.position()
2

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward(4) |> Cursor.position()
2

Resets the position of the Cursor to before the first item. An alias for Cursor.move_to(c, -1).

examples

Examples

iex> Cursor.new() |> Cursor.reset()
%Cursor{current: nil, next: [], prev: []}

iex> Cursor.from_list([1]) |> Cursor.move_forward() |> Cursor.reset()
%Cursor{current: nil, next: [1], prev: []}

iex> Cursor.from_list([1, 2]) |> Cursor.move_forward() |> Cursor.reset()
%Cursor{current: nil, next: [1, 2], prev: []}

iex> %Cursor{current: 3, next: [4, 5], prev: [2, 1]} |> Cursor.reset()
%Cursor{current: nil, next: [1, 2, 3, 4, 5], prev: []}
@spec to_list(t()) :: list()

Extract the list from a Cursor.

examples

Examples

iex> Cursor.from_list([1, 2, 3]) |> Cursor.to_list()
[1, 2, 3]