summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Reiner <nathan@nathanreiner.xyz>2024-08-03 10:30:14 +0200
committerNathan Reiner <nathan@nathanreiner.xyz>2024-08-03 10:30:14 +0200
commitcd907dd59a48c2aa9d602aa3fb2f24563994420e (patch)
tree33a1d783dc98a09b09fdcaf039bdcee9912dadd5
parenteafde55afcdf9dc4c17c6c97c1db472fc9ff9957 (diff)
implement into_luamulti for cursor move
-rw-r--r--src/cursor.rs66
-rw-r--r--src/state/editor/buffer.rs10
-rw-r--r--src/state/editor/mod.rs31
-rw-r--r--src/state/view/mod.rs12
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(())
});