From 30c375b6c552c8d41136cf161bd62c35660bd99b Mon Sep 17 00:00:00 2001 From: vikingowl Date: Wed, 15 Oct 2025 06:35:42 +0200 Subject: [PATCH] feat(tui): revamp help overlay with panel focus shortcuts and accessibility cues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rename “PANEL NAVIGATION” to “PANEL FOCUS” and document Ctrl/Alt + 1‑5 panel focus shortcuts. - Consolidate navigation, scrolling, and layout controls into clearer sections. - Add “VISIBLE CUES”, “ACCESSIBILITY”, and “LAYOUT CONTROLS” headings with high‑contrast and screen‑reader tips. - Update editing, sending, and normal‑mode shortcuts, including new Cmd‑P palette and Ctrl/Alt + 5 focus shortcut. - Extend visual‑mode help with focus shortcuts for Thinking/Agent panels. - Refine provider/model picker, theme browser, command palette, repo search, and symbol search descriptions. - Include “TIPS” section highlighting slash commands and focus behavior. --- crates/owlen-tui/src/ui.rs | 176 +++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 68 deletions(-) diff --git a/crates/owlen-tui/src/ui.rs b/crates/owlen-tui/src/ui.rs index d9f7ffb..7190ae0 100644 --- a/crates/owlen-tui/src/ui.rs +++ b/crates/owlen-tui/src/ui.rs @@ -3298,95 +3298,103 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) { // Navigation Line::from(""), Line::from(vec![Span::styled( - "PANEL NAVIGATION", + "PANEL FOCUS", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Tab → cycle panels forward"), - Line::from(" Shift+Tab → cycle panels backward"), - Line::from(" (Panels: Files, Chat, Thinking, Actions, Input, Code)"), - Line::from(" ▌ beacon marks the active entry; bright when the pane has focus"), - Line::from(" Status bar highlights MODE, CONTEXT, and current FOCUS target"), + Line::from(" Ctrl/Alt+1 → focus Files (opens when available)"), + Line::from(" Ctrl/Alt+2 → focus Chat timeline"), + Line::from(" Ctrl/Alt+3 → focus Code view (requires open file)"), + Line::from(" Ctrl/Alt+4 → focus Thinking / Agent Actions"), + Line::from(" Ctrl/Alt+5 → focus Input editor"), + Line::from(" Tab / Shift+Tab → cycle panels forward/backward"), Line::from(""), Line::from(vec![Span::styled( - "CURSOR MOVEMENT", + "VISIBLE CUES", + Style::default().add_modifier(Modifier::BOLD).fg(theme.info), + )]), + Line::from(" ▌ beacon highlights the active row; brighter when focused"), + Line::from(" Status bar shows MODE · workspace · focus target + shortcut"), + Line::from(" Agent badge flips between 🤖 RUN and 🤖 ARM when automation changes"), + Line::from(" Use :themes to swap palettes—default_dark is tuned for contrast"), + Line::from(""), + Line::from(vec![Span::styled( + "LAYOUT CONTROLS", + Style::default().add_modifier(Modifier::BOLD).fg(theme.info), + )]), + Line::from(" Ctrl+←/→ → resize files panel"), + Line::from(" Ctrl+↑/↓ → adjust chat ↔ thinking split"), + Line::from(" Alt+←/→/↑/↓ → resize focused code pane"), + Line::from(" g then t → expand files panel and focus it"), + Line::from(" F1 or ? → toggle this help overlay"), + Line::from(""), + Line::from(vec![Span::styled( + "SCROLLING & MOVEMENT", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), Line::from(" h/← l/→ → move left/right by character"), Line::from(" j/↓ k/↑ → move down/up by line"), - Line::from(" w → forward to next word start"), - Line::from(" e → forward to word end"), - Line::from(" b → backward to previous word"), - Line::from(" 0 / Home → start of line"), - Line::from(" ^ → first non-blank character"), - Line::from(" $ / End → end of line"), - Line::from(" gg → jump to top"), - Line::from(" G → jump to bottom"), + Line::from(" w / e / b → jump by words (start / end / previous)"), + Line::from(" 0 / ^ / $ → line start / first non-blank / line end"), + Line::from(" gg / G → jump to top / bottom"), + Line::from(" Ctrl+d / Ctrl+u → half-page scroll down/up"), + Line::from(" Ctrl+f / Ctrl+b → full-page scroll down/up"), + Line::from(" PageUp / PageDown → full-page scroll"), Line::from(""), Line::from(vec![Span::styled( - "SCROLLING", + "ACCESSIBILITY", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Ctrl+d/u → scroll half page down/up"), - Line::from(" Ctrl+f/b → scroll full page down/up"), - Line::from(" PageUp/Down → scroll full page"), - Line::from(""), - Line::from(vec![Span::styled( - "HELP & QUICK COMMANDS", - Style::default().add_modifier(Modifier::BOLD).fg(theme.info), - )]), - Line::from(" F1 / ? → toggle help overlay"), - Line::from(" :h, :help → open help from command mode"), - Line::from(" :files, :explorer → toggle files panel"), - Line::from(" :markdown [on|off] → toggle markdown rendering"), - Line::from(" Ctrl+←/→ → resize files panel"), - Line::from(" Ctrl+↑/↓ → resize chat/thinking split"), - Line::from(vec![Span::styled( - "GIT COLORS", - Style::default().add_modifier(Modifier::BOLD).fg(theme.info), - )]), - Line::from(" Green → added · Yellow → modified/staged · Red → deleted/conflict"), + Line::from(" High-contrast defaults keep text legible in low-light terminals"), + Line::from(" Focus shortcuts avoid chords—great with screen readers"), + Line::from(" Thinking and Agent Actions share the Ctrl/Alt+4 focus key"), ], 1 => vec![ // Editing Line::from(""), Line::from(vec![Span::styled( - "ENTERING INSERT MODE", + "ENTERING EDIT MODE", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" i / Enter → enter insert mode at cursor"), - Line::from(" a → append after cursor"), - Line::from(" A → append at end of line"), - Line::from(" I → insert at start of line"), - Line::from(" o → insert line below and enter insert mode"), - Line::from(" O → insert line above and enter insert mode"), + Line::from(" i or Enter → focus input and begin editing at cursor"), + Line::from(" a / A / I → append after cursor · append at end · insert at start"), + Line::from(" o / O → open new line below / above and edit"), + Line::from(" Ctrl/Alt+5 → jump to the input panel from any view"), Line::from(""), Line::from(vec![Span::styled( - "ENTER KEY BEHAVIOUR", + "SENDING & NEWLINES", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Normal mode → press Enter to send the current message"), - Line::from(" Insert mode → Enter sends · Shift+Enter inserts newline"), + Line::from(" Enter → send message (slash commands run before send)"), + Line::from(" Shift+Enter → insert newline without leaving edit mode"), + Line::from(" Ctrl+J → insert newline (multiline compose)"), + Line::from(" Esc / Ctrl+[ → return to normal mode"), Line::from(""), Line::from(vec![Span::styled( - "INSERT MODE KEYS", + "EDITING UTILITIES", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Enter → send message"), - Line::from(" Ctrl+J → insert newline (multiline message)"), - Line::from(" Ctrl+↑/↓ → navigate input history"), - Line::from(" Ctrl+A → jump to start of line"), - Line::from(" Ctrl+E → jump to end of line"), - Line::from(" Ctrl+W → word forward"), - Line::from(" Ctrl+B → word backward"), - Line::from(" Ctrl+R → redo"), - Line::from(" Esc → return to normal mode"), + Line::from(" Ctrl+↑ / Ctrl+↓ → cycle input history"), + Line::from(" Ctrl+A / Ctrl+E → jump to start / end of line"), + Line::from(" Ctrl+W / Ctrl+B → move cursor by words forward/back"), + Line::from(" Ctrl+P → open command palette without exiting edit mode"), + Line::from(" Ctrl+C → cancel streaming response and exit editing"), Line::from(""), Line::from(vec![Span::styled( - "NORMAL MODE OPERATIONS", + "NORMAL MODE SHORTCUTS", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), Line::from(" dd → clear input buffer"), - Line::from(" p → paste from clipboard to input"), + Line::from(" p → paste clipboard into input"), + Line::from(" Ctrl+P → open command palette (also works in Normal)"), + Line::from(""), + Line::from(vec![Span::styled( + "TIPS", + Style::default() + .add_modifier(Modifier::BOLD) + .fg(theme.user_message_role), + )]), + Line::from(" • Slash commands (e.g. :clear, :open) are parsed before sending"), + Line::from(" • After sending, focus returns to Normal—press i or Ctrl/Alt+5 to edit"), ], 2 => vec![ // Visual @@ -3395,7 +3403,9 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) { "VISUAL MODE", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" v → enter visual mode at cursor"), + Line::from(" v → enter visual mode at cursor (from normal mode)"), + Line::from(" Ctrl/Alt+4 → focus Thinking/Agent panels before selecting"), + Line::from(" Ctrl/Alt+5 → return focus to Input after selection work"), Line::from(""), Line::from(vec![Span::styled( "SELECTION MOVEMENT", @@ -3414,7 +3424,7 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) { Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), Line::from(" y → yank (copy) selection to clipboard"), - Line::from(" d / Delete → cut selection (Input panel only)"), + Line::from(" d / Delete → cut selection (yank from read-only panels)"), Line::from(" v / Esc → exit visual mode"), Line::from(""), Line::from(vec![Span::styled( @@ -3425,6 +3435,7 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) { )]), Line::from(" • Visual mode works across all panels (Chat, Thinking, Input)"), Line::from(" • Yanked text is available for paste with 'p' in normal mode"), + Line::from(" • Read-only panels (Chat/Thinking) always keep data intact; yank copies"), ], 3 => vec![ // Commands @@ -3586,22 +3597,51 @@ fn render_help(frame: &mut Frame<'_>, app: &ChatApp) { // Browsers Line::from(""), Line::from(vec![Span::styled( - "PROVIDER & MODEL BROWSERS", + "PROVIDER & MODEL PICKERS", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Enter → select item"), - Line::from(" Esc → close browser"), - Line::from(" ↑/↓ or j/k → navigate items"), + Line::from(" m or :model → open provider selector (if multiple providers)"), + Line::from(" ↑/↓ or j/k → navigate providers"), + Line::from(" Enter → confirm provider and open model list"), + Line::from(" Space / ←/→ → collapse or expand provider groups"), + Line::from(" i / r → show or refresh model info side panel"), + Line::from(" q / Esc → close selector"), Line::from(""), Line::from(vec![Span::styled( - "THEME BROWSER", + "THEME BROWSER (:themes)", Style::default().add_modifier(Modifier::BOLD).fg(theme.info), )]), - Line::from(" Enter → apply theme"), - Line::from(" Esc / q → close browser"), Line::from(" ↑/↓ or j/k → navigate themes"), - Line::from(" g / Home → jump to top"), - Line::from(" G / End → jump to bottom"), + Line::from(" g / G / Home / End → jump to top or bottom"), + Line::from(" Enter → apply highlighted theme"), + Line::from(" Esc / q → close browser"), + Line::from(""), + Line::from(vec![Span::styled( + "COMMAND PALETTE (Ctrl+P or ':')", + Style::default().add_modifier(Modifier::BOLD).fg(theme.info), + )]), + Line::from(" Tab / Shift+Tab → accept suggestion / cycle backwards"), + Line::from(" ↑/↓ → navigate grouped suggestions"), + Line::from(" Enter → run highlighted command"), + Line::from(" Esc → cancel"), + Line::from(""), + Line::from(vec![Span::styled( + "REPO SEARCH (Ctrl+Shift+F)", + Style::default().add_modifier(Modifier::BOLD).fg(theme.info), + )]), + Line::from(" Type pattern → update ripgrep query"), + Line::from(" Enter → run search or open highlighted match"), + Line::from(" Alt+Enter → send matches to scratch buffer"), + Line::from(" ↑/↓ or j/k → move between matches · PageUp/Down jump pages"), + Line::from(" Esc → close search"), + Line::from(""), + Line::from(vec![Span::styled( + "SYMBOL SEARCH (Ctrl+Shift+P)", + Style::default().add_modifier(Modifier::BOLD).fg(theme.info), + )]), + Line::from(" Type to filter → fuzzy search indexed symbols"), + Line::from(" Enter → jump to symbol in code view"), + Line::from(" ↑/↓ or j/k → navigate · Esc closes"), ], 6 => vec![],