Class TerminalInput
Read decoded InputEvents from stdin. Pair with RawMode so the terminal actually delivers bytes instead of cooked, line-buffered input.
public static class TerminalInput
- Inheritance
-
TerminalInput
- Inherited Members
Remarks
Maintains a small UTF-8 byte buffer and a parser char buffer between calls so escape sequences split across reads still parse correctly. All state is process-global because stdin is.
On Unix, TryReadEvent(out InputEvent) uses poll(2) with timeout 0
to check for available bytes without blocking. On Windows the
underlying WaitForSingleObject is best-effort: a console
handle becomes signaled on any input event (including key-up events
that produce no VT bytes), so an occasional false positive followed
by a short blocking ReadFile is possible. For strict
non-blocking semantics on Windows, run ReadEvent() on a
background thread and post events to your main loop yourself.
Methods
ReadEvent()
Block until one InputEvent can be parsed, then return it. Throws EndOfStreamException if stdin closes before any further event arrives.
public static InputEvent ReadEvent()
Returns
TryReadEvent(out InputEvent)
Try to return the next event without blocking. Returns
false when no complete event is currently buffered AND no
new bytes are available (or stdin is at EOF).
public static bool TryReadEvent(out InputEvent ev)
Parameters
evInputEvent
Returns
WaitForEvent(int, out InputEvent)
Wait up to timeoutMs milliseconds for an
event. Returns true when an event was decoded, false
when the timeout expires or stdin reaches EOF. Pass 0 for
a strictly non-blocking poll, or a negative number to wait
indefinitely (equivalent to ReadEvent() minus the
EOF exception).
public static bool WaitForEvent(int timeoutMs, out InputEvent ev)
Parameters
timeoutMsintevInputEvent
Returns
Remarks
Resolves the classic ESC-vs-CSI ambiguity: a lone 0x1b
byte could be the user pressing Escape OR the start of a still-
arriving cursor / function key sequence, so the parser stays
optimistic and reports Incomplete. After a non-zero
timeoutMs wait that delivered no follow-up
bytes, this method commits the buffered ESC as a real Escape
keypress — otherwise apps that bind Escape (modal close, menu
dismiss) would feel stuck until the next keystroke nudged the
parser forward.