You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Buffer & Display Subsystems form the foundational data management and presentation layers of the CmdTextC terminal-based text editor. Implemented in pure C99, these modules provide a robust, high-performance architecture for in-memory text storage, dynamic row manipulation, syntax highlighting buffer allocation, coordinate translation, snapshot-based undo/redo, and ANSI terminal rendering. The buffer module handles raw character storage, tab expansion, render string generation, and state persistence. The display module manages viewport scrolling, cursor positioning, syntax-aware color emission, status/messaging bars, and direct terminal I/O via optimized buffer construction. Together, they deliver a deterministic, zero-external-dependency editing core optimized for fast interactive sessions and predictable memory behavior.
2. System Architecture & Design Philosophy
Design Principle
Implementation Strategy
Dual-Buffer Row Model
Each EditorRow maintains chars (raw input) and render (tab-expanded display). Separation ensures editing precision while guaranteeing accurate visual alignment.
Highlight Array Decoupling
Syntax highlighting is stored in a parallel unsigned char *hl array matching render length. Rendering loop applies ANSI codes dynamically without mutating text data.
Snapshot-Based History
Undo/Redo captures deep copies of the entire buffer state. Trade-off: higher memory footprint for O(1) rollback complexity and complete state fidelity.
Terminal-Optimized Rendering
Constructs a contiguous ANSI-encoded string buffer (screenbuf[64KB]) in memory before a single termWrite() syscall. Minimizes I/O latency and terminal flicker.
Viewport-Centric Scrolling
Calculates rowoff/coloff dynamically against terminal dimensions. Guarantees cursor visibility while preserving edit position integrity.
Strict Lifecycle Management
Explicit calloc/malloc/free patterns. Zero global mutable state. All resources tied to EditorBuffer or EditorDisplay structs.
3. Core Data Structures
3.1 EditorRow
typedefstruct {
intsize; // Raw character count in chars[]char*chars; // Raw input buffer (includes '\t', raw newlines excluded)char*render; // Display buffer (tabs expanded to spaces)intrsize; // Rendered character countunsigned char*hl; // Parallel highlight array (1 byte per render char)inthl_open_comment; // Cross-row multiline comment state (0/1)intidx; // Row index in bufferTabStop*tabs; // Dynamic array tracking tab stop positions & lengthsinttab_count; // Active tab stopsinttab_cap; // Allocated tab stop capacity
} EditorRow;
Dual-Storage Rationale:chars preserves exact user input for serialization. render normalizes whitespace for terminal alignment and syntax token mapping.
Highlight Mapping:hl[i] stores an HlColor enum value corresponding to render[i]. Enables per-character ANSI coloring without string duplication.
3.2 EditorBuffer
typedefstruct {
EditorRow*rows; // Dynamic array of row structsintcount; // Current active rowsintcapacity; // Allocated row capacityintdirty; // Modification flag (triggers save prompt)char*filename; // Associated file pathintnum_undo; // Active undo states in stackUndoState*undo_stack; // Fixed-size circular stack (256)inttab_size; // Tab expansion width (default: 4)
} EditorBuffer;
Dynamic Growth: Initial capacity 128. Doubles via realloc when count == capacity.
Undo Stack: Pre-allocated 256 slots. Oldest state discarded when full.
3.3 UndoState
typedefstruct {
intlast_cx, last_cy, last_action;
EditorRow*rows; // Deep-copied row snapshotintrow_count; // Number of rows in snapshotchar*msg; // Contextual message prefixcharmsg_prefix;
long longsaved_msgs; // Reserved for message history
} UndoState;
Deep Copy Semantics: Captures chars, render, hl, and tabs for every row at time of action.
Restoration Logic: Frees current buffer state, reallocates from snapshot, restores cursor position.
3.4 EditorDisplay
typedefstruct {
introwoff, coloff; // Viewport scroll offsets (top row, left column)intcx, cy, rx; // Cursor position: raw index, row index, render indexintmode; // Editor mode (0=NORMAL, 1=INSERT, 2=COMMAND, etc.)charstatusmsg[256]; // Transient status messagetime_tstatusmsg_time; // Message timestamp for auto-expiryintsearch_hit; // Current search match indexintsearch_dir; // Search direction (1=forward, -1=backward)intshow_line_numbers; // Toggle line number renderingintwrap_lines; // Line wrapping flag (reserved)
} EditorDisplay;