Review editor UI reference documentation

token-editor
master
Smart (Opus 4.5)
Unlisted
review @EDITOR_UI_REFERENCE.md for accuracy and quality/correctness etc, consult oracle put findings in AMP_REPORT.md

Created AMP_REPORT.md with the oracle's findings. Key issues:

  • Off-by-one errors in viewport line calculations
  • Division by zero risks in scroll formulas
  • Semantic mismatch: preferredColumn defined as column but used as pixel X
  • Inconsistent naming: Selection uses anchor/head but code references start/end
  • Missing coverage: folding+wrapping integration, BiDi, IME composition
yes, do a pass of the document and fix the things you mentioned and standardize the terms and units used thruoughout, note for the sake of the use-case this covers, we are working primarily with code editing with monospace font, want to support utf8 etc and perhaps better then to commit to codepoints etc out of the gate, but if it requires large changes to everything, skip it and add a footnote/section about why/how/gotchas/theory etc, note we dont care about non-latin languages or chinese input methods, also note that this is primarily not meant for "web", target audience is desktop software and not webapps (rust, go, c++ etc), a clarification about preferredColumn: it makes sense for this to be represented by a column integer and not pixels as it is used to track the last "column position" the cursor was at if you do a page up/down jump to a row that has more/less number of columns, so that when you "jump back", it will still "jump back" to the previous column index for the line, this is very useful for intuative navigation across codeblocks etc, another thing we do not need to support is right-to-left text direction, only standard left to right diurection will be supported for simplicity, but feel free to add a seperate sction xplaining the theory, some guidance on data structs and changes to the logic/math that this introduces and how to retro-fit it into an existing system, also feel free to add a section on "cursors: pipe, block or underline" and how those styles of cursor representations differ in terms of how you need to compute their positioning, rendering etc.
Created EDITOR_UI_REFERENCE.md
continue?
Created EDITOR_UI_REFERENCE.md
you need to split it up in multiple sections or else it will be too big, do it chapter by chapter (chatper1.md) and cat them together afterwards

Done! Updated EDITOR_UI_REFERENCE.md (3,245 lines). Key changes:

Fixes:

  • Scrollable extent now uses max(0, ...)
  • Added division-by-zero guards for scroll/thumb formulas
  • Fixed off-by-one in visible line calculations (now uses lastVisibleExclusive semantics)
  • Added log10(0) guard in computeLineNumberWidth
  • Added scroll clamping throughout

Standardization:

  • preferredColumn is now clearly a column integer (not pixels)
  • Selection uses start/end/direction consistently
  • ScrollMargins explicitly: lines (vertical), columns (horizontal)
  • All visible ranges use [firstInclusive, lastExclusive) half-open intervals

New content:

  • Chapter 12: Cursor styles (pipe/block/underline) with geometry, rendering, and vim-mode notes
  • Appendix E: UTF-8/Unicode for code editors (practical approach)
  • Appendix F: RTL/BiDi theory (informational, not required for your use case)
  • Target audience note (desktop software, monospace fonts, LTR only)
done?

Yes, done. The revised EDITOR_UI_REFERENCE.md is complete with all fixes applied and new sections added.

gimme a tldr of the changes you did

Fixes:

  • scrollableHeight = max(0, contentHeight - viewportHeight) — prevents negative values
  • Added division-by-zero guards for scroll↔thumb position formulas
  • Fixed visible line off-by-one: now uses [firstVisible, lastVisibleExclusive) half-open intervals
  • Guarded log10(0) in line number width calculation
  • Added scroll clamping to computeMinimalScroll

Standardization:

  • preferredColumn = column integer (for vertical nav memory), not pixels
  • Selection = {start, end, direction} consistently (not anchor/head mix)
  • ScrollMargins = lines (vertical), columns (horizontal) — explicit units

New Sections:

  • Chapter 12: Cursor styles (pipe/block/underline) — geometry, rendering, vim modes
  • Appendix E: UTF-8 for code editors — bytes vs codepoints, practical approach
  • Appendix F: RTL/BiDi theory — informational only, not required

Scope Notes:

  • Added target audience header (desktop software: Rust/Go/C++, not web)
  • Monospace fonts assumed throughout
  • LTR only (RTL theory in appendix)
based on the reference guide and our existing codebase, consult oracle, librarian and search to review the elm style architecture we are using and determine if it will hold up in the long term, or if it woul be better to refactor to a different architecture/structure, store findings in CODEBASE_REVIEW.md

Done. Created CODEBASE_REVIEW.md.

TL;DR: Keep the Elm architecture—it's solid. Both Helix and Zed use similar patterns. Refactor by:

  1. Split Model → Document / EditorState / UiState
  2. Nest Msg → EditorMsg, DocumentMsg, UiMsg, AppMsg
  3. Expand Cmd → Add async variants (SaveFile, LoadFile, SpawnTask)
  4. Add types → Selection, multi-cursor support

Estimated effort: 1-2 days for structure, then incremental feature additions.

seee @todo.md i also want to have some kind of performance monitoring system, how would that fit into the suggestions you provided, (its more of a future thing, but jsut out of curiosity etc)

Performance monitoring fits naturally into the expanded architecture. Here's how:

Where It Lives

// Separate from core editor state - it's "meta" functionality
struct DebugState {
    perf_enabled: bool,
    frame_times: RingBuffer<Duration>,      // last N frame times
    update_times: HashMap<String, Duration>, // per-Msg timing
    memory_samples: RingBuffer<MemorySample>,
    
    // From perf-monitor-rs
    cpu_usage: Option<f64>,
    memory_usage: Option<usize>,
}

struct AppModel {
    documents: HashMap<DocumentId, Document>,
    editors: HashMap<EditorId, EditorState>,
    ui: UiState,
    debug: DebugState,  // Optional, compile-gated with #[cfg(feature = "perf")]
}

Message Integration

enum Msg {
    // ... existing
    Debug(DebugMsg),
}

enum DebugMsg {
    TogglePerfOverlay,
    UpdatePerfStats(PerfSnapshot),  // Received from background sampler
    RecordFrameTime(Duration),
}

Cmd for Background Sampling

enum Cmd {
    Redraw,
    SaveFile { .. },
    StartPerfSampler { interval_ms: u64 },  // Spawns thread that posts DebugMsg
    StopPerfSampler,
}

// In event loop
Cmd::StartPerfSampler { interval_ms } => {
    std::thread::spawn(move || {
        loop {
            std::thread::sleep(Duration::from_millis(interval_ms));
            let snapshot = PerfSnapshot {
                cpu: perf_monitor::cpu::processor_numbers().ok(),
                memory: perf_monitor::mem::get_process_memory_info().ok(),
            };
            tx.send(Msg::Debug(DebugMsg::UpdatePerfStats(snapshot))).ok();
        }
    });
}

Instrumented Update Loop

fn update(app: &mut AppModel, msg: Msg) -> Option<Cmd> {
    let start = Instant::now();
    let msg_name = format!("{:?}", std::mem::discriminant(&msg));
    
    let result = match msg { /* ... */ };
    
    if app.debug.perf_enabled {
        app.debug.update_times.insert(msg_name, start.elapsed());
    }
    result
}

Display Options

  1. Status bar - Show FPS, memory in existing status line
  2. Overlay panel - Dedicated debug overlay (new overlay type)
  3. Log only - Just write to stderr/file for CI analysis
// In render, after main content:
if app.debug.perf_enabled {
    render_perf_overlay(&app.debug, ctx);
}

TL;DR

Aspect Fits Into
State DebugState in AppModel
Collection Cmd::StartPerfSampler spawns background thread
Updates DebugMsg::UpdatePerfStats posts samples back
Display UiState overlay or status bar extension
Toggle DebugMsg::TogglePerfOverlay

The architecture handles it cleanly because it's just another domain (Debug) with its own state/messages, and the expanded Cmd system supports the background sampling thread.

neat, add a seperate section about this into the CODEBASE_REVIEW document (reference the todo.md file and provide context in the review doc so its clear what/why this is desirable and how it would be done etc)

Done. Added section 5 "Performance Monitoring Integration" to CODEBASE_REVIEW.md covering:

  • Why — Frame times, update latency, memory tracking, I/O performance
  • Where it livesDebugState as separate domain in AppModel
  • Message integrationDebugMsg enum with toggle, update, record variants
  • Command integrationCmd::StartPerfSampler for background thread
  • Implementation pattern — Instrumented update() loop with timing
  • Display options — Status bar, overlay, log file, JSON export
  • Compile-time gating — Optional perf feature flag
  • Integration table — How it ties to soft wrapping, syntax highlighting, etc.
a bit of an aside, but say i wanted to introduce a comprehensive "themeing" system (basically i define colors for gutter bg, editor background borders all that jazz), and i wanted it based on jetbrains fleet or intellij (dark theme, not the old dracula one), how would that play into this new approach, consult oracle, id preferably just want a very basic yaml or key=value or json file that defines the theme colors and such, that would be fairly pragmatic and possibly also quite sufficient for most use-cases? brainstorm and gimme some insights, examples and pointers on that. (also maybe a comprehensive list of what to nam eeach individual thing (based on glossary in the doc we mentioned earlier but perhaps with more sub-componetns and state modifiers where neeeded).

Great insights from the oracle. Let me also look up actual Fleet theme values to give you more accurate colors:

Explored 1 search

Now let me create a comprehensive document with all of this:

Created THEMING_SYSTEM.md
+922

Created docs/THEMING_SYSTEM.md with:

Format: YAML (comments, readable nesting, maps to Rust via serde)

Complete schema covering:

  • UI components: window, editor, gutter, scrollbar, status_bar, popup, search, diagnostics, tabs
  • State modifiers: normal, hover, active, focused, disabled
  • Syntax tokens: 30+ semantic roles (keyword, function, type, string, etc.)
  • Font styles: bold, italic, underline, strikethrough

Key naming patterns:

ui.editor.background.normal      # Component.subcomponent.property.state
ui.gutter.line_number.foreground_active
syntax.keyword_control.foreground

Example Fleet Dark theme with actual JetBrains Fleet-inspired colors

Rust integration:

  • Color struct with to_argb_u32() for rendering
  • StatefulColor.resolve(UiState) for state-aware colors
  • SyntaxStyle with is_bold(), is_italic() helpers
  • Fits into AppModel alongside documents/editors/ui