1use ratatui::Frame;
5use ratatui::layout::Rect;
6use ratatui::style::{Modifier, Style};
7use ratatui::text::{Line, Span};
8use ratatui::widgets::{Block, Clear, Paragraph};
9
10use crate::keymap::KEYMAP;
11use crate::state::Focus;
12
13const EX_COMMANDS: &[(&str, &str)] = &[
14 (":q :quit", "quit"),
15 (":help", "this overlay"),
16 (":reload", "rebuild the snapshot from the vault"),
17 (":profile <name|all>", "set the profile scope"),
18 (
19 ":find ..tag ::cat --todo --since D --until D --filter E",
20 "",
21 ),
22 (":search <words>", "full text (zetetes hybrid, else bm25)"),
23 (":goto <ref>", "jump to --N or --profile--N"),
24 (":backlinks [<ref>]", "jots referencing a jot"),
25];
26
27pub fn draw(f: &mut Frame) {
28 let mut lines = vec![section("keys")];
29 for b in KEYMAP.iter().filter(|b| b.bar.is_some()) {
30 let ctx = match (b.when.focus, b.when.results_only) {
31 (_, true) => " (results)",
32 (Some(Focus::List), _) => " (list)",
33 (Some(Focus::View), _) => " (view)",
34 (None, _) => "",
35 };
36 lines.push(Line::from(vec![
37 Span::styled(
38 format!(" {:>6} ", b.key_label),
39 Style::new().add_modifier(Modifier::BOLD),
40 ),
41 Span::raw(b.action_label),
42 Span::styled(ctx, Style::new().add_modifier(Modifier::DIM)),
43 ]));
44 }
45 lines.push(Line::default());
46 lines.push(section("ex commands"));
47 for (cmd, what) in EX_COMMANDS {
48 lines.push(Line::from(vec![
49 Span::styled(
50 format!(" {cmd}"),
51 Style::new().add_modifier(Modifier::BOLD),
52 ),
53 Span::styled(
54 if what.is_empty() {
55 String::new()
56 } else {
57 format!(" — {what}")
58 },
59 Style::new().add_modifier(Modifier::DIM),
60 ),
61 ]));
62 }
63
64 let area = f.area();
65 let w = 64.min(area.width.saturating_sub(2)).max(1);
66 let h = (lines.len() as u16 + 2)
67 .min(area.height.saturating_sub(1))
68 .max(1);
69 let rect = Rect {
70 x: area.x + (area.width.saturating_sub(w)) / 2,
71 y: area.y + (area.height.saturating_sub(h)) / 2,
72 width: w,
73 height: h,
74 };
75 f.render_widget(Clear, rect);
76 f.render_widget(
77 Paragraph::new(lines).block(Block::bordered().title(" help ")),
78 rect,
79 );
80}
81
82fn section(title: &'static str) -> Line<'static> {
83 Line::from(Span::styled(
84 title,
85 Style::new().add_modifier(Modifier::BOLD | Modifier::UNDERLINED),
86 ))
87}