use ratatui::buffer::Buffer as Surface;
use ratatui::layout::Rect;
use ratatui::text::{Line, Span};
use ratatui::widgets::Widget;
use crate::app::mode::Mode;
use crate::editor::cursor::Position;
use crate::editor::document::LineEnding;
use crate::theme::Theme;
pub struct StatusBar<'a> {
pub mode: Mode,
pub name: &'a str,
pub dirty: bool,
pub language: &'a str,
pub position: Position,
pub line_count: usize,
pub line_ending: LineEnding,
pub cursor_count: usize,
pub theme: &'a Theme,
}
impl Widget for StatusBar<'_> {
fn render(self, area: Rect, surface: &mut Surface) {
if area.is_empty() {
return;
}
surface.set_style(area, self.theme.status);
let mut left = vec![
Span::styled(format!(" {} ", self.mode.name()), self.theme.status_mode),
Span::styled(format!(" {}", self.name), self.theme.status),
];
if self.dirty {
left.push(Span::styled(" ●", self.theme.status_dirty));
}
if self.cursor_count > 1 {
left.push(Span::styled(
format!(" {} cursors", self.cursor_count),
self.theme.status,
));
}
let right = Line::from(Span::styled(
format!(
" {} {} {}:{} {}% ",
self.language,
self.line_ending.label(),
self.position.line + 1,
self.position.col + 1,
self.scroll_percentage(),
),
self.theme.status,
))
.right_aligned();
Line::from(left).render(area, surface);
right.render(area, surface);
}
}
impl StatusBar<'_> {
fn scroll_percentage(&self) -> usize {
let last = self.line_count.saturating_sub(1);
(self.position.line * 100).checked_div(last).unwrap_or(100)
}
}