--- phase: 02-vault-core-and-rendering plan: 01 subsystem: vault-and-highlighter tags: [cargo, dependencies, file-io, syntax-highlighting, cga-colors] dependency_graph: requires: [] provides: [vault-file-loading, syntect-initialization, cga-color-mapping, highlight-code] affects: [02-02-renderer, 02-03-app-integration] tech_stack: added: - pulldown-cmark 0.13.1 - syntect 5.3 (default-fancy, pure-Rust engine) - syntect-tui 3.0 patterns: - OnceLock for one-time syntect initialization - Euclidean RGB-to-CGA quantization - Owned String Spans for Vec> output key_files: created: - Cargo.toml (modified - 3 new deps added) - src/vault.rs - src/highlighter.rs modified: [] decisions: - "Used LinesWithNewlines iterator to preserve trailing \\n for syntect grammar correctness" - "Removed mod declarations from main.rs after compile verification - Plan 03 handles wiring" - "syntect-tui pulled onig_sys via transitive dep but cargo check succeeds cleanly" metrics: duration_seconds: 102 completed: 2026-02-28 tasks_completed: 2 files_changed: 3 --- # Phase 02 Plan 01: Vault Core and Highlighter Summary **One-liner:** pulldown-cmark/syntect/syntect-tui dependencies added with VaultDocument file-loading enum and OnceLock-based CGA-mapped syntax highlighter. ## What Was Built ### Task 1: Dependencies and vault file-loading module Added three new dependencies to `Cargo.toml`: - `pulldown-cmark = "0.13.1"` — markdown event parser - `syntect = { version = "5.3", default-features = false, features = ["default-fancy"] }` — syntax highlighting with pure-Rust regex engine - `syntect-tui = "3.0"` — bridge between syntect and ratatui Created `src/vault.rs` with: - `VaultDocument` enum: `Loaded { path, content }`, `Missing { path }`, `ReadError { path, reason }` - `load_document(vault_path: &Path, relative: &str) -> VaultDocument` using `std::fs::read_to_string` with proper `ErrorKind::NotFound` discrimination ### Task 2: Syntax highlighter module with CGA color mapping Created `src/highlighter.rs` with: - `static SYNTAX_SET: OnceLock` and `static THEME_SET: OnceLock` for one-time initialization - `init_highlighter()` — call once before `App::new()` - `syntax_set()` and `theme_set()` accessor functions with expect panics on uninitialized state - `syntect_color_to_cga(c: Color) -> ratatui::style::Color` — Euclidean distance RGB-to-CGA 16-color quantization across the full classic CGA palette - `highlight_code(code: &str, lang: &str) -> Vec>` — full pipeline: syntax lookup by token/name/fallback, `base16-ocean.dark` theme, per-line `HighlightLines::highlight_line()`, CGA color mapping, owned String Spans - `LinesWithNewlines` private iterator that preserves trailing `\n` per line for correct syntect grammar matching ## Verification 1. `cargo build` succeeds with all new dependencies (53 packages locked) 2. `src/vault.rs` contains `VaultDocument` enum with `Loaded`, `Missing`, `ReadError` variants 3. `src/vault.rs` contains `load_document()` function using `std::fs::read_to_string` 4. `src/highlighter.rs` contains `init_highlighter()`, `highlight_code()`, `syntect_color_to_cga()` 5. No changes to existing Phase 1 files (app.rs, main.rs, config.rs, signals.rs, terminal.rs) ## Deviations from Plan ### Auto-fixed Issues **1. [Rule 2 - Missing Critical Functionality] Added LinesWithNewlines iterator** - **Found during:** Task 2 - **Issue:** syntect's `highlight_line()` expects lines to include their trailing `\n` terminator so language grammars can match end-of-line anchors. Using `str::lines()` strips newlines, causing grammar state machine errors in some syntect definitions. - **Fix:** Added a private `LinesWithNewlines` iterator that yields substrings including the `\n` terminator, with correct handling for the final line without a trailing newline. - **Files modified:** src/highlighter.rs - **Commit:** 8d45a7c ## Commits | Hash | Task | Description | |------|------|-------------| | 7622d41 | Task 1 | feat(02-01): add Phase 2 deps and vault file-loading module | | 8d45a7c | Task 2 | feat(02-01): add syntax highlighter module with CGA color mapping | ## Self-Check: PASSED - [x] src/vault.rs exists and contains VaultDocument, load_document - [x] src/highlighter.rs exists and contains init_highlighter, syntect_color_to_cga, highlight_code - [x] Cargo.toml contains pulldown-cmark, syntect, syntect-tui - [x] Commits 7622d41 and 8d45a7c exist in git log - [x] cargo build succeeds