use self::{bar::EditorBarState, buffer::Buffer}; use super::{GlobalState, DUMMY_STATE}; use mlua::{Lua, Table, UserData}; pub mod bar; pub mod buffer; #[derive(Default, Debug)] pub struct EditorState { pub visible: bool, pub buffer: Buffer, pub bar: EditorBarState, } 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(), } } 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| { cfg_mut!().visible = visible; Ok(()) }); 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::(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(()) }); } fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) { methods.add_function("run", |lua, _: ()| { EditorState::run(lua); Ok(()) }) } }