This module parses raw terminal byte streams into structured events: keyboard input with modifiers, mouse actions, scroll wheel, bracketed paste, terminal resize, and focus tracking. Capability responses (device attributes, mode reports, cursor position) are separated into their own stream.
The module handles multiple terminal protocols transparently: Kitty keyboard protocol, SGR and URXVT mouse tracking, X10/Normal mouse tracking, bracketed paste, and OSC 52 clipboard responses.
Event model
The event type t covers user-facing input. Capability responses are reported separately as Caps.event values so applications can handle input and capability detection independently.
let p = Input.Parser.create () in
Input.Parser.feed p buf 0 len ~now ~on_event:handle_event
~on_caps:handle_caps
Escape sequences may arrive fragmented across reads; the parser buffers partial sequences until they complete or time out. Ambiguous sequences (lone Escape vs. Alt+key) use a 50ms timeout; clearly incomplete sequences (CSI, OSC) use 100ms. Call Parser.drain after Parser.deadline to emit pending events.
Warning. The parser is not thread-safe; use one instance per input source.
Key bindings
Keymap maps key combinations to application commands:
let km =
Input.Keymap.empty
|> Input.Keymap.add_char ~ctrl:true 'q' `Quit
|> Input.Keymap.add Input.Key.Enter `Submit
in
match Input.Keymap.find km event with
| Some `Quit -> exit 0
| Some `Submit -> submit ()
| None -> ()
Scroll (x, y, dir, delta, mods) is a scroll wheel event at (x, y) with direction dir, step delta (usually 1), and modifiers mods. Coordinates are 0-based. Normalizes wheel actions across terminal protocols (SGR, URXVT, X10) into a single event.
*)
| Resizeof int * int
(*
Resize (width, height) is a terminal resize.
*)
| Focus
(*
Terminal gained focus.
*)
| Blur
(*
Terminal lost focus.
*)
| Pasteof string
(*
Paste text is bracketed paste content with ANSI escape sequences stripped. Empty payloads are dropped by the parser.
*)
| Clipboardof string * string
(*
Clipboard (selection, data) is an OSC 52 clipboard response. data is base64-decoded when possible, verbatim otherwise.
*)
| Oscof int * string
(*
Osc (number, payload) is an unhandled OSC sequence. payload is the raw text between introducer and terminator with no sanitization.
equal a b is true iff a and b are semantically equal.
For Key events only the key and modifier fields are compared; event_type, associated_text, shifted_key and base_key are ignored. All other variants compare fields structurally.
equal_full a b is true iff all fields of a and b are structurally equal. Unlike equal, this compares all fields of Key events including event_type and associated_text.