intelli_shell/widgets/
completion.rs1use ratatui::{
2 backend::FromCrossterm,
3 buffer::Buffer,
4 layout::{Rect, Size},
5 style::{Color, Style},
6 text::{Line, Span, Text},
7 widgets::Widget,
8};
9
10use crate::{config::Theme, model::VariableCompletion};
11
12const DEFAULT_STYLE: Style = Style::new();
13
14#[derive(Clone)]
16pub struct VariableCompletionWidget<'a>(Text<'a>, Size);
17impl<'a> VariableCompletionWidget<'a> {
18 pub fn new(
20 completion: &'a VariableCompletion,
21 theme: &Theme,
22 is_highlighted: bool,
23 is_discarded: bool,
24 plain_style: bool,
25 full_content: bool,
26 ) -> Self {
27 let mut line_style = DEFAULT_STYLE;
28 if is_highlighted && let Some(bg_color) = theme.highlight {
29 line_style = line_style.bg(Color::from_crossterm(bg_color));
30 }
31 let (primary_style, secondary_style) = match (plain_style, is_discarded, is_highlighted) {
33 (_, true, false) => (theme.secondary, theme.secondary),
35 (_, true, true) => (theme.highlight_secondary, theme.highlight_secondary),
37 (true, false, false) => (theme.primary, theme.primary),
39 (true, false, true) => (theme.highlight_primary, theme.highlight_primary),
41 (false, false, false) => (theme.primary, theme.secondary),
43 (false, false, true) => (theme.highlight_primary, theme.highlight_secondary),
45 };
46
47 let mut parts = vec![
49 Span::styled(&completion.variable, Style::from_crossterm(primary_style)),
50 Span::styled(": ", Style::from_crossterm(primary_style)),
51 Span::styled(&completion.suggestions_provider, Style::from_crossterm(secondary_style)),
52 ];
53
54 if full_content {
56 parts.insert(0, Span::styled("$ ", Style::from_crossterm(primary_style)));
58 if !completion.is_global() {
60 parts.insert(1, Span::styled("(", Style::from_crossterm(primary_style)));
61 parts.insert(
62 2,
63 Span::styled(&completion.root_cmd, Style::from_crossterm(primary_style)),
64 );
65 parts.insert(3, Span::styled(") ", Style::from_crossterm(primary_style)));
66 }
67 }
68
69 let text = Text::from(vec![Line::from(parts)]).style(line_style);
70 let width = text.width() as u16;
71 let height = text.height() as u16;
72 VariableCompletionWidget(text, Size::new(width, height))
73 }
74
75 pub fn size(&self) -> Size {
77 self.1
78 }
79}
80
81impl<'a> Widget for VariableCompletionWidget<'a> {
82 fn render(self, area: Rect, buf: &mut Buffer)
83 where
84 Self: Sized,
85 {
86 self.0.render(area, buf);
87 }
88}