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)
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)
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)
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)
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)
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
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>
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
Add a `changes_mode` method to the `Effect` trait with a default implementation
returning `false` . Implement this method for the `ChangeMode` effect to return
`true` . Update the command execution logic to use `e.changes_mode()` instead of
string matching on formatted output. Adjust the corresponding test to assert the
presence of a mode‑changing effect directly via the new method, removing the
temporary debug string.
This change introduces a clear, typed way to detect mode‑changing effects,
improving readability and reducing reliance on string inspection.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
Expose CmdRegistry via KeymapSet registry method.
Update Z keybinding to use SaveAndQuit command.
Pass registry to App's CmdContext construction.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
Update CmdContext to include registry reference.
Adjust make_ctx function signature to accept registry.
Update all tests to pass the default registry.
Ensure test contexts are constructed with registry.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
Add new command structs for quitting and command execution.
Introduce Quit and SaveAndQuit commands with dirty checks.
Add ExecuteCommand for handling ':' input.
Define effect_cmd for SetFormatCmd, ImportCmd, ExportCmd, WriteCmd, and HelpCmd.
Register the new commands in the default command registry.
Fix a buggy mode reset check that used Debug string matching.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (bartowski/nvidia_Nemotron-Cascade-2-30B-A3B-GGUF)
Update documentation for ToggleRecordsMode to clarify its behavior with the view
stack.
- Clarify that entering records mode creates a `_Records` view
- Clarify that leaving records mode navigates back to the previous view
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Clean up formatting and code style across the project.
- Remove unnecessary whitespace and empty lines in `src/model/cell.rs` ,
`src/model/types.rs` , and `src/draw.rs` .
- Reformat long lines and function calls in `src/command/cmd.rs` ,
`src/ui/grid.rs` , and `src/ui/tile_bar.rs` for better readability.
- Consolidate imports and simplify expressions in `src/command/keymap.rs` and
`src/ui/app.rs` .
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Improve ToggleRecordsMode by using the view stack for navigation. Instead of
manually calculating axes, it now creates a `_Records` view and switches to it,
or navigates back to the previous view if already in records mode.
- Use `ctx.layout.is_records_mode()` to detect state
- Use `effect::ViewBack` to exit records mode
- Use `effect::CreateView` and `effect::SwitchView` to enter records mode
- Simplify axis setting logic for records mode
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Refactor CmdContext to use GridLayout for cell-related information instead of
storing redundant fields. This simplifies the context structure and ensures
commands always use the most up-to-date layout information.
- Add layout field to CmdContext
- Remove redundant row_count, col_count, cell_key, and none_cats fields
- Implement helper methods on CmdContext to delegate to layout
- Update all command implementations and tests to use the new methods
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Adds a `mode()` method to the `Panel` enum to map panels to their
corresponding `AppMode`. Simplifies `TogglePanelAndFocus` in `cmd.rs`
to use this method instead of a manual match block.
Also adds regression tests in `app.rs` to verify that viewport
scrolling now correctly handles small terminal heights.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Replaces separate jump-to-edge commands with a unified `JumpToEdge`
command. Simplifies the command registry using a macro and updates
`ScrollRows` to use a shared `viewport_effects` helper for consistent
scrolling behavior.
This fixes a bug where viewport scrolling was based on a hardcoded
constant (20) instead of the actual visible row count.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Update the test context setup in `src/command/cmd.rs` to use the new
`display_value` field instead of the removed `records_col` and `records_value`
fields.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Add new navigation and editing capabilities to improve data entry and
browsing efficiency.
- Implement `PageScroll` command for PageUp/PageDown navigation.
- Implement `OpenRecordRow` command (Vim-style 'o') to add a row and enter edit
mode.
- Implement `CommitAndAdvanceRight` command for Excel-style Tab navigation.
- Add keybindings for Home, End, PageUp, PageDown, and Tab.
- Update UI hints to reflect new Tab functionality.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Refactor records mode to use synthetic CellKeys (_Index, _Dim) for all columns,
allowing uniform handling of display values and edits across both pivot and
records modes.
- Introduce `synthetic_record_info` to extract metadata from synthetic keys.
- Update `GridLayout::cell_key` to return synthetic keys in records mode.
- Add `GridLayout::resolve_display` to handle value resolution for synthetic
keys.
- Replace `records_col` and `records_value` in `CmdContext` with a unified
`display_value`.
- Update `EditOrDrill` and `AddRecordRow` to use synthetic key detection.
- Refactor `CommitCellEdit` to use a shared `commit_cell_value` helper.
BREAKING CHANGE: CmdContext fields `records_col` and `records_value` are replaced by
`display_value` .
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Update TogglePanelAndFocus and related components to use open/focused flags.
Changed TogglePanelAndFocus from currently_open to open+focused flags.
Parser accepts optional [open] [focused] arguments.
Interactive mode toggles between open+focus and closed/unfocused.
Keymap updates: F/C/V in panel modes close panels when focused.
Model initialization: Virtual categories _Index/_Dim default to None
axis, regular categories auto-assign Row/Column/Page.
App test context updated with visible_rows/visible_cols.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Update viewport effects to use dynamic visible dimensions.
viewport_effects() now takes visible_rows and visible_cols parameters
instead of hardcoded 20/8 values.
Scrolling logic uses these parameters:
- row_offset updates when nr >= row_offset + visible_rows
- col_offset updates when nc >= col_offset + visible_cols
Default registry initialized with visible_rows=20, visible_cols=8
for MoveSelection, MovePanelCursor, and other commands.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Update command tests for new API.
Added EMPTY_EXPANDED static for expanded_cats in test context.
Renamed tests:
- toggle_panel_and_focus_opens_and_enters_mode → toggle_panel_open_and_focus
- toggle_panel_and_focus_closes_when_open → toggle_panel_close_and_unfocus
Updated test assertions to use open/focused flags instead of
currently_open. Tests now verify 2 effects (SetPanelOpen + ChangeMode)
for both open and close operations.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Update commit commands to continue editing after advancing cursor.
CommitCellEdit now advances cursor (typewriter-style) and re-enters
edit mode at the new cell, allowing continuous data entry.
CommitCategoryAdd and CommitItemAdd now exit to CategoryPanel when
the buffer is empty, instead of just clearing the buffer.
Empty buffer behavior:
- CommitCategoryAdd: empty → exit to CategoryPanel
- CommitItemAdd: empty → exit to CategoryPanel
- Non-empty: add item/category, clear buffer, stay in add mode
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add prune_empty feature to hide empty rows/columns in pivot mode.
View gains prune_empty boolean (default false for backward compat).
GridLayout::prune_empty() removes data rows where all columns are
empty and data columns where all rows are empty.
Group headers are preserved if at least one data item survives.
In records mode, pruning is skipped (user drilled in to see all data).
EditOrDrill command updated to check for regular (non-virtual)
categories when determining if a cell is aggregated.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add new commands for enhanced data entry and category management.
AddRecordRow: Adds a new record row in records mode with empty value.
TogglePruneEmpty: Toggles pruning of empty rows/columns in pivot mode.
ToggleRecordsMode: Switches between records and pivot layout.
DeleteCategoryAtCursor: Removes a category and all its cells.
ToggleCatExpand: Expands/collapses a category in the tree.
FilterToItem: Filters to show only items matching cursor position.
Model gains remove_category() and remove_item() to delete categories
and items along with all referencing cells and formulas.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add a tree-based category panel that supports expand/collapse of categories.
Introduces CatTreeEntry and build_cat_tree to render categories as
a collapsible tree. The category panel now displays categories with
expand indicators (▶/▼) and shows items under expanded categories.
CmdContext gains cat_tree_entry(), cat_at_cursor(), and cat_tree_len()
methods to work with the tree. App tracks expanded_cats in a HashSet.
Keymap updates: Enter in category panel now triggers filter-to-item.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Introduce EditOrDrill command that intelligently handles
editing based on cell type. When cursor is on an aggregated
pivot cell (categories on Axis::None, no records mode), it
drills into the cell. Otherwise, it enters edit mode with
the current displayed value.
The 'i' and 'a' keys now trigger edit-or-drill instead of
enter-edit-mode. Aggregated cells are styled in italic to
signal that drilling is required for editing.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Implement dynamic column widths for the grid widget when in records mode.
In records mode, each column width is computed based on the widest
content (pending edit, record value, or header label), with a minimum
of 6 characters and maximum of 32. Pivot mode continues to use fixed
10-character column widths.
The rendering code has been updated to use the computed column widths
and x-offsets for all grid elements: headers, data cells, and totals.
Note that the total row is now only displayed in pivot mode, as it
is not meaningful in records mode.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Introduce records-mode drill-down functionality that allows users to
edit individual records without immediately modifying the underlying model.
Key changes:
- Added DrillState struct to hold frozen records snapshot and pending edits
- New effects: StartDrill, ApplyAndClearDrill, SetDrillPendingEdit
- Extended CmdContext with records_col and records_value for records mode
- CommitCellEdit now stages edits in pending_edits when in records mode
- DrillIntoCell captures a snapshot before switching to drill view
- GridLayout supports frozen records for stable view during edits
- GridWidget renders with drill_state for pending edit display
In records mode, edits are staged and only applied to the model when
the user navigates away or commits. This prevents data loss and allows
batch editing of records.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Implement records mode (long-format view) when drilling into aggregated cells.
Key changes:
- DrillIntoCell now creates views with _Index on Row and _Dim on Column
- GridLayout detects records mode and builds a records list instead of
cross-product row/col items
- Added records_display() to render individual cell values in records mode
- GridWidget and CSV export updated to handle records mode rendering
- category_names() now includes virtual categories (_Index, _Dim)
- Tests updated to reflect virtual categories counting toward limits
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add view navigation history with back/forward stacks (bound to < and >).
Introduce CategoryKind enum to distinguish regular categories from
virtual ones (_Index, _Dim) that are synthesized at query time.
Add DrillIntoCell command that creates a drill view showing raw data
for an aggregated cell, expanding categories on Axis::None into Row
and Column axes while filtering by the cell's fixed coordinates.
Virtual categories default to Axis::None and are automatically added
to all views when the model is initialized.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add #[derive(Default)] to CmdRegistry and Keymap structs, enabling
easy construction of empty instances with CmdRegistry::default() and
Keymap::default().
This simplifies initialization code and follows Rust conventions for
types that hold empty collections as their default state.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)