From 417cee4eeeaf7516dfeb59cdbe34fed18f30e0f7 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sun, 28 Jul 2024 12:50:02 +0200 Subject: add statusbar widget --- src/widgets/luaeditor/buffer.rs | 8 ++++- src/widgets/luaeditor/cursor.rs | 2 +- src/widgets/luaeditor/mod.rs | 71 ++++++++++++++++++++++++++--------------- 3 files changed, 53 insertions(+), 28 deletions(-) (limited to 'src/widgets/luaeditor') diff --git a/src/widgets/luaeditor/buffer.rs b/src/widgets/luaeditor/buffer.rs index 905950e..3f59b6c 100644 --- a/src/widgets/luaeditor/buffer.rs +++ b/src/widgets/luaeditor/buffer.rs @@ -2,7 +2,7 @@ use std::str::FromStr; use super::cursor::{Cursor, CursorMove}; -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct Buffer { lines: Vec, cursor: Cursor, @@ -157,6 +157,12 @@ impl Buffer { pub fn lines(&self) -> &Vec { &self.lines } + + pub fn set_lines(&mut self, lines: Vec) { + self.lines = lines; + self.cursor.move_checked(CursorMove::Jump((0, 0))); + self.refresh_max(); + } } impl FromStr for Buffer { diff --git a/src/widgets/luaeditor/cursor.rs b/src/widgets/luaeditor/cursor.rs index c4466d0..e051231 100644 --- a/src/widgets/luaeditor/cursor.rs +++ b/src/widgets/luaeditor/cursor.rs @@ -11,7 +11,7 @@ pub enum CursorMove { Jump((usize, usize)), } -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub struct Cursor { x: isize, y: isize, diff --git a/src/widgets/luaeditor/mod.rs b/src/widgets/luaeditor/mod.rs index 63e3d65..98af9e5 100644 --- a/src/widgets/luaeditor/mod.rs +++ b/src/widgets/luaeditor/mod.rs @@ -1,11 +1,8 @@ -use std::str::FromStr; - use ratatui::{ crossterm::event::{KeyCode, KeyEvent}, - prelude::BlockExt, - style::Stylize, - text::ToSpan, - widgets::{Block, Widget}, + style::{Style, Stylize}, + text::{ToLine, ToSpan}, + widgets::Widget, }; pub mod buffer; @@ -18,31 +15,27 @@ use tree_sitter_highlight::HighlightConfiguration; use self::cursor::CursorMove; -pub struct LuaEditor<'a> { - block: Option>, +use super::statusbar::StatusBar; + +pub struct LuaEditor { + bar: StatusBar, scroll: usize, buffer: Buffer, highlight_config: HighlightConfiguration, } -impl<'a> LuaEditor<'a> { - pub fn new(content: S) -> Self - where - S: AsRef, - { +impl LuaEditor { + pub fn new() -> Self { Self { - block: None, + bar: StatusBar::new() + .left(" [No Name] ") + .left_style(Style::default().on_magenta()), scroll: 0, - buffer: Buffer::from_str(content.as_ref()).unwrap(), + buffer: Buffer::new(), highlight_config: treesitter::new_highlight_configuration(), } } - pub fn block(mut self, block: Option>) -> Self { - self.block = block; - self - } - pub fn handle_key_event(&mut self, event: KeyEvent) { match event.code { KeyCode::Char(c) => self.buffer.insert(c), @@ -79,30 +72,42 @@ impl<'a> LuaEditor<'a> { } } + pub fn set_text(&mut self, content: S) + where + S: AsRef, + { + self.buffer + .set_lines(content.as_ref().lines().map(|s| s.to_string()).collect()) + } + pub fn text(&self) -> String { self.buffer.lines().join("\n") } } -impl Widget for &mut LuaEditor<'_> { +impl Widget for &mut LuaEditor { fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) where Self: Sized, { - self.block.render(area, buf); - let inner_area = self.block.inner_if_some(area); + self.bar.render(area, buf); + let inner_area = self.bar.area(area); let text = self.text(); let highlights = treesitter::highlighter_split(text.as_bytes(), &self.highlight_config); - let mut span_area = inner_area.clone(); + let nr_width = (self.buffer.lines().len().to_string().len() + 1).max(4) as u16; + let mut text_area = inner_area.clone(); + text_area.x += nr_width; + + let mut span_area = text_area.clone(); let mut current_line = 0; for (hl, group) in highlights.iter() { if *group == "\n" { if current_line >= self.scroll { span_area.y += 1; - span_area.x = inner_area.x; + span_area.x = text_area.x; } current_line += 1; @@ -118,7 +123,21 @@ impl Widget for &mut LuaEditor<'_> { } } - let mut cursor_area = inner_area.clone(); + for i in self.scroll..self.buffer.lines().len() { + let mut nr_area = span_area.clone(); + nr_area.x = inner_area.x; + nr_area.width = nr_width - 1; + nr_area.y = inner_area.y + (i - self.scroll) as u16; + nr_area.height = 1; + + if !inner_area.contains(nr_area.into()) { + break; + } + + (i + 1).to_line().right_aligned().render(nr_area, buf); + } + + let mut cursor_area = text_area.clone(); cursor_area.width = 1; cursor_area.height = 1; cursor_area.y += self.buffer.cursor().y() as u16; -- cgit v1.2.3-70-g09d2