View Source ExTerm.Console (ex_term v0.2.0)

A datastructure which describes in-memory storage of console information.

important

Important

Understanding this datastructure and its associated functions is critical to implementing a custom ExTerm backend.

Console information consists of the following:

  • buffer of all rows/columns so far.
  • view window sizing metadata.
  • cursor location.
  • current ANSI styling metadata.

You may also store custom metadata into console.

Console is backed by an ets table. Access functions are designed to operate across a cluster. Note that console is not backed by a process, but it is the responsibility of a process; if that process dies, the console will get destroyed, and by default mutating functions cannot be called from other processes.

inside-the-table

Inside the table

the table contains metadata of the form {atom, term}, and cells of the form {{row, column}, %ExTerm.Console.Cell{}}. The table is sorted on term order; this preserves lexicographical order over the cells, and the metadata precede all of the cells.

Note that every row contains an extra "sentinel" cell at the end which needs to be displayed on the console. This sentinel serves to record the length of the row, and also creates line breaks in the terminal div by being a "preformatted" hard return.

Link to this section Summary

Types

the contents of the "cells" section of the table.

the layout of the console, which should corresppond to the number of rows and columns in the primary view of the console in html.

coordinate information for a character in the console.

t()

descriptor for a console, which stores a the permission information, a reference to the table, and a write semaphore (if the table is public)

Functions

returns the number of columns in a given row.

obtains the cursor metadata

primitive :ets delete function

removes a key from the metadata store

returns a full row, in ascending order.

retrieves the cell info (location + cell contents) for the console location

obtains a single key metadata or a list of keys.

returns if a location is present in the console

primitive :ets insert function

inserts iodata at a certain row.

primitive :ets last function

returns the last location on the console.

returns true if the cell exists and the location is on the last column of its row, not inclusive of the sentinel. Note this returns false if it's the sentinel.

obtains the layout metadata

primitive :ets lookup function

initalizes a new console. The argument, which should be a keyword list, will be put into the console metadata.

inserts a new row into the console, either at a given location, given by an integer, or at the end, given by :end atom.

puts a single cell onto the console, using absolute row position.

inserts iodata at the location of a cursor.

puts multiple k/v into the metadata store (as a keyword list)

puts a single k/v into the metadata store

primitive :ets select function

primitive :ets select_count function

primitive :ets select function that selects cells from a location inclusive

obtains the style metadata

Link to this section Types

@type cellinfo() :: {location(), ExTerm.Console.Cell.t()}

the contents of the "cells" section of the table.

@type layout() :: location()

the layout of the console, which should corresppond to the number of rows and columns in the primary view of the console in html.

@type location() :: {row :: pos_integer(), column :: pos_integer()}

coordinate information for a character in the console.

@opaque t()

descriptor for a console, which stores a the permission information, a reference to the table, and a write semaphore (if the table is public)

Link to this section Functions

@spec columns(t(), row :: pos_integer()) :: non_neg_integer()

returns the number of columns in a given row.

Does not include the sentinel in the final count.

If the row doesn't exist, returns 0.

this function must be in an access transaction

@spec cursor(t()) :: location()

obtains the cursor metadata

this function must be in an access transaction

@spec delete(t(), atom()) :: t()

primitive :ets delete function

this function must be in a mutation transaction

Link to this function

delete_metadata(console, key)

View Source
@spec delete_metadata(t(), atom()) :: t()

removes a key from the metadata store

this function must be in a mutation transaction

Link to this function

full_row(console, row, with_sentinel? \\ false)

View Source
@spec full_row(t(), row :: pos_integer(), with_sentinel? :: boolean()) :: [cellinfo()]

returns a full row, in ascending order.

May include the sentinel, if with_sentinel? is true (defaults to false)

this function must be in an access transaction

@spec get(t(), location()) :: nil | ExTerm.Console.Cell.t()

retrieves the cell info (location + cell contents) for the console location

this function must be in an access transaction

Link to this function

get_metadata(console, key)

View Source
@spec get_metadata(t(), atom() | [atom()]) :: term()

obtains a single key metadata or a list of keys.

Note that if you provide a list of keys the values will be returned as a keyword list, in erlang term order of the keys.

@spec has?(t(), location()) :: boolean()

returns if a location is present in the console

this function must be in an access transaction

Link to this function

insert(console, content)

View Source
@spec insert(t(), tuple() | [tuple()]) :: t()

primitive :ets insert function

this function must be in a mutation transaction

Link to this function

insert_iodata(console, iodata, row)

View Source
@spec insert_iodata(t(), iodata(), row :: pos_integer()) :: Range.t()

inserts iodata at a certain row.

This will "push down" as many lines as is necessary to insert the iodata. If the current cursor precedes the insertion point, it will be unaffected. If the current cursor is after the insertion point, it will be displaced as many lines as are necessary

this function must be in an mutation transaction

@spec last(t()) :: location() | atom()

primitive :ets last function

this function must be in an access transaction

@spec last_cell(t()) :: layout()

returns the last location on the console.

Does NOT include the sentinel. There is always guaranteed to be a sentinel on the end of the cell.

If the table is empty and only contains metadata, returns {0, 0}

this function must be in an access transaction

Link to this function

last_column?(console, arg)

View Source
@spec last_column?(t(), location()) :: boolean()

returns true if the cell exists and the location is on the last column of its row, not inclusive of the sentinel. Note this returns false if it's the sentinel.

this function must be in an access transaction

@spec layout(t()) :: location()

obtains the layout metadata

this function must be in an access transaction

Link to this function

lookup(console, location)

View Source
@spec lookup(t(), location()) :: cellinfo() | nil

primitive :ets lookup function

this function must be in an access transaction

Link to this function

move_cursor(console, new_cursor)

View Source
@spec move_cursor(t(), location()) :: t()
@spec new(keyword()) :: t()

initalizes a new console. The argument, which should be a keyword list, will be put into the console metadata.

Link to this function

new_row(console, insertion_at \\ :end)

View Source
@spec new_row(t(), pos_integer() | :end) :: t()

inserts a new row into the console, either at a given location, given by an integer, or at the end, given by :end atom.

this function must be in a mutation transaction

Link to this function

put_cell(console, location, char)

View Source
@spec put_cell(t(), location(), ExTerm.Console.Cell.t()) :: t()

puts a single cell onto the console, using absolute row position.

Does not change the cursor location.

this function must be in a mutation transaction

Link to this function

put_iodata(console, iodata)

View Source
@spec put_iodata(t(), iodata()) :: :ok

inserts iodata at the location of a cursor.

this function must be in an mutation transaction

Link to this function

put_metadata(console, keyword)

View Source
@spec put_metadata(
  t(),
  keyword()
) :: t()

puts multiple k/v into the metadata store (as a keyword list)

this function must be in a mutation transaction

Link to this function

put_metadata(console, key, value)

View Source
@spec put_metadata(t(), atom(), term()) :: t()

puts a single k/v into the metadata store

this function must be in a mutation transaction

@spec select(t(), :ets.match_spec()) :: [cellinfo()]

primitive :ets select function

this function must be in an access transaction

Link to this function

select_count(console, ms)

View Source
@spec select_count(t(), :ets.match_spec()) :: non_neg_integer()

primitive :ets select_count function

this function must be in an access transaction

Link to this function

select_from(console, location)

View Source
@spec select_from(t(), Console.location()) :: [cellinfo()]

primitive :ets select function that selects cells from a location inclusive

this function must be in an access transaction

@spec style(t()) :: ExTerm.Style.t()

obtains the style metadata

this function must be in an access transaction