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 parser states dcs_passthrough_state.ex
Raw

lib/raxol/terminal/parser/states/dcs_passthrough_state.ex

defmodule Raxol.Terminal.Parser.States.DCSPassthroughState do
@moduledoc """
Handles the :dcs_passthrough state of the terminal parser.
"""
alias Raxol.Terminal.Emulator
alias Raxol.Terminal.Parser.State
require Raxol.Core.Runtime.Log
@behaviour Raxol.Terminal.Parser.StateBehaviour
@impl Raxol.Terminal.Parser.StateBehaviour
@doc """
Processes input when the parser is in the :dcs_passthrough state.
Collects the DCS data string until ST (ESC \).
"""
@spec handle(Emulator.t(), State.t(), binary()) ::
{:continue, Emulator.t(), State.t(), binary()}
| {:finished, Emulator.t(), State.t()}
| {:incomplete, Emulator.t(), State.t()}
def handle(
emulator,
%State{state: :dcs_passthrough} = parser_state,
input
) do
process_input(emulator, parser_state, input)
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_byte(_byte, emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_escape(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_control_sequence(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_osc_string(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_dcs_string(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_apc_string(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_pm_string(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_sos_string(emulator, state) do
{:ok, emulator, state}
end
@impl Raxol.Terminal.Parser.StateBehaviour
def handle_unknown(emulator, state) do
{:ok, emulator, state}
end
defp process_input(emulator, parser_state, <<>>) do
Raxol.Core.Runtime.Log.debug("[Parser] Incomplete DCS string, input ended.")
{:incomplete, emulator, parser_state}
end
defp process_input(emulator, parser_state, <<27, rest_after_esc::binary>>) do
Raxol.Core.Runtime.Log.debug(
"DCSPassthroughState: Found ESC, transitioning to dcs_passthrough_maybe_st with rest_after_esc=#{inspect(rest_after_esc)}"
)
{:continue, emulator, %{parser_state | state: :dcs_passthrough_maybe_st},
rest_after_esc}
end
defp process_input(emulator, parser_state, <<byte, rest_after_byte::binary>>)
when byte >= 0x20 and byte != 0x7F do
next_parser_state = %{
parser_state
| payload_buffer: parser_state.payload_buffer <> <<byte>>
}
{:continue, emulator, next_parser_state, rest_after_byte}
end
defp process_input(
emulator,
parser_state,
<<abort_byte, rest_after_abort::binary>>
)
when abort_byte == 0x18 or abort_byte == 0x1A do
Raxol.Core.Runtime.Log.debug("Aborting DCS Passthrough due to CAN/SUB")
next_parser_state = %{parser_state | state: :ground}
{:continue, emulator, next_parser_state, rest_after_abort}
end
defp process_input(
emulator,
parser_state,
<<_ignored_byte, rest_after_ignored::binary>>
) do
Raxol.Core.Runtime.Log.debug("Ignoring C0/DEL byte in DCS Passthrough")
{:continue, emulator, parser_state, rest_after_ignored}
end
end