use crate::cursor::CursorMove; use self::{bar::EditorBarState, buffer::Buffer, cursorshape::CursorShape}; use super::{window::Window, GlobalState, DUMMY_STATE}; use mlua::{Lua, Table, UserData}; pub mod bar; pub mod buffer; pub mod cursorshape; #[derive(Default, Debug)] pub struct EditorState { pub visible: bool, pub buffer: Buffer, pub bar: EditorBarState, pub cursor_shape: CursorShape, } macro_rules! cfg { () => { GlobalState::instance().editor }; } macro_rules! cfg_mut { () => { GlobalState::instance_mut().editor }; } impl EditorState { pub const fn new() -> Self { Self { visible: false, buffer: Buffer::new(), bar: EditorBarState::new(), cursor_shape: CursorShape::Bar, } } pub fn run(lua: &Lua) { let script = { cfg!().buffer.as_string() }; if let Err(_error) = lua.load(script).exec() { // TODO: add error handling } } } impl UserData for EditorState { fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) { fields.add_field_function_get("visible", |_, _| Ok(cfg!().visible)); fields.add_field_function_set("visible", |_, _, visible: bool| { let mut state = GlobalState::instance_mut(); state.editor.visible = visible; if let Window::Editor = state.active_window { if !visible { state.set_focus(Window::View); } } Ok(()) }); 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("cursor_shape", |_, _| Ok(cfg!().cursor_shape)); fields.add_field_function_set("cursor_shape", |_, _, shape: CursorShape| { cfg_mut!().cursor_shape = shape; Ok(()) }); fields.add_field_function_get("lines", |lua, _| { let table = lua.create_table()?; for (i, line) in cfg!().buffer.lines().iter().enumerate() { table.set::(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::() { let (_, line) = r?; vec.push(line); } cfg_mut!().buffer.set_lines(vec); Ok(()) }); fields.add_field_function_get("bar", |_, _| Ok(DUMMY_STATE.editor.bar)); } fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("run", |lua, _: ()| { EditorState::run(lua); Ok(()) }); methods.add_function("move_cursor", |_, m: CursorMove| { cfg_mut!().buffer.move_cursor(m); Ok(()) }) } }