Commit Graph

85 Commits

Author SHA1 Message Date
038c99c473 chore: update gitignore 2026-04-03 23:07:13 -07:00
f7436e73ba refactor: add Keymap with default bindings and wire into handle_key
Create keymap.rs with Keymap struct mapping (mode, key) to Cmd trait
objects. Wire into App::handle_key — keymap dispatch is tried first,
falling through to old handlers for unmigrated bindings. Normal mode
navigation, cell ops, mode switches, and Help mode are keymap-driven.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:40:36 -07:00
0c751b7b8b refactor: add Cmd trait with CmdContext and first command implementations
Define Cmd trait (execute returns Vec<Box<dyn Effect>>) and CmdContext
(read-only state snapshot). Implement navigation commands (MoveSelection,
JumpTo*, ScrollRows), mode commands (EnterMode, Quit, SaveAndQuit),
cell operations (ClearSelectedCell, YankCell, PasteCell), and view
commands (TransposeAxes, Save, EnterSearchMode).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:38:56 -07:00
9421d01da5 refactor: add Effect trait and apply_effects infrastructure
Define Effect trait in ui/effect.rs with concrete effect structs for
all model mutations, view changes, navigation, and app state updates.
Each effect implements apply(&self, &mut App). Add App::apply_effects
to apply a sequence of effects. No behavior change yet — existing
key handlers still work as before.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:36:44 -07:00
567ca341f7 feat: Forth-style prefix command parser
Replace JSON command syntax with prefix notation: `word arg1 arg2`.
Multiple commands per line separated by `.`. Coordinate pairs use
`Category/Item`. Quoted strings for multi-word values. set-cell
uses value-first: `set-cell 100 Region/East Measure/Revenue`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 22:14:37 -07:00
6647be30fa refactor: switch to clap with subcommands for CLI parsing
Replace hand-rolled arg parser with clap derive. Restructure as
subcommands: import, cmd, script. Import subcommand supports
--category, --measure, --time, --skip, --extract, --axis, --formula,
--name, --no-wizard, and --output flags for configurable imports.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 21:43:16 -07:00
ac0c538c98 feat: adjust arg processing so script+command modes are exclusive 2026-04-03 20:32:55 -07:00
9f5b7f602a chore: cleanup flake 2026-04-03 13:44:26 -07:00
4525753109 chore(merge): remote-tracking branch 'origin/main' 2026-04-03 13:42:07 -07:00
4233d3fbf4 feat: wizard UI for date config and formula steps
Add key handling for ConfigureDates (space toggle components) and
DefineFormulas (n new, d delete, text input mode) wizard steps.
Render date component toggles, formula list with input area, and
sample formulas derived from detected measures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:41:18 -07:00
a73fe160c7 feat: date parsing, component extraction, and wizard formulas
Extend FieldProposal with chrono-based date format detection and
configurable component extraction (Year, Month, Quarter). Add
ConfigureDates and DefineFormulas wizard steps to ImportPipeline.
build_model injects derived date categories and parses formula strings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:41:05 -07:00
5a251a1cbe feat: add Axis::None for hidden dimensions with implicit aggregation
Categories on the None axis are excluded from the grid and cell keys.
When evaluating cells, values across hidden dimensions are aggregated
using a per-measure function (default SUM). Adds evaluate_aggregated
to Model, none_cats to GridLayout, and 'n' shortcut in TileSelect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 16:38:35 -07:00
dd728ccac8 feat: multiple-CSV import 2026-04-02 16:21:45 -07:00
77b33b7a85 refactor: further cleanup of linux build 2026-04-02 15:58:28 -07:00
e831648b18 feat(build): don't bother with static build 2026-04-02 15:47:22 -07:00
be277f43c2 feat(build): use crate2nix 2026-04-02 11:34:22 -07:00
edd6431444 refactor: use data_col_to_visual via group_for helpers, add column group toggle
Add row_group_for/col_group_for to GridLayout, replacing inline
backward-search logic. Refactor grid renderer to use col_group_for
instead of pre-filtering col_items. Add gz keybinding for column
group collapse toggle, symmetric with z for rows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 10:22:00 -07:00
5136aadd86 fix: remove tests for top_level_groups 2026-04-02 10:18:32 -07:00
b9da06c55f fix: csv_parser tests 2026-04-02 10:18:01 -07:00
edd33d6dee chore: cleanup dead code in category.rs 2026-04-02 10:07:49 -07:00
2c9d9c7de7 chore: move csv_path_p, restructure modules 2026-04-02 10:01:51 -07:00
368b303eac chore(merge): remote-tracking branch 'origin/main' 2026-04-02 09:35:41 -07:00
fe74cc5fcb chore: clippy + fmt 2026-04-02 09:35:02 -07:00
b9818204a4 chore: clippy + fmt 2026-04-01 22:17:11 -07:00
1d5edd2c09 fix: handle PathBuf correctly 2026-04-01 22:16:56 -07:00
da93145de5 refactor: introduce draw module 2026-04-01 08:54:22 -07:00
fcfdc09732 chore: cargo fmt 2026-04-01 01:37:40 -07:00
23e26f0e06 Add CSV import functionality
- Use csv crate for robust CSV parsing (handles quoted fields, empty values, \r\n)
- Extend --import command to auto-detect format by file extension (.csv or .json)
- Reuse existing ImportPipeline and analyzer for field type detection
- Categories detected automatically (string fields), measures for numeric fields
- Updated help text and welcome screen to mention CSV support

All 201 tests pass.
2026-04-01 01:37:04 -07:00
2cf1123bcb refactor: cleanup main.rs 2026-04-01 01:35:43 -07:00
bbfd2dc163 refactor: TuiGuard -> TuiContext 2026-03-31 22:05:02 -07:00
85eabebd88 refactor: extract terminal setup/teardown 2026-03-31 21:27:40 -07:00
22ea265b63 refactor: inline print_usage 2026-03-31 20:59:39 -07:00
dda5571faf refactor: inline run_headless 2026-03-31 20:58:43 -07:00
c32e800128 refactor: split main code paths for clarity. 2026-03-31 20:52:28 -07:00
aae8392f46 refactor: continue simplifying entrypoint 2026-03-31 20:15:20 -07:00
6eee161f02 chore: rm vim swap file 2026-03-31 00:08:28 -07:00
183b2350f7 chore: reformat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 00:07:22 -07:00
37584670eb feat: group-aware grid rendering and hide/show item
Builds out two half-finished view features:

Group collapse:
- AxisEntry enum distinguishes GroupHeader from DataItem on grid axes
- expand_category() emits group headers and filters collapsed items
- Grid renders inline group header rows with ▼/▶ indicator
- `z` keybinding toggles collapse of nearest group above cursor

Hide/show item:
- Restore show_item() (was commented out alongside hide_item)
- Add HideItem / ShowItem commands and dispatch
- `H` keybinding hides the current row item
- `:show-item <cat> <item>` command to restore hidden items
- Restore silenced test assertions for hide/show round-trip

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 00:07:11 -07:00
3cf64b40a3 chore: don't pin rust overlay nixpkgs to normal nixpkgs 2026-03-31 00:04:36 -07:00
866a6ff589 chore: more cleaning 2026-03-30 23:55:08 -07:00
af0b2c6fdd refactor: more entrypoint simplifications
initial model calculated in its own function
2026-03-30 23:37:04 -07:00
3e3ac05b05 refactor: cleanup entry point 2026-03-30 23:30:57 -07:00
4fb97c89ed fix(tests): restore coverage for toggle_group_collapse, item group, and insertion order
Rewrites three commented-out tests to access public fields directly
instead of the removed item_by_name/item_index/is_group_collapsed methods:
- add_item_in_group_sets_group: uses items.get()
- item_index_reflects_insertion_order: uses items.get_index_of()
- toggle_group_collapse_toggles_twice + involutive proptest: inspect collapsed_groups directly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 23:08:06 -07:00
c5eab1f283 chore: update gitignore 2026-03-30 23:07:42 -07:00
226029bc68 fix(tests): restore persistence round-trip assertions using items.get()
The two tests were previously silenced when item_by_name was removed.
Rewrites them using category.items.get() directly, restoring coverage
of item-name and item-group serialization round-trips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 23:02:48 -07:00
a1b17dc9af refactor: remove dead code, replace sum_matching tests with evaluate()
Removes unused methods (sum_matching, get_mut, item_by_name, item_index,
top_level_groups, is_group_collapsed, show_item) and unused constants
(LABEL_THRESHOLD, MIN_COL_WIDTH).

The sum_matching tests in model.rs were bypassing the formula evaluator
entirely. Replaced them with equivalent tests that call evaluate() against
the existing Total = SUM(Revenue) formula, exercising the real aggregation
code path.

Also fixes a compile error in view.rs prop_tests where View/Axis imports
and a doc comment were incorrectly commented out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:56:04 -07:00
15f7fbe799 chore: add rust-analyzer to nix dev shell
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 22:55:44 -07:00
f58ca625cc chore: misc nix/direnv changes 2026-03-30 22:29:12 -07:00
856b5d5d41 chore: reformat 2026-03-30 22:28:45 -07:00
f19f503ab1 chore: update flake lock 2026-03-30 22:27:24 -07:00