Skip to main content

cui/ui/
bars.rs

1//! The two command bars: global (top, reversed) and context
2//! (below, dim). Both render whatever `keymap::bar_items` derives
3//! from the binding table, so they cannot drift from dispatch.
4
5use ratatui::Frame;
6use ratatui::layout::Rect;
7use ratatui::style::{Modifier, Style};
8use ratatui::text::{Line, Span};
9use ratatui::widgets::Paragraph;
10
11use crate::keymap::{self, Bar};
12use crate::state::{AppState, Mode};
13
14pub fn draw(f: &mut Frame, global: Rect, context: Rect, state: &AppState) {
15    let g = bar_line(&keymap::bar_items(state, Bar::Global));
16    f.render_widget(
17        Paragraph::new(g).style(Style::new().add_modifier(Modifier::REVERSED)),
18        global,
19    );
20
21    let c = match state.mode {
22        Mode::Command => bar_line(&[("⏎", "run"), ("Esc", "cancel"), ("C-u", "clear")]),
23        Mode::Help => bar_line(&[("any key", "close")]),
24        Mode::Normal => bar_line(&keymap::bar_items(state, Bar::Context)),
25    };
26    f.render_widget(
27        Paragraph::new(c).style(Style::new().add_modifier(Modifier::DIM)),
28        context,
29    );
30}
31
32fn bar_line(items: &[(&'static str, &'static str)]) -> Line<'static> {
33    let mut spans = vec![Span::raw(" ")];
34    for (i, (key, action)) in items.iter().enumerate() {
35        if i > 0 {
36            spans.push(Span::raw("   "));
37        }
38        spans.push(Span::styled(
39            *key,
40            Style::new().add_modifier(Modifier::BOLD),
41        ));
42        spans.push(Span::raw(" "));
43        spans.push(Span::raw(*action));
44    }
45    Line::from(spans)
46}