71 lines
3.7 KiB
Markdown
71 lines
3.7 KiB
Markdown
# Plan — help modal (cbd-tui)
|
|
|
|
Ordered tasks for the `implement` stage. Inputs: `architecture/help-modal.md`,
|
|
stubs in `cbd-tui/src/app/{bindings,help,mod}.rs`, gates in
|
|
`quality/help-modal.md`. Run tests with `devenv shell -- cargo test -p cbd-tui`.
|
|
|
|
## 1. Binding lookup
|
|
|
|
- [x] Implement `bindings::lookup`: scan `BINDINGS` in order; when `help_open`
|
|
only `Scope::Help` entries are eligible, otherwise `Scope::Global` plus
|
|
the scope matching `focus`. Compare chords with `SHIFT` ignored for
|
|
`KeyCode::Char` codes, exact modifiers otherwise. Return the first match.
|
|
**Verify**: all `app::bindings::tests::*lookup*`-related tests pass
|
|
(`global_bindings_match_in_any_focus`,
|
|
`pane_bindings_only_match_their_own_pane`, `same_chord_resolves_per_pane`,
|
|
`shift_is_ignored_for_char_codes`, `control_must_match_exactly`,
|
|
`open_help_swallows_everything_but_close`,
|
|
`help_scope_never_matches_while_help_is_closed`).
|
|
- [x] Implement `bindings::key_label`: `Char(' ')` → `"Space"`, other chars →
|
|
the char itself, `Tab`/`Enter`/`Esc` named, `CONTROL` prefix `"Ctrl+"`;
|
|
no panic on any input (fall back to `Debug`-ish formatting for unbound
|
|
codes). **Verify**: `key_labels_are_human_readable` passes; gate "no
|
|
panics on user input".
|
|
|
|
## 2. Action dispatch
|
|
|
|
- [x] Implement `App::dispatch` as one `match action` reproducing, arm for
|
|
arm, the behavior of the old key match in `main.rs` (send via `self.tx`
|
|
with `let _ =`, or call `self.library`/`self.queue` methods).
|
|
`OpenHelp`/`CloseHelp` set `show_help`; `Quit` returns
|
|
`DispatchResult::Quit`; everything else `Continue`.
|
|
**Verify**: all `app::tests::*` pass; gate "behavior parity" (cross-check
|
|
against the pre-change `main.rs` match arm by arm).
|
|
|
|
## 3. Wire the event loop
|
|
|
|
- [x] Replace the key match in `main.rs run_ui` with: on key press,
|
|
`bindings::lookup(app.focus, app.show_help, key)` then
|
|
`app.dispatch(action)`, breaking the loop on `DispatchResult::Quit`.
|
|
Keep the `KeyEventKind::Press` filter. Remove the now-dead imports
|
|
(`KeyCode`, `KeyModifiers`, `UiFocus`, `MessageFromUi` uses that move
|
|
into `dispatch`). **Verify**: `cargo check` clean, no key handling left
|
|
in `main.rs` (gate "single source of truth"); manual smoke via `?`.
|
|
|
|
## 4. Help modal rendering
|
|
|
|
- [x] Implement `help::popup_area`: content-sized centered `Rect` clamped to
|
|
the frame. **Verify**: `popup_never_exceeds_the_frame`.
|
|
- [x] Implement `help::render`: `Clear` the popup area, draw a bordered block
|
|
(style matching the panes: rounded borders, `COLOR_PRIMARY`), a short
|
|
usage paragraph naming the Library and Queue panes and `Tab` to switch,
|
|
then `BINDINGS` grouped by scope in table order with labels from
|
|
`key_label`. Truncate lines that don't fit; never panic on tiny frames.
|
|
**Verify**: `help_lists_bindings_from_the_table`,
|
|
`help_explains_basic_usage`, `help_survives_tiny_terminals` pass; gates
|
|
"modality" (overlay drawn last, `Clear` used) and "no panics".
|
|
|
|
## 5. Polish and gates
|
|
|
|
- [x] Resolve the `TODO(api-design)` on `LibraryQueueNext`: check what
|
|
`MessageFromUi::QueueTracks` does in `crabidy-server` and fix the
|
|
description text if needed. **Verify**: gate "TODO resolved".
|
|
- [x] Sweep: doc comments still accurate, no dead-code warnings left for
|
|
`bindings`/`help`, no new dependencies.
|
|
**Verify**: `devenv shell -- cargo fmt --check`,
|
|
`devenv shell -- cargo clippy -p cbd-tui` (no new warnings),
|
|
`devenv shell -- cargo test -p cbd-tui` all green; every box in
|
|
`quality/help-modal.md` checked.
|
|
- [x] Write `plan/summary.md` (or a `help-modal` section in it) recording any
|
|
deviations from this plan.
|