Commit Graph

198 Commits

Author SHA1 Message Date
35e2626a7d style: add braces to if statements for consistency
Consolidate if-let chain formatting by adding missing braces throughout the
project. This improves readability and ensures consistency across the
codebase.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-14 00:49:32 -07:00
8baa4c4865 test(grid): ensure formulas are recomputed before rendering
The render helper used in Grid tests previously did not recompute formulas,
meaning tests for computed values were either ignored or required manual
setup that didn't reflect actual application behavior.

Update the render helper to identify 'None' axis categories and trigger
recompute_formulas, and update all call sites to pass a mutable model.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-14 00:49:31 -07:00
f019577810 feat(grid): allow drilling into formula cells
When drilling into a cell that is the target of a formula, the resulting
record set was empty because the formula target coordinate itself does not
exist in the raw data.

This change strips the '_Measure' coordinate from the drill key if the
value is a known formula target, allowing the underlying data records that
feed the formula to be discovered.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-14 00:49:31 -07:00
cb35e38df9 refactor(all): use let chains to flatten nested if statements
Replace nested if and if let blocks with combined if statements using let
chains. This reduces indentation and improves readability across the
project.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-13 21:58:14 -07:00
6370f8b19f chore: format 2026-04-13 21:30:37 -07:00
d4e948827b refactor(model): disable formula evaluation entry point
Disable the eval_formula method in Model. This may be a temporary change or
part of a larger refactor of formula evaluation.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-13 21:30:19 -07:00
c48a5cd575 feat!(persistence): update .improv format to v2025-04-09
Update the .improv file grammar to require version v2025-04-09 and remove
unnecessary blank line requirements at the start of files. Update
bank-info.improv to comply with the new version and reformat date entries
and categories.

BREAKING CHANGE: The .improv grammar now strictly requires the version line 'v2025-04-09'.
Existing files without this line will fail to parse.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-13 21:30:18 -07:00
53b13d4942 refactor(project): transition to library structure
Move module declarations from src/main.rs to a new src/lib.rs to transition
the project to a library-first structure. This allows other tools and
examples to utilize the core logic.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
2026-04-13 21:30:18 -07:00
d4f6efd1c0 fix(upgrade): errors from Rust 2024 edition
- gen is a reserved keyword (→ renamed module to generator)
- ref in patterns with implicit borrowing (→ removed ref)
- & pattern with implicit borrowing (→ added & to outer pattern)
2026-04-11 00:38:30 -07:00
1817494db2 chore: update app initialization and example data
Update application initialization and example data.

- `App::new` now recomputes formulas on startup to ensure formula-derived
  values are available immediately.
- Updated `examples/demo.improv` to reflect changes in formula and category
  structure.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:08:02 -07:00
c701534053 refactor(persistence): improve Markdown formula and category handling
Update persistence logic for formulas and categories.

- Formulas targeting `_Measure` no longer include the category suffix in
  Markdown.
- `_Measure` items are now excluded from the category section in Markdown
  to avoid duplication with the formulas section.
- Improved Markdown parsing to correctly handle formulas without an
  explicit category suffix, defaulting them to `_Measure` .
- Added logic to skip virtual index and dimension categories during
  persistence.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:08:02 -07:00
7fea5f67ed refactor(command): improve formula commitment and buffer management
Refactor command execution and buffer management.

- `CommitFormula` now defaults to targeting `_Measure` .
- `CommitFormula` no longer automatically clears the buffer; buffer
  clearing is now handled by keymap sequences.
- Added `ClearBufferCmd` to the command registry.
- Updated `AddFormulaCmd` to support optional target category.
- Added `SetBuffer` effect to allow clearing buffers.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:08:02 -07:00
c3fb8669c2 feat(command): add keymap inheritance and sequence bindings
Implement keymap inheritance and sequence bindings.

- Added `parent` field to `Keymap` to support Emacs-style inheritance.
- Implemented `lookup` in `Keymap` to fall through to parent keymaps.
- Added `bind_seq` to allow multiple commands to be bound to a single key
  pattern.
- Refactored existing keymaps to use sequences for common patterns like
  Esc/Enter/Tab to clear buffers and change modes.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:08:01 -07:00
c8b9d29690 feat(model): introduce virtual '_Measure' category for formulas
Refactor formula handling to use a virtual '_Measure' category.

- Formulas now default to targeting '_Measure' if no category is specified.
- '_Measure' items are dynamically computed from existing data items and
  formula targets, preventing redundant item storage.
- Updated persistence to handle '_Measure' formulas and items correctly in
  Markdown.
- Updated UI and model to use 'effective_item_names' for layout and item
  resolution.
- Updated tests to reflect the new '_Measure' behavior.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:08:01 -07:00
1690fc317b test: use generic category name in formula parser tests
Replace "Measure" with "Foo" as target_category in formula parser
tests so they don't depend on a specific category name convention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Executed-By: spot
2026-04-11 00:08:01 -07:00
d34e8eb313 feat: replace ad-hoc .improv parser with pest grammar
- Add improv.pest PEG grammar as the single source of truth for the
  .improv file format (v2025-04-09)
- Replace hand-written line scanner with pest-derived parser that walks
  the grammar's parse tree
- Add grammar-walking test generator that reads improv.pest at test time
  via pest_meta and produces random valid files from the AST
- Fix 6 parser bugs: newlines in text, commas in names, brackets in
  names, float precision, view name ambiguity, group brackets
- New format: version line, Initial View header, pipe quoting (|...|),
  Views→Formulas→Categories→Data section order, comma-separated items
- Bare names restricted to [A-Za-z_][A-Za-z0-9_-]*, everything else
  pipe-quoted with \| \\ \n escapes
- Remove all unwrap() calls from production code, propagate errors
  with Result throughout parse_md
- Extract shared escape_pipe/unescape_pipe/pipe_quote helpers, deduplicate
  hidden/collapsed formatting, add w!() macro for infallible writeln

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Executed-By: spot
2026-04-11 00:08:00 -07:00
4d7d91257d refactor: colocate cmd tests with their modules
Move tests from the monolithic tests.rs into #[cfg(test)] mod tests
blocks in each command module. Shared test helpers live in
mod.rs::test_helpers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Executed-By: fido
2026-04-11 00:08:00 -07:00
23a876d556 feat: rename Measure to _Measure (virtual), add fixed-point formula eval
_Measure is now a virtual category (CategoryKind::VirtualMeasure),
created automatically in Model::new() alongside _Index and _Dim.
Formula targets are added as items automatically by add_formula.

Formula evaluation uses a fixed-point cache: recompute_formulas()
iterates evaluation of all formula cells until values stabilize,
resolving refs through the cache for formula values and raw data
aggregation for non-formula values. This fixes formulas that
reference other measures when hidden dimensions are present.

evaluate_aggregated now checks the formula cache instead of
recursively evaluating formulas, breaking the dependency between
formula evaluation and aggregation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:59 -07:00
fd69126cdc refactor: split cmd.rs 2026-04-11 00:07:59 -07:00
24c59fbf40 fix: Model::add_formula auto-adds target item; fix formula panel display
Model::add_formula now ensures the formula target exists as an item in
the target category (same fix as AddFormula effect, but at the model
level — covers file loading and headless paths).

Formula panel now shows raw formula text instead of debug-formatted
string with redundant target name and quotes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:59 -07:00
4686f47026 fix: scroll tile bar to keep selected tile visible
When there are more tiles than fit in the available width, the tile
bar now auto-scrolls to ensure the selected tile is always visible.
Overflow indicators (◀ ▶) show when tiles exist beyond the visible
area. Scroll offset is computed fresh each frame from tile_cat_idx.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:58 -07:00
737d14a5c0 fix: add depth limit to formula evaluation, propagate errors
Circular or self-referencing formulas now return CellValue::Error
instead of stack overflowing. eval_expr uses Result<f64, String>
internally so errors (circular refs, div/0, missing refs) propagate
immediately through the expression tree via ?. The depth limit (16)
is checked per evaluate_depth call — normal 1-2 level chains are
unaffected.

Also adds CellValue::Error variant for displaying ERR:reason in the
grid, and handles it in format, persistence, and search.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:58 -07:00
32d215f3d6 fix: AddFormula now adds target item to category
When adding a formula interactively, the target (e.g. "Margin") was
registered as a formula but never added as an item to the target
category. The grid layout never created cells for it, making the
formula invisible. Now AddFormula::apply calls add_item before
registering the formula.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:58 -07:00
6239ac83ad chore: fmt + clippy 2026-04-11 00:07:57 -07:00
ad9ea30fc2 test(csv): add RFC 4180 edge case tests for CSV quote handling
Audit confirms the csv crate correctly handles all RFC 4180 cases:
- Embedded commas in quoted fields
- Escaped quotes ("") within quoted fields
- Embedded newlines in quoted fields
- Combined commas + escaped quotes

No bugs found — added 4 regression tests to document compliance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:07:56 -07:00
fb8b6ca053 feat(formula): support pipe-quoted identifiers |...|
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:06:51 -07:00
e67f4d5a92 fix(formula): break tokenizer identifiers when current word is a keyword
The tokenizer already broke multi-word identifiers when the NEXT word
was a keyword, but not when the identifier collected SO FAR was a
keyword. This meant "WHERE Region" was merged into one token when
tokenizing "SUM(Revenue WHERE Region = East)".

Now the tokenizer also checks if the identifier built up to the current
space IS a keyword (WHERE, SUM, AVG, MIN, MAX, COUNT, IF), which
correctly produces separate tokens for "Revenue", "WHERE", "Region".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:06:51 -07:00
4c8ba6400b refactor: use regular_category_names in command and import wizard
Updates `CommitFormula` and `ImportPipeline` to use
`regular_category_names` instead of `category_names` . This ensures that
these components do not target or default to virtual categories (_Index,
_Dim) when no regular categories are present.

Includes updated tests for `CommitFormula` to verify it correctly handles
cases with no regular categories.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
db170a10b8 feat(model): add regular_category_names to Model
Updates `Model` to include `regular_category_names` , which returns
category names excluding virtual categories (_Index, _Dim). This allows
other parts of the application to distinguish between user-defined
categories and system-internal ones.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
d14ec443c2 feat(formula): improve tokenizer to correctly handle keywords and delimiters
The tokenizer was greedily consuming spaces and potentially merging
identifiers with subsequent keywords. This change improves the tokenizer
by:
- Peeking ahead past spaces to find the next word/token.
- Breaking the identifier if the next word is a known keyword (WHERE, SUM,
  AVG, MIN, MAX, COUNT, IF).
- Adding support for more delimiter characters (<, >, =, !, ").

This fixes a regression where "Revenue WHERE" was treated as a single
identifier instead of an identifier followed by a WHERE clause.

Includes a new regression test for inline WHERE filters in aggregate
functions.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
a83a4f604f chore: improve test coverage of mod.rs 2026-04-11 00:06:50 -07:00
c8607b78ba test(ui): add unit tests for effects
Add unit tests for UI effects, covering:
- Model mutations
- View navigation
- App state changes
- Drill-down functionality

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
687cf80698 test(import): add unit tests for import wizard and pipeline
Add unit tests for ImportWizard and ImportPipeline, covering:
- Wizard step transitions
- Proposal and formula editing
- Date configuration
- Edge cases for building the data model

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
96a4cda368 test(formula): add unit tests for formula parser
Add a comprehensive suite of unit tests for the formula parser, covering:
- Aggregate functions
- WHERE clauses
- Comparison operators
- Arithmetic operations
- Various error handling scenarios

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
5f71321980 test(command): add unit tests for various commands
Add unit tests for various commands including PasteCell, TransposeAxes,
ViewNavigate, and MovePanelCursor to ensure correct command execution and
state changes.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
a3d8adfb45 refactor(command): improve axis operation feedback
Improve feedback for axis operations:

- `CycleAxisAtCursor` : Now provides a status message if no category is at
  the cursor.
- `TileAxisOp` :
    - Now provides a status message showing the new axis (e.g., "Category →
      Row").
    - No longer automatically switches to `AppMode::Normal` , allowing for
      multiple consecutive adjustments.
    - Provides a status message if no category is at the cursor.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
da076eadc8 test(model,ui): add tests for precision and cat tree
Add unit tests for model precision and category tree rendering:

- `src/model/types.rs` : Added `formula_chain_preserves_full_precision` to
  ensure formulas use full `f64` precision for calculations, even when
  display is rounded.
- `src/ui/cat_tree.rs` : Added comprehensive tests for `build_cat_tree` ,
  covering empty models (virtual categories), expanded/collapsed states,
  and item rendering.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
433a20928a refactor(format): improve number formatting and rounding
Improve number formatting and add comprehensive tests:

- Implemented `round_half_away` to provide more intuitive rounding (e.g.,
  2.5 -> 3, -2.5 -> -3).
- Updated `format_f64` to use this rounding logic.
- Added extensive unit tests for `parse_number_format` and `format_f64` ,
  covering various edge cases and rounding behaviors.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
7dd9d906c1 refactor(ui): improve rendering, feedback, and help system
Improve UI rendering and feedback:

- `src/draw.rs` :
    - Automatically enter Help mode if the model is empty.
    - Render the `HelpWidget` with the current help page.
    - Render the `WhichKeyWidget` when a transient keymap is active.
- `src/ui/tile_bar.rs` : Use more descriptive labels for axes (e.g., "Row",
  "Col", "Pag").
- `src/ui/view_panel.rs` :
    - Include an axis summary (e.g., "R:Region C:Product") next to view
      names.
    - Refactor `ViewContent` to hold a reference to the `Model` .
- `src/ui/effect.rs` : Add error feedback to `AddItem` , `AddItemInGroup` ,
  and `AddFormula` when operations fail.
- `src/ui/help.rs` : Refactor `HelpWidget` into a multi-page system.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
2b1f42d8bf refactor(command): update keymaps for command mode and help navigation
Update keymaps to allow entering command mode via ':' in various panels and
add help page navigation.

- Added ':' command binding to Help, FormulaPanel, CategoryPanel,
  ViewPanel, and TileSelect modes.
- Added navigation bindings (Right/Left, l/h, n/p, Tab/BackTab) to the Help
  keymap.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:50 -07:00
d49bcf0060 feat(ui): implement which-key popup for command completions
Implement `WhichKey` popup to show available command completions.

- Added `format_key_label` to convert `KeyCode` to human-readable strings.
- Added `binding_hints` to `Keymap` to extract available commands for a
  given prefix.
- Added `src/ui/which_key.rs` for the widget implementation.
- Updated `src/ui/mod.rs` to export the new module.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:49 -07:00
bbc009b088 feat(command): implement help page navigation
Implement help page navigation with `help-page-next` and `help-page-prev`
commands.

- Added `HelpPageNextCmd` and `HelpPagePrevCmd` to `src/command/cmd.rs` .
- Registered help navigation commands in `CmdRegistry` .
- Updated `HelpCmd` to initialize the help page.
- Added unit tests for help navigation in `src/ui/app.rs` .

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:49 -07:00
33676b8abd feat(command): add add-items command
Implement `add-items` command to allow adding multiple items to a category
at once.

- Added `AddItemsCmd` to `src/command/cmd.rs` .
- Registered `add-items` in `CmdRegistry` .
- Added unit tests for `add-items` in `src/command/parse.rs` .

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:49 -07:00
1813d2a662 feat(command): implement command aliasing
Implement command aliasing in CmdRegistry and update command parsing to
resolve aliases.

- Added `aliases` field to `CmdRegistry` .
- Added `alias()` method to register short names.
- Added `resolve()` method to map aliases to canonical names.
- Updated `parse()` and `interactive()` to use `resolve()` .
- Added unit tests for alias resolution in `src/command/parse.rs` .

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:49 -07:00
956cb5692c refactor: move main function to the top of src/main.rs
Move the main function from the bottom of the file to the top, after
imports.

This improves code readability by placing the entry point closer to the top
of the file.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:48 -07:00
cb24cce1f0 feat: use enum_dispatch for command dispatch and add Open command
Replace manual dynamic dispatch using Box <dyn Runnable> with enum_dispatch
for improved performance and cleaner code.

Add a new Open command to allow opening the TUI as the default behavior
when no subcommand is provided.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:48 -07:00
a3a74d2787 refactor(cli): refactor command structure and introduce Runnable trait
Refactor the CLI command structure by moving subcommand arguments into
dedicated structs (ImportArgs, CmdArgs, and ScriptArgs).

Introduce a Runnable trait to allow for polymorphic command execution,
replacing the large match statement in the main function with a more
scalable approach.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
2026-04-11 00:06:48 -07:00
3885fc19c8 refactor(test): split let statements and clean up vec! macro
Split multi-line let statements in command tests into separate lines.
Remove unnecessary commas and inline vec! macro. Clean up test code
formatting for readability. No functional changes, only style improvements.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
2026-04-11 00:06:48 -07:00
5566d7349b feat(ui): add footer support to panels
Add footer_height method to PanelContent trait with default 0. Implement
footer_height in FormulaContent to return 1 when in FormulaEdit mode.
Update Panel::render to subtract footer height from item height. This
enables optional footers in panels.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
2026-04-11 00:06:48 -07:00
4b11b6e321 feat(ui): simplify AppMode minibuffer handling and panel rendering
Refactor AppMode to use MinibufferConfig for all text-entry modes. Update
command implementations to use new mode constructors. Introduce
PanelContent trait and replace panel structs with content types. Adjust
rendering to use Panel::new and minibuffer configuration. Update imports
and add MinibufferConfig struct. No functional changes; all behavior
preserved.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
2026-04-11 00:06:48 -07:00