use ratatui::buffer::Buffer as Surface;
use ratatui::layout::Rect;
use ratatui::text::{Line, Span};
use ratatui::widgets::Widget;
use unicode_width::UnicodeWidthStr;
use crate::app::state::Status;
use crate::theme::Theme;
pub struct CommandBar<'a> {
pub command: Option<&'a str>,
pub status: &'a Status,
pub theme: &'a Theme,
}
impl CommandBar<'_> {
#[must_use]
pub fn caret_position(&self, area: Rect) -> Option<(u16, u16)> {
let command = self.command?;
let column = u16::try_from(command.width()).unwrap_or(u16::MAX);
Some((
area.x
.saturating_add(1 + column)
.min(area.right().saturating_sub(1)),
area.y,
))
}
}
impl Widget for CommandBar<'_> {
fn render(self, area: Rect, surface: &mut Surface) {
if area.is_empty() {
return;
}
surface.set_style(area, self.theme.command);
let line = match self.command {
Some(command) => Line::from(vec![
Span::styled(":", self.theme.command),
Span::styled(command, self.theme.command),
]),
None if self.status.text.is_empty() => return,
None => {
let style = if self.status.is_error {
self.theme.command.patch(self.theme.command_error)
} else {
self.theme.command
};
Line::from(Span::styled(self.status.text.as_str(), style))
}
};
line.render(area, surface);
}
}