Skip to main content

Atomic VTE Parser

The Atomic VTE Parser wraps Alacritty’s battle-tested VTE parser to process ANSI escape sequences with fast native performance.

Overview

┌─────────────────────────────────────────────────────────────────────┐
│               ATOMIC VTE PARSER IN MONOLEX                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   PTY Output (raw bytes + ANSI)                                     │
│       │                                                             │
│       ▼                                                             │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │  AlacrittyRenderer                                          │   │
│   │                                                             │   │
│   │  ┌──────────────────┐    ┌──────────────────────────────┐   │   │
│   │  │  AtomicParser    │───→│  alacritty_terminal::Term    │   │   │
│   │  │  BSU/ESU detect  │    │  VTE Parser + Grid State     │   │   │
│   │  └──────────────────┘    └──────────────────────────────┘   │   │
│   │                                   │                         │   │
│   │                                   ▼                         │   │
│   │                          ┌──────────────────┐               │   │
│   │                          │  CellConverter   │               │   │
│   │                          │  Alacritty→xterm │               │   │
│   │                          └──────────────────┘               │   │
│   │                                   │                         │   │
│   └───────────────────────────────────│─────────────────────────┘   │
│                                       ▼                             │
│   GridUpdate { viewport, scrollback, cursor, epoch }                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Why Alacritty?

Aspectxterm.js ParserAlacritty Parser
LanguageJavaScriptRust
PerformanceInterpretedNative
MemoryGC overheadZero-copy
Test CoverageGoodExcellent (1000+)
ANSI SupportStandardExtensive
CJK SupportBasicFull

Core Components

AlacrittyRenderer

Wrapper around Alacritty’s Term:
┌─────────────────────────────────────────────────────────────────┐
│  ALACRITTY RENDERER STRUCTURE                                   │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  AlacrittyRenderer:                                             │
│  ├── term           Alacritty Term instance                     │
│  ├── size           Current terminal dimensions                 │
│  ├── dirty_lines    Set of changed row indices                  │
│  └── request_full   Flag for full update needed                 │
│                                                                 │
│  new(cols, rows):                                               │
│  ─────────────────                                              │
│  1. Create TermSize with dimensions                             │
│  2. Initialize Alacritty Term                                   │
│  3. Set initial dirty state                                     │
│                                                                 │
│  process(data) → Option<GridUpdate>:                            │
│  ───────────────────────────────────                            │
│  1. Feed each byte to Alacritty VTE parser                      │
│  2. Mark dirty lines based on changes                           │
│  3. If should emit:                                             │
│       → Return GridUpdate                                       │
│     Else:                                                       │
│       → Return None                                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

AtomicParser

Detects BSU/ESU (Begin/End Synchronized Update) sequences:
┌─────────────────────────────────────────────────────────────────┐
│  ATOMICPARSER - BSU/ESU DETECTION                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  AtomicParser:                                                  │
│  ├── state      Normal | InAtomicBlock                          │
│  └── data       Accumulated bytes                               │
│                                                                 │
│  process(data) → ProcessResult:                                 │
│  ──────────────────────────────                                 │
│  For each byte:                                                 │
│       │                                                         │
│       ├── [Normal state]                                        │
│       │   Is BSU detected?                                      │
│       │     → YES: Switch to InAtomicBlock                      │
│       │                                                         │
│       └── [InAtomicBlock state]                                 │
│           Is ESU detected?                                      │
│             → YES: Return AtomicBlockComplete                   │
│                    Reset to Normal state                        │
│                                                                 │
│  BSU/ESU SEQUENCES:                                             │
│  ─────────────────                                              │
│  BSU: ESC [ ? 2026 h   (Begin Synchronized Update)              │
│  ESU: ESC [ ? 2026 l   (End Synchronized Update)                │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

CellConverter

Converts Alacritty cells to xterm.js format:
┌─────────────────────────────────────────────────────────────────┐
│  CELL CONVERTER                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  convert_cell(Alacritty Cell) → xterm Cell:                     │
│  ──────────────────────────────────────────                     │
│  Input:                                                         │
│  ├── Character (Unicode)                                        │
│  ├── Foreground color                                           │
│  ├── Background color                                           │
│  └── Flags (bold, italic, wide, etc.)                           │
│                                                                 │
│  Output (3 × 32-bit values):                                    │
│  ├── Content slot   (codepoint + width)                         │
│  ├── Foreground slot (color + mode + flags)                     │
│  └── Background slot (color + mode + flags)                     │
│                                                                 │
│  CONTENT ENCODING:                                              │
│  ─────────────────                                              │
│  ┌────────────────────────────────────────┐                     │
│  │ codepoint [0:20] │ combined │ width    │                     │
│  │    21 bits       │  1 bit   │ 2 bits   │                     │
│  └────────────────────────────────────────┘                     │
│                                                                 │
│  COLOR ENCODING:                                                │
│  ───────────────                                                │
│  ┌────────────────────────────────────────┐                     │
│  │ color [0:23] │ mode [24:25] │ flags    │                     │
│  │   24 bits    │    2 bits    │ 6 bits   │                     │
│  └────────────────────────────────────────┘                     │
│                                                                 │
│  Color Modes:                                                   │
│  ├── Named    (0-15)   → 16-color palette                       │
│  ├── Indexed  (16-255) → 256-color palette                      │
│  └── RGB      (24-bit) → True color                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

GridUpdate Structure

The output of AlacrittyRenderer:
┌─────────────────────────────────────────────────────────────────┐
│  GRIDUPDATE STRUCTURE                                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  GridUpdate:                                                    │
│  ├── viewport          Visible area cells (2D array)            │
│  ├── scrollback        History cells (2D array)                 │
│  │                                                              │
│  ├── cursor_x          Cursor column position                   │
│  ├── cursor_y          Cursor row position                      │
│  ├── cursor_visible    Whether cursor is visible                │
│  │                                                              │
│  ├── epoch             Synchronization counter                  │
│  ├── scrollback_lines  Number of history lines                  │
│  │                                                              │
│  ├── dirty_lines       List of changed row indices              │
│  └── is_full_update    Whether full redraw needed               │
│                                                                 │
│  DATA FLOW:                                                     │
│  ──────────                                                     │
│  Alacritty Grid → CellConverter → GridUpdate → Frontend         │
│                                                                 │
│  DIRTY TRACKING:                                                │
│  ───────────────                                                │
│  is_full_update = true  → Send all rows                         │
│  is_full_update = false → Send only dirty_lines                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Dirty Tracking

Only emit changed lines for efficiency:
┌─────────────────────────────────────────────────────────────────────┐
│               DIRTY TRACKING                                        │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   Full Grid (40 rows):                                              │
│   ┌─────────────────────────────────────────────────────────────┐   │
│   │ Row 0:  unchanged                                           │   │
│   │ Row 1:  unchanged                                           │   │
│   │ Row 2:  DIRTY ← cursor moved here                           │   │
│   │ Row 3:  DIRTY ← new text written                            │   │
│   │ Row 4:  unchanged                                           │   │
│   │ ...                                                         │   │
│   │ Row 39: unchanged                                           │   │
│   └─────────────────────────────────────────────────────────────┘   │
│                                                                     │
│   GridUpdate.dirty_lines = [2, 3]                                   │
│   GridUpdate.is_full_update = false                                 │
│                                                                     │
│   → Only rows 2, 3 sent to frontend                                 │
│   → Significant bandwidth reduction                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Wide Character Handling

CJK characters (한글, 日本語, 中文) occupy 2 cells:
"한" (Korean character, width=2)

Cell Layout:
┌─────────────┬─────────────┐
│ Col 0       │ Col 1       │
│ "한"        │ (spacer)    │
│ width=2     │ WIDE_CHAR_  │
│ WIDE_CHAR   │ SPACER      │
└─────────────┴─────────────┘

Content Encoding:
Main cell:
  content = (0xD55C) | (0 << 21) | (2 << 22)
          = codepoint | combined_flag | width

Spacer cell:
  content = 0 (empty, WebGL handles spacing)

Performance Characteristics

OperationDescription
VTE parsingFast native Rust processing
Cell conversionDirect format conversion
Dirty trackingEfficient change detection
OverallFaster than JavaScript parser
The native Rust implementation provides faster parsing compared to JavaScript-based alternatives.

Key Components

┌─────────────────────────────────────────────────────────────────┐
│  ALACRITTY RENDERER COMPONENTS                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Component          Purpose                                     │
│  ─────────────────  ────────────────────────────────────────    │
│  VTE Renderer       Term wrapper, dirty tracking                │
│  AtomicParser       BSU/ESU detection                           │
│  Cell Converter     Alacritty→xterm format conversion           │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

SMPC/OFAC Applied

PrincipleApplication
SMPCSingle purpose: VTE parsing only
Clean interface: process() → GridUpdate
No rendering logic (that’s xterm’s job)
OFACDirty tracking emerged from performance need
AtomicParser emerged from BSU/ESU requirement
Cell format emerged from xterm.js internals