diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-02 11:38:19 +0200 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2024-08-02 11:38:19 +0200 |
| commit | 04a5a938994ddb95cfaa9a74b180e457d3a2b5d0 (patch) | |
| tree | 31ce9525ed3f3423678397323b65c910d63eadb1 /src/widgets/luaeditor | |
| parent | fe0938b1de0c46fc2afcaa3dcd6a0f4ec870d21a (diff) | |
implement new lua interface
Diffstat (limited to 'src/widgets/luaeditor')
| -rw-r--r-- | src/widgets/luaeditor/buffer.rs | 180 | ||||
| -rw-r--r-- | src/widgets/luaeditor/mod.rs | 96 |
2 files changed, 49 insertions, 227 deletions
diff --git a/src/widgets/luaeditor/buffer.rs b/src/widgets/luaeditor/buffer.rs deleted file mode 100644 index 1427bdb..0000000 --- a/src/widgets/luaeditor/buffer.rs +++ /dev/null @@ -1,180 +0,0 @@ -use std::str::FromStr; - -use crate::cursor::{Cursor, CursorMove}; - -#[derive(Default, Debug, Clone)] -pub struct Buffer { - lines: Vec<String>, - cursor: Cursor, -} - -impl Buffer { - pub fn new() -> Self { - Self { - lines: Vec::new(), - cursor: Cursor::new().with_position(0, 0).with_max(0, 0), - } - } - - fn refresh_line_max(&mut self) { - self.cursor.set_x_max(self.lines[self.cursor.y()].len()) - } - - fn refresh_buffer_max(&mut self) { - self.cursor.set_y_max(self.lines.len() - 1); - } - - fn refresh_max(&mut self) { - self.refresh_line_max(); - self.refresh_buffer_max(); - } - - fn end_balance(&self, level: usize) -> isize { - let str = "\t".repeat(level); - let start_count = self - .lines - .iter() - .filter(|s| { - s.starts_with(&(str.clone() + "if ")) - || s.starts_with(&(str.clone() + "for ")) - || s.starts_with(&(str.clone() + "while ")) - || (s.starts_with(&str) && s.contains("function(") && s.ends_with(')')) - }) - .count(); - - let end_count = self - .lines - .iter() - .filter(|s| s.starts_with(&(str.clone() + "end ")) || **s == (str.clone() + "end")) - .count(); - - (end_count as isize) - (start_count as isize) - } - - pub fn insert(&mut self, c: char) { - match c { - '\n' => { - let (a, b) = { - let line = self.current_line(); - let (a, b) = line.split_at(self.cursor.x()); - (a.to_string(), b.to_string()) - }; - - let indent_normalized = a.replace(" ", "\t"); - let indent = indent_normalized.len() - indent_normalized.trim_start().len(); - let l = a.trim(); - let insert_end = (l.starts_with("if ") && l.ends_with(" then")) - || ((l.starts_with("for ") || l.starts_with("while ")) && l.ends_with(" do")) - || (l.contains("function(") && l.ends_with(')')); - - let extra_indent = if insert_end { 1 } else { 0 }; - - { - *self.current_line_mut() = a; - } - self.cursor.move_unchecked(CursorMove::Down(1)); - self.cursor.move_unchecked(CursorMove::Begin); - self.lines - .insert(self.cursor().y(), "\t".repeat(indent + extra_indent) + &b); - - if insert_end && self.end_balance(indent) < 0 { - self.lines - .insert(self.cursor().y() + 1, "\t".repeat(indent) + "end"); - } - - self.refresh_max(); - self.cursor - .move_checked(CursorMove::Right(indent + extra_indent)); - } - _ => { - let x = self.cursor().x(); - self.current_line_mut().insert(x, c); - self.refresh_line_max(); - self.cursor.move_checked(CursorMove::Right(1)); - } - } - } - - pub fn delete(&mut self) { - if self.cursor.is_at_start() && !self.cursor.is_at_top() { - let old_line = self.current_line_mut().clone(); - self.lines.remove(self.cursor.y()); - self.cursor.move_checked(CursorMove::Up(1)); - self.refresh_line_max(); - - let new_x = self.current_line().len(); - self.current_line_mut().push_str(&old_line); - self.cursor - .move_checked(CursorMove::Jump((new_x, self.cursor.y()))); - - self.refresh_buffer_max() - } else { - let x = self.cursor.x() - 1; - self.current_line_mut().remove(x); - self.refresh_line_max(); - self.cursor.move_checked(CursorMove::Left(1)); - } - } - - pub fn line(&self, index: usize) -> Option<&String> { - self.lines.get(index) - } - - fn line_mut(&mut self, index: usize) -> Option<&mut String> { - self.lines.get_mut(index) - } - - pub fn current_line(&self) -> &String { - self.line(self.cursor.y()).unwrap() - } - - fn current_line_mut(&mut self) -> &mut String { - self.line_mut(self.cursor.y()).unwrap() - } - - pub fn cursor(&self) -> &Cursor { - &self.cursor - } - - pub fn move_cursor(&mut self, m: CursorMove) { - match m { - CursorMove::Up(_) - | CursorMove::Down(_) - | CursorMove::Top - | CursorMove::Bottom - | CursorMove::Relative(_) - | CursorMove::Jump(_) => { - self.cursor.move_checked(m); - self.cursor.set_x_max(self.current_line().len()); - self.cursor.correct_cursor_position(); - } - CursorMove::Left(_) | CursorMove::Right(_) | CursorMove::Begin | CursorMove::End => { - self.cursor.move_checked(m) - } - } - } - - pub fn lines(&self) -> &Vec<String> { - &self.lines - } - - pub fn set_lines(&mut self, lines: Vec<String>) { - self.lines = lines; - self.cursor.move_checked(CursorMove::Jump((0, 0))); - self.refresh_max(); - } -} - -impl FromStr for Buffer { - type Err = (); - - fn from_str(s: &str) -> Result<Self, Self::Err> { - let lines: Vec<_> = s.lines().map(|s| s.to_string()).collect(); - let mut buffer = Self::new(); - buffer.lines = lines; - - buffer.refresh_max(); - - Ok(buffer) - } -} diff --git a/src/widgets/luaeditor/mod.rs b/src/widgets/luaeditor/mod.rs index 6fc8436..de35c3d 100644 --- a/src/widgets/luaeditor/mod.rs +++ b/src/widgets/luaeditor/mod.rs @@ -1,25 +1,22 @@ use ratatui::{ - crossterm::event::{KeyCode, KeyEvent}, + crossterm::event::{KeyCode, KeyEvent, KeyModifiers}, style::{Style, Stylize}, text::{ToLine, ToSpan}, widgets::Widget, }; - -pub mod buffer; -pub mod theme; -pub mod treesitter; - -use buffer::Buffer; use tree_sitter_highlight::HighlightConfiguration; -use crate::cursor::CursorMove; +use crate::state::{editor::EditorState, window::Window, GlobalState}; +use crate::{cursor::CursorMove, lua}; use super::statusbar::StatusBar; +pub mod theme; +pub mod treesitter; + pub struct LuaEditor { bar: StatusBar, scroll: usize, - buffer: Buffer, highlight_config: HighlightConfiguration, } @@ -30,35 +27,53 @@ impl LuaEditor { .left(" [No Name] ") .left_style(Style::default().on_magenta()), scroll: 0, - buffer: Buffer::new(), highlight_config: treesitter::new_highlight_configuration(), } } pub fn handle_key_event(&mut self, event: KeyEvent) { match event.code { - KeyCode::Char(c) => self.buffer.insert(c), + KeyCode::Char('r') if event.modifiers == KeyModifiers::CONTROL => { + EditorState::run(&lua::get()) + } + KeyCode::Char(c) => GlobalState::instance_mut().editor.buffer.insert(c), KeyCode::Backspace => { - self.buffer.delete(); + GlobalState::instance_mut().editor.buffer.delete(); } KeyCode::Enter => { - self.buffer.insert('\n'); + GlobalState::instance_mut().editor.buffer.insert('\n'); } - KeyCode::Left => self.buffer.move_cursor(CursorMove::Left(1)), - KeyCode::Right => self.buffer.move_cursor(CursorMove::Right(1)), - KeyCode::Up => self.buffer.move_cursor(CursorMove::Up(1)), - KeyCode::Down => self.buffer.move_cursor(CursorMove::Down(1)), + KeyCode::Left => GlobalState::instance_mut() + .editor + .buffer + .move_cursor(CursorMove::Left(1)), + KeyCode::Right => GlobalState::instance_mut() + .editor + .buffer + .move_cursor(CursorMove::Right(1)), + KeyCode::Up => GlobalState::instance_mut() + .editor + .buffer + .move_cursor(CursorMove::Up(1)), + KeyCode::Down => GlobalState::instance_mut() + .editor + .buffer + .move_cursor(CursorMove::Down(1)), KeyCode::Home => {} KeyCode::End => {} KeyCode::PageUp => {} KeyCode::PageDown => {} - KeyCode::Tab => self.buffer.insert('\t'), + KeyCode::Tab => GlobalState::instance_mut().editor.buffer.insert('\t'), KeyCode::BackTab => {} KeyCode::Delete => {} KeyCode::Insert => {} KeyCode::F(_) => {} KeyCode::Null => {} - KeyCode::Esc => {} + KeyCode::Esc => { + let mut state = GlobalState::instance_mut(); + state.editor.visible = false; + state.set_focus(Window::View) + } KeyCode::CapsLock => {} KeyCode::ScrollLock => {} KeyCode::NumLock => {} @@ -70,18 +85,6 @@ impl LuaEditor { KeyCode::Modifier(_) => {} } } - - pub fn set_text<S>(&mut self, content: S) - where - S: AsRef<str>, - { - 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 { @@ -89,13 +92,16 @@ impl Widget for &mut LuaEditor { where Self: Sized, { + let state = GlobalState::instance(); + let buffer = &state.editor.buffer; + self.bar.render(area, buf); let inner_area = self.bar.area(area); - let text = self.text(); + let text = buffer.as_string(); let highlights = treesitter::highlighter_split(text.as_bytes(), &self.highlight_config); - let nr_width = (self.buffer.lines().len().to_string().len() + 1).max(4) as u16; + let nr_width = (buffer.lines().len().to_string().len() + 1).max(4) as u16; let mut text_area = inner_area; text_area.x += nr_width; @@ -122,7 +128,7 @@ impl Widget for &mut LuaEditor { } } - for i in self.scroll..self.buffer.lines().len() { + for i in self.scroll..buffer.lines().len() { let mut nr_area = span_area; nr_area.x = inner_area.x; nr_area.width = nr_width - 1; @@ -139,13 +145,10 @@ impl Widget for &mut LuaEditor { let mut cursor_area = text_area; cursor_area.width = 1; cursor_area.height = 1; - cursor_area.y += self.buffer.cursor().y() as u16; - cursor_area.x += self.buffer.cursor().x() as u16; + cursor_area.y += buffer.cursor().y() as u16; + cursor_area.x += buffer.cursor().x() as u16; - let (first, _) = self - .buffer - .current_line() - .split_at(self.buffer.cursor().x()); + let (first, _) = buffer.current_line().split_at(buffer.cursor().x()); for c in first.chars() { if c == '\t' { @@ -153,19 +156,19 @@ impl Widget for &mut LuaEditor { } } - if self.scroll > self.buffer.cursor().y() { - self.scroll = self.buffer.cursor().y(); - } else if inner_area.height as usize + self.scroll - 1 < self.buffer.cursor().y() { - self.scroll = self.buffer.cursor().y() - inner_area.height as usize + 1; + if self.scroll > buffer.cursor().y() { + self.scroll = buffer.cursor().y(); + } else if inner_area.height as usize + self.scroll - 1 < buffer.cursor().y() { + self.scroll = buffer.cursor().y() - inner_area.height as usize + 1; } cursor_area.y -= self.scroll as u16; if inner_area.contains(cursor_area.into()) { - self.buffer + buffer .current_line() .chars() - .nth(self.buffer.cursor().x()) + .nth(buffer.cursor().x()) .map(|c| if c == '\t' { ' ' } else { c }) .unwrap_or(' ') .to_span() @@ -181,7 +184,6 @@ impl Default for LuaEditor { highlight_config: treesitter::new_highlight_configuration(), bar: StatusBar::default(), scroll: 0, - buffer: Buffer::default(), } } } |