1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
// Copyright (c) 2025 R3BL LLC. Licensed under Apache License, Version 2.0.
//! ANSI Terminal Abstraction Layer
//!
//! This module provides bidirectional ANSI sequence handling for terminal emulation:
//!
//! ## Key Subsystems
//!
//! - **Output Parser** (VTE-based): Parse incoming PTY output (ANSI sequences from child
//! processes) → terminal state updates → [`OffscreenBuffer`] storage (via
//! [`vt_100_pty_output_parser`] and [`AnsiToOfsBufPerformer`])
//! - **Input Parser** (custom): Parse terminal input (keyboard/mouse) → structured
//! [`VT100InputEventIR`] → application logic (via [`vt_100_terminal_input_parser`])
//! - **Generator**: Convert application styling → outgoing ANSI sequences → real terminal
//! display (via [`RenderOpOutput`], [`SgrCode`], [`CliTextInline`])
//! - **Constants & Color**: Shared ANSI specifications - color types (RGB ↔ ANSI256),
//! escape sequence definitions, used by all subsystems
//!
//! ## Architecture Overview
//!
//! ```text
//! PTY Output (child process) User Input (keyboard/mouse)
//! │ │
//! │ │
//! ┌──────────▼───────────────┐ ┌──────────▼───────────────────┐
//! │ VTE Output Parser │ │ Custom Input Parser │
//! │ vt_100_pty_output_parser │ │ vt_100_terminal_input_parser │
//! └──────────┬───────────────┘ └──────────┬───────────────────┘
//! │ │
//! ▼ ▼
//! Terminal State Updates VT100InputEventIR
//! (cursor/color/text changes) (keyboard/mouse/terminal)
//! │ │
//! ┌────────▼─────────┐ ┌──────▼───────┐
//! │ OffscreenBuffer │ │ Application │
//! │ (emulator state) │ │ Logic │
//! └──────────────────┘ └──────┬───────┘
//! │
//! ┌──────▼───────────┐
//! │ Generator │
//! │ • RenderOpOutput│
//! │ • SgrCode │
//! │ • CliText │
//! └──────┬───────────┘
//! │
//! ▼
//! ANSI Sequences
//! │
//! ▼
//! Real Terminal
//! (stdout display)
//!
//! ┌─────────────────────────────────────┐
//! │ Constants & Color (ANSI specs) │ ← Shared by all components
//! │ • Color types (RGB ↔ ANSI256) │
//! │ • Escape sequence definitions │
//! └─────────────────────────────────────┘
//! ```
//!
//! ## Terminal Input Modes: Raw vs Cooked
//!
//! To understand why this module exists, you need to know how terminals handle input.
//!
//! ### Cooked Mode (Default)
//!
//! This is the **default terminal mode** when you open a shell:
//!
//! ```text
//! You type: "hello^H^H" (^H = backspace key)
//! ↓
//! OS processes: character buffering, line editing, special key handling
//! ↓
//! Program gets: "hel" (only after Enter, with backspace processed)
//! ```
//!
//! The OS handles input processing: backspace deletes, Ctrl+C terminates the program,
//! Enter sends the line. The program only receives complete lines.
//!
//! ### Raw Mode (Interactive TUI)
//!
//! Interactive applications (vim, less, this R3BL TUI crate) need
//! **character-by-character input**:
//!
//! ```text
//! You press: [individual keystroke]
//! ↓
//! OS processing: [NONE - raw bytes sent immediately]
//! ↓
//! Program gets: raw keystroke immediately
//! (including escape sequences for arrow keys, Ctrl+C, etc.)
//! ```
//!
//! **Why raw mode?** The program needs to:
//! - Capture every keystroke immediately (no line buffering)
//! - Distinguish between Ctrl+C (user interrupt) vs. Ctrl+C keypress the user wants
//! - Detect special keys (arrows, function keys) sent as **escape sequences**
//! - Control the cursor, colors, and screen layout
//!
//! ### Escape Sequences in Raw Mode
//!
//! When a user presses a special key in raw mode, the terminal sends an **escape
//! sequence**. For example:
//!
//! ```text
//! User presses: Up arrow
//! Terminal sends: ESC [ A (3 bytes: 0x1B 0x5B 0x41)
//! Displayed as: ^[[A (when using cat -v to visualize)
//! ```
//!
//! Use `cat -v` to see raw escape sequences:
//!
//! ```text
//! $ cat -v # cat with visualization of control characters
//! # [user types: "hello" then Up arrow then Left arrow]
//! hello^[[A^[[D
//! # ^[ is the Escape character (ESC, 0x1B)
//! # [A is "cursor up"
//! # [D is "cursor left"
//! ```
//!
//! **Common escape sequences:**
//! - `^[[A` = Up arrow
//! - `^[[B` = Down arrow
//! - `^[[C` = Right arrow
//! - `^[[D` = Left arrow
//! - `^[[3~` = Delete key
//! - `^[OP` = F1 key
//!
//! ## Two Separate Parsers: Why?
//!
//! This module contains **two distinct parsers** that handle different data streams:
//!
//! ### Output Parser: VTE-based ([`vt_100_pty_output_parser`])
//!
//! **What it does**: Parses ANSI escape sequences sent TO the terminal by child
//! processes (via the PTY master).
//!
//! **Architecture**: Uses the [VTE crate] - a battle-tested state machine from the
//! Alacritty terminal emulator project.
//!
//! **Why stateful parsing?** PTY output is **non-atomic**. Child processes can write
//! partial sequences that span multiple buffer reads:
//! ```text
//! PTY Read 1: [0x1B, 0x5B, 0x31] // ESC [ 1
//! PTY Read 2: [0x3B, 0x35, 0x41] // ; 5 A
//! Complete: ESC[1;5A (Ctrl+Up Arrow)
//! ```
//!
//! VTE handles this by maintaining parse state across `advance()` calls, buffering
//! incomplete parameters until the final sequence byte arrives.
//!
//! **Benefits**:
//! - ✅ Robust state machine for split sequences and edge cases
//! - ✅ Battle-tested in production (Alacritty uses it)
//! - ✅ Proper ANSI/VT-100 spec compliance
//! - ✅ Low maintenance (bug fixes come from upstream)
//!
//! ### Input Parser: Custom Implementation ([`vt_100_terminal_input_parser`])
//!
//! **What it does**: Parses terminal input events (keyboard, mouse, terminal
//! resize/focus) sent FROM the user TO the application.
//!
//! **Architecture**: Custom Rust implementation using stateless pattern matching.
//!
//! **Why NOT use VTE?** Terminal input has fundamentally different characteristics:
//!
//! 1. **Atomic sequences**: Terminal emulators send input sequences **complete** in
//! single writes:
//! ```text
//! User presses: Up Arrow
//! Terminal sends: "\x1B[A" (3 bytes in one syscall)
//! stdin read(): [0x1B, 0x5B, 0x41] (always complete)
//! ```
//!
//! 2. **Different event types**: VTE cannot parse keyboard/mouse events - it's
//! designed for output sequences only. Input events require custom parsing logic:
//! - `ESC[A` = User pressed Up Arrow (not "move cursor up")
//! - `ESC[<0;10;20M` = Mouse click at (10,20)
//! - `ESC[?1049h` = Terminal entered alternate buffer mode
//!
//! 3. **Simpler logic**: Input patterns are predictable - no need for full state
//! machine overhead
//!
//! **Benefits**:
//! - ✅ Zero-latency ESC key detection (instant emit when buffer = `[0x1B]`)
//! - ✅ Optimal for atomic sequences (no buffering overhead)
//! - ✅ Full control over parsing logic
//! - ✅ Can optimize for specific terminal features (SGR mouse, Kitty etc.)
//!
//! **Key insight**: The architectural split (VTE for output, custom for input) is
//! **not a limitation** - it's the correct design because output and input are
//! fundamentally different problems requiring different solutions.
//!
//! ## Key Types and Public API
//!
//! **Color System:**
//! - `TuiColor` - Terminal color with RGB and ANSI256 support
//! - [`RgbValue`], [`AnsiValue`] - Color value types
//!
//! **Text Styling:**
//! - [`SgrCode`] - SGR (Select Graphic Rendition) styling codes
//! - [`CliTextInline`] - Styled inline text for output
//!
//! **Output Parsing** (PTY escape sequences):
//! - [`AnsiToOfsBufPerformer`] - VTE Perform trait implementation for PTY parsing
//! - [`CsiSequence`] - CSI escape sequence types
//!
//! **Input Parsing** (keyboard/mouse events):
//! - `VT100InputEventIR` - Keyboard, mouse, and terminal events (see [`vt_100_terminal_input_parser`])
//! - `VT100KeyCodeIR` - Keyboard event key codes
//!
//! **Terminal I/O:**
//! - Color detection and support queries
//!
//! [VTE crate]: https://docs.rs/vte/latest/vte/
//! [`CliTextInline`]: crate::core::ansi::CliTextInline
//! [`OffscreenBuffer`]: crate::OffscreenBuffer
//! [`RenderOpOutput`]: crate::RenderOpOutput
//! [`SgrCode`]: crate::core::ansi::SgrCode
//! [`VT100InputEventIR`]: crate::core::ansi::vt_100_terminal_input_parser::VT100InputEventIR
//! [`vt_100_pty_output_parser`]: mod@crate::core::ansi::vt_100_pty_output_parser
//! [`vt_100_terminal_input_parser`]: mod@crate::core::ansi::vt_100_terminal_input_parser
// XMARK: rustfmt prevent from reformatting entire file.
// Skip rustfmt for rest of file.
// https://stackoverflow.com/a/75910283/2085356
// Private modules.
// Module is public only when building documentation or tests.
// This allows rustdoc links to work while keeping it private in release builds.
// Module is public only when building documentation or tests.
// This allows rustdoc links to work while keeping it private in release builds.
// This module is private in non-test, non-doc builds.
// XMARK: Example for how to conditionally expose private modules for testing and documentation.
// Module is public only when building documentation or tests.
// This allows rustdoc links to work while keeping it private in release builds.
// This module is private in non-test, non-doc builds.
// Input parsing module - public for protocol access
// Re-export flat public API.
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
pub use *;
// Re-export test fixtures for testing purposes only.
pub use vt_100_pty_output_conformance_tests;