Make mode-related commands and effects mode-agnostic by passing the target
mode as an argument instead of inspecting the current application mode.
- `CommitAndAdvance` now accepts `edit_mode` .
- `EditOrDrill` now accepts `edit_mode` .
- `EnterEditAtCursorCmd` now accepts `target_mode` .
- `EnterEditAtCursor` effect now accepts `target_mode` .
Update the command registry to parse mode names from arguments and pass
them to the corresponding commands.
Add tests to verify the new mode-passing behavior.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-26B-A4B-it-UD-Q5_K_XL.gguf)
Implement a new "Records" mode for data entry.
- Add `RecordsNormal` and `RecordsEditing` to `AppMode` and `ModeKey` .
- `DataStore` now uses `IndexMap` and supports `sort_by_key()` to ensure
deterministic row order.
- `ToggleRecordsMode` command now sorts data and switches to
`RecordsNormal` .
- `EnterEditMode` command now respects records editing variants.
- `RecordsNormal` mode includes a new `o` keybinding to add a record row.
- `RecordsEditing` mode inherits from `Editing` and adds an `Esc` binding
to return to `RecordsNormal` .
- Added `SortData` effect to trigger data sorting.
- Updated UI to display "RECORDS" and "RECORDS INSERT" mode names and
styles.
- Updated keymaps, command registry, and view navigation to support these
new modes.
- Added comprehensive tests for records mode behavior, including sorting
and boundary conditions for Tab/Enter.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-26B-A4B-it-UD-Q5_K_XL.gguf)
Replace `HashMap` with `IndexMap` in `DataStore::cells` to preserve
insertion order. This allows records mode to display rows in the order they
were added. Update `remove` to use `shift_remove` to maintain order during
deletions.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-26B-A4B-it-UD-Q5_K_XL.gguf)
Introduce `ViewFrame` to store both the view name and the `AppMode` when
pushing to the navigation stack. Update `view_back_stack` and
`view_forward_stack` to use `ViewFrame` instead of `String` . Update
`CmdContext` and `Effect` implementations (SwitchView, ViewBack,
ViewForward) to handle the new `ViewFrame` structure. Add `is_editing()`
helper to `AppMode` .
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-26B-A4B-it-UD-Q5_K_XL.gguf)
Virtual categories _Index and _Dim now default to None on new models
instead of being forced onto Row/Column. _Measure defaults to Page
(the natural home for measure filtering). Fixed page_coords builder
to skip Page categories with no items/selection, preventing empty-string
contamination of cell keys.
Made-with: Cursor
Ensure that virtual categories (_Index, _Dim, _Measure) are registered in
the default view with Axis::None. This prevents potential panics when
calling axis_of on these categories and allows users to move them to a
specific axis manually.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
The records mode column filter excluded all categories starting with '_',
which hid _Measure. Changed to explicitly exclude only _Index and _Dim,
making _Measure visible as a data column. Updated the blank-model editing
test to reflect the new column order (_Measure first, Value last).
Made-with: Cursor
Clean up formatting of a test assertion in app.rs to improve readability.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Simplify the commit_cell_value function by extracting its core logic into
specialized helper functions: commit_regular_cell_value, stage_drill_edit,
and commit_plain_records_edit. This improves readability and reduces
nesting.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Extract the hardcoded error message "Record coordinates cannot be empty"
into a public constant in effect.rs to avoid duplication and improve
maintainability.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Allow synthetic record edits to be applied directly to the model when not
in drill mode, whereas they remain staged in drill state when a drill
snapshot is active. This enables editing of records in plain records view.
Additionally, add validation to prevent creating records with empty
coordinates in both direct commits and when applying staged drill edits.
Includes regression tests for persistence in blank models, drill state
staging, and empty coordinate prevention.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Extract the formula AST and parser into a dedicated `improvise-formula`
crate and convert the project into a Cargo workspace.
The root crate now re-exports `improvise-formula` as `crate::formula` to
maintain backward compatibility for internal callers. The repository map is
updated to reflect the new crate structure.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Add helper methods to CmdContext to clarify layout state and synthetic
record presence. Update AddRecordRow to check for records mode generally
rather than requiring a synthetic record at the current cursor, which
allows adding the first row to an empty records view.
Includes a regression test for the empty records view scenario.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Update the loop in TileBar to use an iterator-based approach with
enumerate, take, and skip instead of indexing.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Clean up various test cases by simplifying Option checks, removing
redundant clones, using contains instead of any for DateComponent checks,
and removing unnecessary references in string formatting.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Simplify the return value of CommitFormula::execute to use a vec! macro and
move the page_cat_data helper function in navigation.rs for better
organization.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
Replace modulo operations with is_multiple_of calls and simplify nested if
statements using let-chains in the grammar generator.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
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)
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)
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)
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)
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)
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)
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)
- 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)
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)
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)
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)
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)
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)
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
- 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
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
_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>
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>
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>
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>
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>
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>
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)
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)
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)