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)
Update TileBar to use UnicodeWidthStr for accurate text width calculation and
improve axis display.
- Use `unicode_width::UnicodeWidthStr` for calculating label and hint widths
- Move `axis_display` to a static method on `TileBar`
- Update axis symbols for better visual clarity (e.g., '|', '-', '=', '.')
- Clear the tile bar area before rendering to prevent stale characters
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Refactor GridWidget and other UI components to use the pre-computed layout from
App instead of re-creating it on every render. This improves performance and
ensures consistency.
- Update GridWidget to take a reference to GridLayout
- Update GridWidget::new and render to use the provided layout
- Update App::cmd_context and other call sites to pass the layout
- Update tests to provide the layout to GridWidget
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Refactor GridLayout to use Rc for sharing records and simplify its structure.
This improves performance when cloning the layout and ensures consistent data
access.
- Use Rc<Vec<(CellKey, CellValue)>> for records in GridLayout
- Update with_frozen_records and other methods to handle Rc
- Simplify layout construction and sorting logic
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
Refactor App and DrillState to use Rc for sharing records, and introduce
rebuild_layout() to manage GridLayout lifecycle. This ensures the layout is
consistently updated when the model or drill state changes.
- Use Rc<Vec<(CellKey, CellValue)>> for DrillState.records to allow cheap
cloning
- Add layout field to App
- Implement rebuild_layout() in App to refresh the GridLayout
- Update App::new and App::cmd_context to use the new layout management
- Ensure layout is rebuilt after applying effects and handling key events
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)
Unifies cell text retrieval and formatting across pivot and records modes.
Introduces `GridLayout::display_text` to centralize how cell content is
resolved, reducing duplication in `GridWidget` and `export_csv`.
Moves formatting logic from `src/ui/grid.rs` to a new dedicated `src/format.rs`
module to improve reusability.
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)
Clean up UI panel titles by removing redundant keyboard hints that are
already present in the app's status bar or are no longer needed.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-31B-it-GGUF:UD-Q5_K_XL)
Improve grid viewport calculations by using actual column widths instead of
rough estimates. This ensures that the viewport scrolls correctly when the
cursor moves past the visible area.
- Move column width and visible column calculations to public functions in
`src/ui/grid.rs`.
- Update `App::cmd_context` to use these precise calculations for `visible_cols`
.
- Add a regression test to verify that `col_offset` scrolls when cursor moves
past visible columns.
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 grid widget with adaptive column/row widths and pruning support.
Replaced fixed ROW_HEADER_WIDTH (16) and COL_WIDTH (10) with adaptive
widths based on content. MIN_COL_WIDTH=5, MAX_COL_WIDTH=32. MIN_ROW_HEADER_W=4,
MAX_ROW_HEADER_W=24.
Column widths measured from header labels and cell content (pivot mode
measures formatted values, records mode measures raw values).
Row header widths measured from widest label at each level.
Added underlining for columns sharing ancestor groups with selected
column. Updated is_aggregated check to filter virtual categories.
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 status bar hints for new features.
Normal mode hint: Added R:records P:prune, removed F/C/V:panels
CategoryPanel hint: Added d:delete
These hints reflect the new keybindings for records mode toggle,
prune empty toggle, and category deletion.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add EnterEditAtCursor effect to re-enter edit mode after commit.
Used by CommitCellEdit to continue data entry after advancing
cursor. Reads the cell value at the new cursor position and
starts editing mode with that value pre-filled.
Also adds TogglePruneEmpty, ToggleCatExpand, RemoveItem, and
RemoveCategory effects to effect.rs for the new commands.
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)
Fix column header and cell text truncation to prevent overflow
when text width equals column width. Changed truncate() calls to
use cw.saturating_sub(1) instead of cw, ensuring at least one
character of padding remains.
Affected areas:
- Column header labels (left-aligned)
- Column header labels (right-aligned)
- Cell values
- Total/summary rows
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add two new tests for label field functionality:
- label_fields_imported_as_label_category_coords: Verifies that
high-cardinality fields (>20 distinct values) are classified as
Label kind, default to accepted, and are stored as category coords
- label_category_defaults_to_none_axis: Verifies that label categories
default to Axis::None in the active view
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add support for Label-kind categories to handle high-cardinality
per-row fields like descriptions, IDs, and notes. These fields are
stored alongside regular categories but default to Axis::None and
are excluded from pivot category limits.
Changes:
- analyzer.rs: Label fields now default to accepted=true
- wizard.rs: Collect and process label fields during model building,
attaching label values as coordinates for each cell
- category.rs: Add Label variant to CategoryKind enum
- types.rs: Add add_label_category() method and update category
counting to only include Regular-kind categories
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Fix column header and cell text truncation to prevent overflow
when text width equals column width. Changed truncate() calls to
use cw.saturating_sub(1) instead of cw, ensuring at least one
character of padding remains.
Affected areas:
- Column header labels (left-aligned)
- Column header labels (right-aligned)
- Cell values
- Total/summary rows
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add two new tests for label field functionality:
- label_fields_imported_as_label_category_coords: Verifies that
high-cardinality fields (>20 distinct values) are classified as
Label kind, default to accepted, and are stored as category coords
- label_category_defaults_to_none_axis: Verifies that label categories
default to Axis::None in the active view
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add support for Label-kind categories to handle high-cardinality
per-row fields like descriptions, IDs, and notes. These fields are
stored alongside regular categories but default to Axis::None and
are excluded from pivot category limits.
Changes:
- analyzer.rs: Label fields now default to accepted=true
- wizard.rs: Collect and process label fields during model building,
attaching label values as coordinates for each cell
- category.rs: Add Label variant to CategoryKind enum
- types.rs: Add add_label_category() method and update category
counting to only include Regular-kind categories
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)
Add a subtle dark-gray background color constant for row highlighting.
Apply the highlight background across the entire selected row area,
including gaps between columns and the margin after the last column.
Apply the highlight background to individual cells in the selected row,
using DarkGray for empty values and White for non-empty values.
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)
Generates Forth-style command scripts that build a multi-dimensional
model and exercise the grid aggregation hot path via repeated
export-csv calls. Used for profiling with samply.
Usage:
python3 bench/gen_workload.py --scale 5 > /tmp/workload.txt
cargo build --profile profiling
samply record ./target/profiling/improvise script /tmp/workload.txt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a new [profile.profiling] section to Cargo.toml.
This profile inherits from release but with:
- strip = false: Keep debug symbols for profiling
- debug = 2: Full debug information for analysis
Useful for generating profiling data with symbol information.
Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
Add a new SymbolTable module for interned string identifiers.
The module implements a bidirectional mapping between strings and
Symbol IDs using a HashMap. Key functionality includes:
- intern(): Add a string to the table and return its Symbol ID
- get(): Look up a string by Symbol ID
- resolve(): Get the original string for a Symbol ID
- intern_pair() and intern_coords(): Helper functions for structured
data interning
The implementation includes unit tests to verify correct behavior.
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)