From 5a7ba5fb306460d6e3f282c7e41f6291fc3b6fe9 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Tue, 14 Apr 2026 00:49:32 -0700 Subject: [PATCH] docs: update repository map and project metadata Update the repository map with the latest project metadata, including version bumps, updated dependency versions, and technical notes on formula drilling, formula recomputation, and minibuffer clearing. Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf) --- context/repo-map.md | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/context/repo-map.md b/context/repo-map.md index 1bbd2d5..f7bfe98 100644 --- a/context/repo-map.md +++ b/context/repo-map.md @@ -1,7 +1,8 @@ # Repository Map (LLM Reference) Terminal pivot-table modeling app. Rust, Ratatui TUI, command/effect architecture. -Crate `improvise` v0.1.0, Apache-2.0, edition 2021. +Crate `improvise` v0.1.0-rc2, Apache-2.0, edition 2024. +Library + binary crate: `src/lib.rs` exports public modules, `src/main.rs` is the CLI entry. --- @@ -94,8 +95,10 @@ pub struct Model { // evaluate(&self, key: &CellKey) -> Option [formulas + raw data] // evaluate_aggregated(&self, key, none_cats) -> Option [sums over hidden dims] // recompute_formulas(&mut self, none_cats) [fixed-point formula cache] -// add_formula(&mut self, formula: Formula) [replaces same target+category, adds item] +// add_formula(&mut self, formula: Formula) [replaces same target+category] // remove_formula(&mut self, target, category) +// measure_item_names(&self) -> Vec [_Measure items + formula targets] +// effective_item_names(&self, cat) -> Vec [_Measure dynamic, others ordered_item_names] // category_names(&self) -> Vec<&str> [includes virtual] // regular_category_names(&self) -> Vec<&str> [excludes _Index, _Dim, _Measure] @@ -262,8 +265,10 @@ pub enum ModeKey { SearchMode, ImportWizard, } +// Keymap::with_parent(parent: Arc) -> Self [Emacs-style inheritance] // Keymap::lookup(&self, key, mods) -> Option<&Binding> -// Fallback chain: exact(key,mods) → Char with NONE mods → AnyChar → Any +// Fallback chain: exact(key,mods) → Char with NONE mods → AnyChar → Any → parent +// Minibuffer modes: Enter and Esc use Binding::Sequence to include clear-buffer // KeymapSet::default_keymaps() -> Self [builds all 14 mode keymaps] // KeymapSet::dispatch(&self, ctx, key, mods) -> Option>> @@ -293,7 +298,8 @@ collapsed: |Time Period|/|2024| format: ,.2f ## Formulas -- Profit = Revenue - Cost [Measure] ← [TargetCategory] +- Profit = Revenue - Cost ← defaults to [_Measure] +- Tax = Revenue * 0.1 [CustomCat] ← explicit [TargetCategory] for non-_Measure ## Category: Region - North, South, East, West ← bare items, comma-separated @@ -323,7 +329,7 @@ The parser accepts sections in any order. ### Key design choices -- Version line (`v2025-04-09`) enables future format changes. +- Version line is exact match (`v2025-04-09`) — grammar enforces valid versions only. - `Initial View:` is a top-level header, not embedded in view sections. - Text cell values are always pipe-quoted to distinguish from numbers. - Bare items are comma-separated on one line; grouped items get one line each. @@ -349,7 +355,7 @@ Import flags: `--category`, `--measure`, `--time`, `--skip`, `--extract`, `--axi | Crate | Purpose | |-------|---------| -| ratatui 0.29 | TUI framework | +| ratatui 0.30 | TUI framework | | crossterm 0.28 | Terminal backend | | clap 4.6 (derive) | CLI parsing | | serde + serde_json | Serialization | @@ -442,11 +448,18 @@ command/cmd/ Cmd trait, CmdContext, CmdRegistry, 40+ comma ``` 400 / 0t draw.rs TUI event loop (run_tui), frame composition 391 / 0t main.rs CLI entry (clap): open, import, cmd, script + 10 / 0t lib.rs Public module exports (enables examples) 228 / 29t format.rs Number display formatting (view-only rounding) 124 / 0t persistence/improv.pest PEG grammar — single source of truth for .improv format 2291 / 83t persistence/mod.rs .improv save/load (pest parser + format + gzip + legacy JSON) ``` +### Examples +``` +examples/gen-grammar.rs Grammar-walking random file generator (pest_meta) +examples/pretty-print.rs Parse stdin, print formatted .improv to stdout +``` + ### Context docs ``` context/design-principles.md Architectural principles @@ -455,7 +468,7 @@ context/repo-map.md This file docs/design-notes.md Product vision & non-goals (salvaged from former SPEC.md) ``` -**Total: ~21,400 lines, 568 tests.** +**Total: ~22,000 lines, 572 tests.** --- @@ -519,7 +532,7 @@ examples). 1. **Commands never mutate.** They receive `&CmdContext` (read-only) and return `Vec>`. 2. **CellKey is always sorted.** Use `CellKey::new()` — never construct the inner Vec directly. 3. **`category_mut()` for adding items.** `Model` has no `add_item` method; get the category first: `m.category_mut("Region").unwrap().add_item("East")`. -4. **Virtual categories** `_Index`, `_Dim`, and `_Measure` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. `_Measure` holds numeric data fields and formula targets; `add_formula` auto-adds the target item. +4. **Virtual categories** `_Index`, `_Dim`, and `_Measure` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. `_Measure` items come from two sources: explicit data items (in category) + formula targets (dynamically via `measure_item_names()`). `add_formula` does NOT add items to `_Measure` — use `effective_item_names("_Measure")` to get the full list. `_Index` and `_Dim` are never persisted to `.improv` files; `_Measure` only persists non-formula items. 5. **Display rounding is view-only.** `format_f64` (half-away-from-zero) is only called in rendering. Formula eval uses full f64. 5b. **Formula evaluation is fixed-point.** `recompute_formulas(none_cats)` iterates formula evaluation until values stabilize, using a cache. `evaluate_aggregated` checks the cache for formula results. Circular refs produce `CellValue::Error("circular")`. 6. **Keybindings are per-mode.** `ModeKey::from_app_mode()` resolves the current mode, then the corresponding `Keymap` is looked up. Normal + `search_mode=true` maps to `SearchMode`. @@ -527,3 +540,6 @@ examples). 8. **`.improv` format is defined by a PEG grammar** (`persistence/improv.pest`). Parsed by pest. Names use CL-style `|...|` pipe quoting when they aren't valid bare identifiers. JSON is legacy only. 9. **`IndexMap`** is used for categories and views to preserve insertion order. 10. **`MAX_CATEGORIES = 12`** applies only to `CategoryKind::Regular`. Virtual/Label categories are exempt. +11. **Drill into formula cells** strips the `_Measure` coordinate from the drill key when it names a formula target, so `matching_cells` finds the raw data records that feed the formula instead of returning empty. +12. **`App::new` calls `recompute_formulas`** before building the initial layout, so formula values appear on the first rendered frame. +13. **Minibuffer buffer clearing** is handled by `Binding::Sequence` in keymaps: Enter and Esc sequences include `clear-buffer` to reset the text buffer. The `clear-buffer` command is registered in the registry.