TermUI.Backend.State (TermUI v1.0.0)
View SourceShared state structure for terminal backends.
The State module provides a consistent wrapper around backend-specific state, enabling uniform state management across different backend implementations (Raw and TTY modes).
Purpose
This optional helper can wrap backend selection data for callers that want a
uniform value. TermUI.Runtime stores backend fields directly in
TermUI.Runtime.State and does not construct this struct. The helper provides:
- Consistent interface: All backends expose the same state structure
- Mode tracking: Easy identification of current terminal mode
- Capability access: Unified access to detected terminal capabilities
- Size caching: Cached terminal dimensions to avoid repeated queries
- Lifecycle tracking: Initialization status for proper cleanup
Usage
A custom integration can create a state struct after backend selection:
case Selector.select() do
{:raw, raw_state} ->
%State{
backend_module: TermUI.Backend.Raw,
backend_state: raw_state,
backend_mode: :raw,
capabilities: %{},
initialized: false
}
{:tty, capabilities} ->
%State{
backend_module: TermUI.Backend.TTY,
backend_state: nil,
backend_mode: :tty,
capabilities: capabilities,
initialized: false
}
endFields
:backend_module- The backend implementation module (required):backend_state- Backend-specific internal state:backend_mode- Current terminal mode,:rawor:tty(required):capabilities- Map of detected terminal capabilities:size- Cached terminal dimensions as{rows, cols}ornil:initialized- Whether the backend has been fully initialized
Naming Convention
This field is named :backend_mode (not :mode) to be consistent with
Runtime.State.backend_mode and to avoid confusion with other mode fields
throughout the codebase (e.g., line_mode, mouse_mode, color_mode).
Constructors
Instead of creating structs directly, use the constructor functions:
# General constructor with explicit backend module
State.new(MyBackend, backend_mode: :tty, capabilities: %{colors: :true_color})
# Convenience constructor for raw mode
State.new_raw()
State.new_raw(%{raw_mode_started: true})
# Convenience constructor for TTY mode
State.new_tty(%{colors: :color_256, unicode: true})State Updates
State structs are immutable. Use update functions for convenience:
state = State.new_tty(%{colors: :true_color})
state = State.put_size(state, {24, 80})
state = State.mark_initialized(state)
Summary
Types
Terminal mode indicating which backend type is active.
Cached terminal dimensions as {rows, cols}.
The backend state struct.
Functions
Marks the state as initialized.
Creates a new backend state with the given module and options.
Creates a new raw mode backend state.
Creates a new TTY mode backend state with the given capabilities.
Updates the backend-specific state.
Updates the capabilities map.
Updates the cached terminal dimensions.
Types
@type backend_mode() :: :raw | :tty
Terminal mode indicating which backend type is active.
@type dimensions() :: {pos_integer(), pos_integer()} | nil
Cached terminal dimensions as {rows, cols}.
@type t() :: %TermUI.Backend.State{ backend_mode: backend_mode(), backend_module: module(), backend_state: term(), capabilities: map(), initialized: boolean(), size: dimensions() }
The backend state struct.
Contains all metadata needed to manage a terminal backend instance.
Functions
Marks the state as initialized.
This function is idempotent - calling it on an already initialized state has no effect.
Arguments
state- The current state struct
Examples
iex> state = State.new_tty(%{})
iex> state.initialized
false
iex> state = State.mark_initialized(state)
iex> state.initialized
true
Creates a new backend state with the given module and options.
Arguments
backend_module- The backend implementation moduleopts- Keyword list of options::backend_mode- Required. The terminal mode (:rawor:tty):backend_state- Optional. Backend-specific internal state:capabilities- Optional. Map of terminal capabilities (default:%{}):size- Optional. Cached dimensions as{rows, cols}(default:nil):initialized- Optional. Initialization status (default:false)
Examples
iex> State.new(MyBackend, backend_mode: :tty)
%State{backend_module: MyBackend, backend_mode: :tty, ...}
iex> State.new(MyBackend, backend_mode: :tty, capabilities: %{colors: :true_color})
%State{backend_module: MyBackend, backend_mode: :tty, capabilities: %{colors: :true_color}, ...}Raises
ArgumentErrorif:backend_modeis not provided in options
Creates a new raw mode backend state.
This is a convenience function that sets:
backend_moduletoTermUI.Backend.Rawbackend_modeto:rawcapabilitiesto%{}
Arguments
backend_state- Optional. Backend-specific internal state (default:nil)
Examples
iex> State.new_raw()
%State{backend_module: TermUI.Backend.Raw, backend_mode: :raw, ...}
iex> State.new_raw(%{raw_mode_started: true})
%State{backend_module: TermUI.Backend.Raw, backend_mode: :raw, backend_state: %{raw_mode_started: true}, ...}
Creates a new TTY mode backend state with the given capabilities.
This is a convenience function that sets:
backend_moduletoTermUI.Backend.TTYbackend_modeto:tty
Arguments
capabilities- Map of detected terminal capabilitiesbackend_state- Optional. Backend-specific internal state (default:nil)
Examples
iex> State.new_tty(%{colors: :color_256, unicode: true})
%State{backend_module: TermUI.Backend.TTY, backend_mode: :tty, capabilities: %{colors: :color_256, unicode: true}, ...}
iex> State.new_tty(%{colors: :true_color}, %{some: :state})
%State{backend_module: TermUI.Backend.TTY, backend_mode: :tty, capabilities: %{colors: :true_color}, backend_state: %{some: :state}, ...}
Updates the backend-specific state.
Arguments
state- The current state structbackend_state- The new backend-specific state value
Examples
iex> state = State.new_raw()
iex> state = State.put_backend_state(state, %{cursor: {1, 1}})
iex> state.backend_state
%{cursor: {1, 1}}
Updates the capabilities map.
Note: This replaces the entire capabilities map, it does not merge.
Arguments
state- The current state structcapabilities- The new capabilities map
Examples
iex> state = State.new_tty(%{colors: :basic})
iex> state = State.put_capabilities(state, %{colors: :true_color, unicode: true})
iex> state.capabilities
%{colors: :true_color, unicode: true}
@spec put_size(t(), dimensions()) :: t()
Updates the cached terminal dimensions.
Arguments
state- The current state structsize- The new size as{rows, cols}tuple ornil
Examples
iex> state = State.new_tty(%{})
iex> state = State.put_size(state, {24, 80})
iex> state.size
{24, 80}
iex> state = State.put_size(state, nil)
iex> state.size
nil