TermUI.Input.TTY.Server (TermUI v1.0.0)
View SourceGenServer that manages IEx-compatible TTY input using a separate process.
This server spawns a separate process that continuously polls for input using
:io.get_chars/2. This approach lets TUI applications read through the
active IEx IO server without replacing its shell. Because the terminal stays
in cooked mode, delivery may still be buffered until Enter.
This is a standalone alternative and is not used by TermUI.Runtime, which
runs TermUI.Input.TTY.poll/2 in its own dedicated reader process.
Architecture
The server manages a spawned process that:
- Continuously polls with
receive after 0for non-blocking behavior - Calls
:io.get_chars("", 1)to read single characters - Parses escape sequences and converts charlists to binaries
- Sends parsed key events as messages to the server
The server maintains:
- A queue of parsed events waiting to be delivered
- The original IO options (for restoration on shutdown)
- The spawned input process PID
Usage
{:ok, server} = TermUI.Input.TTY.Server.start_link(receiver: self())
{:ok, event} = TermUI.Input.TTY.Server.poll(server)
:ok = TermUI.Input.TTY.Server.stop(server)IO Server Configuration
The server configures the IO server on startup:
- Saves original options via
:io.getopts/0 - Sets
echo: falseto disable character echo - Sets
binary: falseso:io.get_chars/2returns charlists
On termination, it restores the original options.
Summary
Functions
Returns a specification to start this module under a supervisor.
Polls for a key event.
Returns the current event queue size.
Starts the TTY input server.
Stops the TTY input server.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
Polls for a key event.
Returns the next queued event. The timeout argument is retained for API
compatibility but is not used to wait; callers receive {:error, :no_event}
immediately while the reader is alive and the queue is empty.
Returns
{:ok, event}- A key event was received{:error, :eof}- End of input stream{:error, :no_event}- Reader is alive but no event is queued
Examples
case TermUI.Input.TTY.Server.poll(server) do
{:ok, %Event.Key{} = event} -> handle_key(event)
{:error, :no_event} -> try_again_later()
{:error, :eof} -> handle_shutdown()
end
Returns the current event queue size.
Starts the TTY input server.
Options
:receiver- PID to receive{:input_event, event}messages. Supply this when using push delivery; omitting it is only safe if no input will arrive before shutdown.:name- Name for GenServer registration (optional)
Examples
{:ok, server} = TermUI.Input.TTY.Server.start_link(receiver: some_pid)
Stops the TTY input server.