InputSourceTerminal input.
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.
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.
Create a Parser and feed it raw terminal bytes:
let p = Input.Parser.create () in
Input.Parser.feed p buf 0 len ~now ~on_event:handle_event
~on_caps:handle_capsEscape 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.
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 -> ()type t = | Key of Key.eventKeyboard input.
*)| Mouse of Mouse.eventMouse button or motion.
*)| Scroll of int * int * Mouse.scroll_direction * int * Key.modifierScroll (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.
| Resize of int * intResize (width, height) is a terminal resize.
| FocusTerminal gained focus.
*)| BlurTerminal lost focus.
*)| Paste of stringPaste text is bracketed paste content with ANSI escape sequences stripped. Empty payloads are dropped by the parser.
| Clipboard of string * stringClipboard (selection, data) is an OSC 52 clipboard response. data is base64-decoded when possible, verbatim otherwise.
| Osc of int * stringOsc (number, payload) is an unhandled OSC sequence. payload is the raw text between introducer and terminator with no sanitization.
The type for terminal input events.
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.
See equal_full for full structural equality.
pp formats events for debugging.
val key :
?modifier:Key.modifier ->
?event_type:Key.event_type ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
Key.t ->
tkey k is Key (Key.make k) with the given optional arguments. See Key.make for defaults.
val char :
?modifier:Key.modifier ->
?event_type:Key.event_type ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
char ->
tchar c is Key (Key.of_char c) with the given optional arguments. See Key.of_char for defaults.
val key_event :
?modifier:Key.modifier ->
?event_type:Key.event_type ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
Key.t ->
Key.eventval char_event :
?modifier:Key.modifier ->
?event_type:Key.event_type ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
char ->
Key.eventchar_event c is Key.of_char c.
val press :
?modifier:Key.modifier ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
Key.t ->
Key.eventpress k is Key.make ~event_type:Press k.
val repeat :
?modifier:Key.modifier ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
Key.t ->
Key.eventrepeat k is Key.make ~event_type:Repeat k.
val release :
?modifier:Key.modifier ->
?associated_text:string ->
?shifted_key:Uchar.t ->
?base_key:Uchar.t ->
Key.t ->
Key.eventrelease k is Key.make ~event_type:Release k.
mouse_press x y button is Mouse (Button_press (x, y, button, modifier)). modifier defaults to Key.no_modifier.
mouse_release x y button is Mouse (Button_release (x, y, button, modifier)). modifier defaults to Key.no_modifier.
mouse_motion x y state is Mouse (Motion (x, y, state, modifier)). modifier defaults to Key.no_modifier.
match_ctrl_char e is Some c when e is a Key event with modifier.ctrl = true and the key is an ASCII Char (code point < 0x80). None otherwise.
is_drag e is true iff e is a Mouse Motion event with at least one primary button pressed.