diff options
| -rw-r--r-- | src/cursor.rs | 66 | ||||
| -rw-r--r-- | src/state/editor/buffer.rs | 10 | ||||
| -rw-r--r-- | src/state/editor/mod.rs | 31 | ||||
| -rw-r--r-- | src/state/view/mod.rs | 12 |
4 files changed, 107 insertions, 12 deletions
diff --git a/src/cursor.rs b/src/cursor.rs index 8ab538b..5027e80 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -1,3 +1,4 @@ +use mlua::FromLuaMulti; pub enum CursorMove { Up(usize), @@ -12,6 +13,69 @@ pub enum CursorMove { Relative((isize, isize)), } +impl<'lua> FromLuaMulti<'lua> for CursorMove { + fn from_lua_multi( + values: mlua::prelude::LuaMultiValue<'lua>, + _lua: &'lua mlua::prelude::Lua, + ) -> mlua::prelude::LuaResult<Self> { + let first = values + .get(1) + .filter(|v| v.is_integer() || v.is_number()) + .map(|v| { + if v.is_number() { + v.as_number().unwrap_or(0.0) + } else { + v.as_number().unwrap_or(0.0) + } + }) + .map(|n| n as usize); + + let second = values + .get(2) + .filter(|v| v.is_integer() || v.is_number()) + .map(|v| { + if v.is_number() { + v.as_number().unwrap() + } else { + v.as_number().unwrap() + } + }) + .map(|n| n as usize); + + if let Some(value) = values.get(0) { + if value.is_string() { + match value.as_str().unwrap().to_lowercase().as_str() { + "up" => return Ok(CursorMove::Up(first.unwrap_or(1))), + "down" => return Ok(CursorMove::Down(first.unwrap_or(1))), + "left" => return Ok(CursorMove::Left(first.unwrap_or(1))), + "right" => return Ok(CursorMove::Right(first.unwrap_or(1))), + "top" => return Ok(CursorMove::Top), + "bottom" => return Ok(CursorMove::Bottom), + "begin" => return Ok(CursorMove::Begin), + "end" => return Ok(CursorMove::End), + "jump" => { + if first.is_some() && second.is_some() { + return Ok(CursorMove::Jump((first.unwrap(), second.unwrap()))); + } + + return Err(mlua::Error::runtime("invalid row, column values")); + } + "relative" => { + if first.is_some() && second.is_some() { + return Ok(CursorMove::Jump((first.unwrap(), second.unwrap()))); + } + + return Err(mlua::Error::runtime("invalid row, column values")); + } + _ => {} + } + } + } + + Err(mlua::Error::runtime("invalid first value")) + } +} + #[derive(Default, Debug, Clone)] pub struct Cursor { x: isize, @@ -76,7 +140,7 @@ impl Cursor { CursorMove::Jump((x, y)) => { self.x = x as isize; self.y = y as isize; - }, + } CursorMove::Relative((x, y)) => { self.x += x; self.y += y; diff --git a/src/state/editor/buffer.rs b/src/state/editor/buffer.rs index 49c27b9..6e210ab 100644 --- a/src/state/editor/buffer.rs +++ b/src/state/editor/buffer.rs @@ -52,6 +52,10 @@ impl Buffer { } pub fn insert(&mut self, c: char) { + if self.lines.is_empty() { + return; + } + match c { '\n' => { let (a, b) = { @@ -96,6 +100,10 @@ impl Buffer { } pub fn delete(&mut self) { + if self.lines.is_empty() { + return; + } + 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()); @@ -108,7 +116,7 @@ impl Buffer { .move_checked(CursorMove::Jump((new_x, self.cursor.y()))); self.refresh_buffer_max() - } else if !self.cursor.is_at_top() { + } else if !self.cursor.is_at_start() { let x = self.cursor.x() - 1; self.current_line_mut().remove(x); self.refresh_line_max(); diff --git a/src/state/editor/mod.rs b/src/state/editor/mod.rs index 279a164..058bbf6 100644 --- a/src/state/editor/mod.rs +++ b/src/state/editor/mod.rs @@ -1,10 +1,10 @@ use self::{bar::EditorBarState, buffer::Buffer}; use super::{GlobalState, DUMMY_STATE}; -use mlua::{Lua, UserData}; +use mlua::{Lua, Table, UserData}; -pub mod buffer; pub mod bar; +pub mod buffer; #[derive(Default, Debug)] pub struct EditorState { @@ -51,6 +51,33 @@ impl UserData for EditorState { }); fields.add_field_function_get("bar", |_, _| Ok(DUMMY_STATE.editor.bar)); + + fields.add_field_function_get("content", |_, _| Ok(cfg!().buffer.as_string())); + fields.add_field_function_set("content", |_, _, content: String| { + cfg_mut!().buffer.set_lines_from_string(content); + Ok(()) + }); + + fields.add_field_function_get("lines", |lua, _| { + let table = lua.create_table()?; + + for (i, line) in cfg!().buffer.lines().iter().enumerate() { + table.set::<usize, &str>(i + 1, line.as_ref())? + } + + Ok(table) + }); + fields.add_field_function_set("lines", |_, _, content: Table| { + let mut vec = Vec::new(); + + for r in content.pairs::<usize, String>() { + let (_, line) = r?; + vec.push(line); + } + + cfg_mut!().buffer.set_lines(vec); + Ok(()) + }); } fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { diff --git a/src/state/view/mod.rs b/src/state/view/mod.rs index b142227..961c4ca 100644 --- a/src/state/view/mod.rs +++ b/src/state/view/mod.rs @@ -14,8 +14,8 @@ use crate::{ }, }; -pub mod mode; pub mod bar; +pub mod mode; #[derive(Default, Debug)] pub struct SheetViewState { @@ -172,16 +172,12 @@ impl UserData for SheetViewState { Ok(()) }); - fields.add_field_function_get("bar", |_, _| { - Ok(DUMMY_STATE.view.bar) - }) + fields.add_field_function_get("bar", |_, _| Ok(DUMMY_STATE.view.bar)) } fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { - methods.add_function("move_cursor", |_, (row, column): (usize, usize)| { - cfg_mut!() - .cursor - .move_checked(CursorMove::Jump((column, row))); + methods.add_function("move_cursor", |_, m: CursorMove| { + cfg_mut!().cursor.move_checked(m); Ok(()) }); |