summaryrefslogtreecommitdiff
path: root/src/widgets/luaeditor
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-08-02 11:38:19 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2024-08-02 11:38:19 +0200
commit04a5a938994ddb95cfaa9a74b180e457d3a2b5d0 (patch)
tree31ce9525ed3f3423678397323b65c910d63eadb1 /src/widgets/luaeditor
parentfe0938b1de0c46fc2afcaa3dcd6a0f4ec870d21a (diff)
implement new lua interface
Diffstat (limited to 'src/widgets/luaeditor')
-rw-r--r--src/widgets/luaeditor/buffer.rs180
-rw-r--r--src/widgets/luaeditor/mod.rs96
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(),
}
}
}