Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol lib raxol terminal emulator helpers.ex
Raw

lib/raxol/terminal/emulator/helpers.ex

defmodule Raxol.Terminal.Emulator.Helpers do
@moduledoc """
Utility and helper functions for the terminal emulator.
Extracted from the main emulator module for clarity and reuse.
"""
alias Raxol.Terminal.{ScreenBuffer, Cursor}
@spec get_config_struct(Raxol.Terminal.Emulator.t()) :: any()
def get_config_struct(%Raxol.Terminal.Emulator{config: pid})
when is_pid(pid) do
GenServer.call(pid, :get_state)
end
@spec get_window_manager_struct(Raxol.Terminal.Emulator.t()) :: any()
def get_window_manager_struct(%Raxol.Terminal.Emulator{window_manager: pid})
when is_pid(pid) do
GenServer.call(pid, :get_state)
end
@doc """
Gets the cursor struct from the emulator.
"""
@spec get_cursor_struct(Raxol.Terminal.Emulator.t()) :: Cursor.t()
def get_cursor_struct(%Raxol.Terminal.Emulator{cursor: cursor}) do
case is_pid(cursor) do
true ->
GenServer.call(cursor, :get_state)
false ->
cursor
end
end
@spec get_mode_manager_struct(Raxol.Terminal.Emulator.t()) :: any()
def get_mode_manager_struct(%Raxol.Terminal.Emulator{
mode_manager: mode_manager
}) do
mode_manager
end
@doc """
Gets the active buffer from the emulator.
"""
@spec get_screen_buffer(Raxol.Terminal.Emulator.t()) :: ScreenBuffer.t()
def get_screen_buffer(
%Raxol.Terminal.Emulator{active_buffer_type: :main} = emulator
),
do: emulator.main_screen_buffer
def get_screen_buffer(
%Raxol.Terminal.Emulator{active_buffer_type: :alternate} = emulator
),
do: emulator.alternate_screen_buffer
# Test helpers
def get_cursor_struct_for_test(
%Raxol.Terminal.Emulator{cursor: pid} = emulator
)
when is_pid(pid),
do: get_cursor_struct(emulator)
def get_mode_manager_struct_for_test(%Raxol.Terminal.Emulator{} = emulator),
do: get_mode_manager_struct(emulator)
def get_cursor_position_struct(
%Raxol.Terminal.Emulator{cursor: cursor} = emulator
) do
case is_pid(cursor) do
true ->
get_cursor_struct(emulator).position
false ->
# Handle non-pid cursor (e.g., in test environments)
case cursor do
%{position: position} -> position
%{col: col, row: row} -> {col, row}
_ -> {0, 0}
end
end
end
def get_cursor_visible_struct(
%Raxol.Terminal.Emulator{cursor: pid} = emulator
)
when is_pid(pid),
do: get_cursor_struct(emulator).visible
def get_mode_manager_cursor_visible(%Raxol.Terminal.Emulator{} = emulator),
do: get_mode_manager_struct(emulator).cursor_visible
@doc """
Gets the current cursor position.
Returns {row, col} for consistency with ANSI standards.
"""
@spec get_cursor_position(Raxol.Terminal.Emulator.t()) ::
{non_neg_integer(), non_neg_integer()}
def get_cursor_position(%Raxol.Terminal.Emulator{cursor: cursor} = emulator) do
case is_pid(cursor) do
true ->
cursor_struct = get_cursor_struct(emulator)
case cursor_struct do
# Already in {row, col} format
%{position: {row, col}} -> {row, col}
# Use row/col fields directly
%{row: row, col: col} -> {row, col}
_ -> {0, 0}
end
false ->
case cursor do
# Already in {row, col} format
%{position: {row, col}} -> {row, col}
# Use row/col fields directly
%{row: row, col: col} -> {row, col}
_ -> {0, 0}
end
end
end
end