3.7 KiB
3.7 KiB
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
- Implement
bindings::lookup: scanBINDINGSin order; whenhelp_openonlyScope::Helpentries are eligible, otherwiseScope::Globalplus the scope matchingfocus. Compare chords withSHIFTignored forKeyCode::Charcodes, exact modifiers otherwise. Return the first match. Verify: allapp::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). - Implement
bindings::key_label:Char(' ')→"Space", other chars → the char itself,Tab/Enter/Escnamed,CONTROLprefix"Ctrl+"; no panic on any input (fall back toDebug-ish formatting for unbound codes). Verify:key_labels_are_human_readablepasses; gate "no panics on user input".
2. Action dispatch
- Implement
App::dispatchas onematch actionreproducing, arm for arm, the behavior of the old key match inmain.rs(send viaself.txwithlet _ =, or callself.library/self.queuemethods).OpenHelp/CloseHelpsetshow_help;QuitreturnsDispatchResult::Quit; everything elseContinue. Verify: allapp::tests::*pass; gate "behavior parity" (cross-check against the pre-changemain.rsmatch arm by arm).
3. Wire the event loop
- Replace the key match in
main.rs run_uiwith: on key press,bindings::lookup(app.focus, app.show_help, key)thenapp.dispatch(action), breaking the loop onDispatchResult::Quit. Keep theKeyEventKind::Pressfilter. Remove the now-dead imports (KeyCode,KeyModifiers,UiFocus,MessageFromUiuses that move intodispatch). Verify:cargo checkclean, no key handling left inmain.rs(gate "single source of truth"); manual smoke via?.
4. Help modal rendering
- Implement
help::popup_area: content-sized centeredRectclamped to the frame. Verify:popup_never_exceeds_the_frame. - Implement
help::render:Clearthe popup area, draw a bordered block (style matching the panes: rounded borders,COLOR_PRIMARY), a short usage paragraph naming the Library and Queue panes andTabto switch, thenBINDINGSgrouped by scope in table order with labels fromkey_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_terminalspass; gates "modality" (overlay drawn last,Clearused) and "no panics".
5. Polish and gates
- Resolve the
TODO(api-design)onLibraryQueueNext: check whatMessageFromUi::QueueTracksdoes incrabidy-serverand fix the description text if needed. Verify: gate "TODO resolved". - 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-tuiall green; every box inquality/help-modal.mdchecked. - Write
plan/summary.md(or ahelp-modalsection in it) recording any deviations from this plan.