1use crate::agent::ui::theme::RabTheme;
2use crate::tui::Component;
3
4pub struct HelpOverlay {
6 theme: RabTheme,
7 commands: Vec<(String, String)>,
8}
9
10impl HelpOverlay {
11 pub fn new(theme: &RabTheme) -> Self {
12 Self {
13 theme: theme.clone(),
14 commands: Vec::new(),
15 }
16 }
17
18 pub fn set_commands(&mut self, commands: Vec<(String, String)>) {
19 self.commands = commands;
20 }
21}
22
23impl Component for HelpOverlay {
24 fn render(&mut self, width: usize) -> Vec<String> {
25 let mut lines = Vec::new();
26
27 let push = |l: &mut Vec<String>, text: &str| {
29 l.push(crate::tui::util::truncate_to_width(text, width, "", true));
30 };
31
32 push(
33 &mut lines,
34 &self.theme.bold(&self.theme.accent(" Keyboard Shortcuts")),
35 );
36 lines.push(String::new());
37
38 let shortcuts = [
39 ("Enter", "Submit message"),
40 ("Ctrl+J", "Newline"),
41 ("Ctrl+C", "Interrupt / clear editor"),
42 ("Ctrl+D", "Quit (empty) / interrupt"),
43 ("Escape", "Clear editor"),
44 ("Ctrl+L", "Open model selector"),
45 ("!<command>", "Run bash inline"),
46 ("!!<command>", "Run bash (excluded from context)"),
47 ("Ctrl+T", "Toggle thinking visibility"),
48 ("Ctrl+O", "Toggle tool output"),
49 ("F1", "Show this help"),
50 ("↑↓", "History (editor empty)"),
51 ("PgUp / PgDn", "Scroll messages"),
52 ];
53
54 for (key, desc) in &shortcuts {
55 let line = format!(
56 " {:20} {}",
57 self.theme.bold(&self.theme.accent(key)),
58 self.theme.dim(desc)
59 );
60 push(&mut lines, &line);
61 }
62
63 if !self.commands.is_empty() {
64 lines.push(String::new());
65 push(
66 &mut lines,
67 &self.theme.bold(&self.theme.accent(" Slash Commands")),
68 );
69 lines.push(String::new());
70 for (name, desc) in &self.commands {
71 let line = format!(
72 " /{:<19} {}",
73 self.theme.bold(&self.theme.accent(name)),
74 self.theme.dim(desc)
75 );
76 push(&mut lines, &line);
77 }
78 }
79
80 lines.push(String::new());
81 push(
82 &mut lines,
83 &self.theme.dim(" Press any key to close help."),
84 );
85
86 lines
87 }
88
89 fn handle_input(&mut self, _key: &crossterm::event::KeyEvent) -> bool {
90 true
92 }
93}