feat(ui): context- and state-aware bottom keybinding strip (#27)
Per ADR-0051 (closing issue #27): the bottom status line is now a keystrokes-only, state-selected strip. A pure status_bar_bindings() picks the binding set by priority (first match wins): sidebar focus → Ctrl-O next pane · ↑↓/PgUp/PgDn scroll · Esc input completion live → Tab/Shift-Tab cycle · Esc cancel · Enter run history nav → ↑↓ browse · Esc clear · Enter run editing → Esc clear · Ctrl-A/E home/end · Ctrl-W del word · Enter run default (empty) → Ctrl-O sidebar · Tab complete · ↑ history · Enter run The editing state surfaces the #29 readline keys (ADR-0049's deferred advertisement). Typed-command words (mode advanced/simple, the ':' one-shot) and Ctrl-C quit leave the strip; simple mode's empty-input hint gains a '`mode advanced` for SQL' pointer (advanced mode shows none — a switcher knows the way back, and help covers it). Mechanism: status_bar_bindings + a thin renderer (unit-testable); App::is_browsing_history() exposes the private history_cursor; the mode pointer lives in resolve_hint_lines. Catalog: 12 new shortcut labels + panel.hint_mode_advanced (en-US.yaml + keys.rs, validator 1:1), 5 dead strip strings removed. Forks user-chosen: editing state shows #29 keys; quit omitted; no width-drop machinery (longest strip ~65 cols fits; a width-budget test keeps it lean). Modal-aware strip is OOS (pre-existing). Tests: 9 Tier-1 unit (per-state key sets, width budget, mode pointer), 1 Tier-3 rewritten, 15 full-panel snapshots re-accepted (reviewed). 2467 pass / 0 fail / 0 skip, clippy clean.
This commit is contained in:
@@ -223,21 +223,30 @@ fn typing_colon_in_simple_mode_flips_prompt_to_advanced() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_bar_lists_quit_and_submit_in_all_modes() {
|
||||
fn status_bar_is_keystroke_only_and_state_aware() {
|
||||
// ADR-0051 (issue #27): the bottom strip is keystrokes-only and
|
||||
// tracks the interaction state. Typed-command words (`:` advanced
|
||||
// once, `mode advanced`/`mode simple` switch) and `Ctrl-C quit`
|
||||
// leave the strip; mode discovery moves to the hint (locked by the
|
||||
// ui.rs unit tests). This test exercises the real render path.
|
||||
let mut app = App::new();
|
||||
let theme = Theme::dark();
|
||||
|
||||
let simple = rendered_text(&mut app, &theme, 80, 24);
|
||||
assert!(simple.contains("Enter"), "status bar lists Enter");
|
||||
assert!(simple.contains("Ctrl-C"), "status bar lists Ctrl-C");
|
||||
assert!(simple.contains("mode advanced"));
|
||||
// Default (empty input): nav / complete / history / run keystrokes.
|
||||
let default_view = rendered_text(&mut app, &theme, 80, 24);
|
||||
assert!(default_view.contains("Ctrl-O sidebar"), "strip lists sidebar:\n{default_view}");
|
||||
assert!(default_view.contains("Enter run"), "strip lists run:\n{default_view}");
|
||||
assert!(!default_view.contains("Ctrl-C"), "quit dropped from the strip:\n{default_view}");
|
||||
assert!(
|
||||
!default_view.contains("advanced once"),
|
||||
"`:` command word dropped from the strip:\n{default_view}",
|
||||
);
|
||||
|
||||
type_str(&mut app, "mode advanced");
|
||||
submit(&mut app);
|
||||
let advanced = rendered_text(&mut app, &theme, 80, 24);
|
||||
assert!(advanced.contains("Enter"));
|
||||
assert!(advanced.contains("Ctrl-C"));
|
||||
assert!(advanced.contains("mode simple"));
|
||||
// Editing (input has text): the #29 readline edit keys appear.
|
||||
type_str(&mut app, "create");
|
||||
let editing = rendered_text(&mut app, &theme, 80, 24);
|
||||
assert!(editing.contains("Esc clear"), "editing strip lists clear:\n{editing}");
|
||||
assert!(editing.contains("Ctrl-W del word"), "editing strip lists del word:\n{editing}");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user