From 7249facf945cb3b44d68e3294952c356c73fe413 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Wed, 29 Apr 2026 17:33:27 -0700 Subject: [PATCH] docs(ui): classify App-resident runtime/derived fields (improvise-99k) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 4 of vb4. After steps 1–3, App owns model_state, view_state, and a residue of five fields that don't belong to either slice. Add a top-level doc on App explaining the slice structure and tag each residue field as derived cache / runtime metadata / transient / config with a one-line rationale. No behavior change. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/ui/app.rs | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index 8498d01..e41226b 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -271,22 +271,50 @@ impl Default for ViewState { } } +/// Top-level TUI application state. Composed of two named slices and a +/// residue of fields that don't belong to either: +/// +/// - `model_state` — document state (Workbook + IO bookkeeping). Persists. +/// - `view_state` — UI session state (mode, cursors, panels, buffers, …). +/// Does not persist. +/// - The remaining direct fields are runtime / derived / config — see +/// per-field tags below. Each of them is documented as belonging to one +/// of these residue categories so the slice boundary stays explicit: +/// +/// - **derived cache**: a pure function of the slices, recomputed on +/// demand. Owned by `App` because rebuilding belongs to the host. +/// - **runtime metadata**: data the runtime feeds in (terminal dims, +/// wall-clock instants). Not part of model or view state. +/// - **transient**: a flag whose lifetime is bounded to one method call +/// on `App`. Reset on entry, never observed across calls. +/// - **config**: data loaded once at startup and read but not written +/// during a session. pub struct App { pub model_state: ModelState, pub view_state: ViewState, + /// **Runtime metadata**: wall-clock instant of the last autosave. Used + /// by `autosave_if_needed` to debounce writes. Not part of either slice + /// because it's about IO timing, not document or session state. pub last_autosave: Instant, - /// Terminal dimensions (updated on resize and at startup). + /// **Runtime metadata**: terminal dimensions, updated on resize events + /// and at startup. Fed in by the host loop in `draw.rs`. pub term_width: u16, pub term_height: u16, - /// Current grid layout, derived from model + view + drill_state. - /// Rebuilt via `rebuild_layout()` after state changes. + /// **Derived cache**: pure function of `model_state.workbook`, + /// `view_state.drill_state`, and the active view. Rebuilt via + /// `rebuild_layout()` after any state change. Owned by `App` because + /// it's the host's job to coordinate the rebuild, not the slices'. pub layout: GridLayout, - /// When set to true by an effect during `apply_effects`, the remaining - /// effects in the batch are skipped. The flag is reset at the start of - /// every `apply_effects` call. Use via the `AbortChain` effect — this is - /// the mechanism by which e.g. "advance at bottom-right" short-circuits - /// the trailing `EnterEditAtCursor` in a `CommitAndAdvance` chain. + /// **Transient**: when an effect sets this to `true` during + /// `apply_effects`, the remaining effects in the batch are skipped. + /// Reset to `false` at the start of every `apply_effects` call. Use + /// via the `AbortChain` effect — this is the mechanism by which e.g. + /// "advance at bottom-right" short-circuits the trailing + /// `EnterEditAtCursor` in a `CommitAndAdvance` chain. pub abort_effects: bool, + /// **Config**: keymap configuration assembled at startup by + /// `KeymapSet::default_keymaps()`. Read every keypress but never + /// mutated during a session. keymap_set: KeymapSet, }