diff --git a/doc/PLUGIN_API.md b/doc/PLUGIN_API.md index 35e984e..983c136 100644 --- a/doc/PLUGIN_API.md +++ b/doc/PLUGIN_API.md @@ -83,6 +83,58 @@ This function is called when an action is performed with the mouse. |`mouse_event`|`MouseEvent`|The mouse event.| |`context`|`Context`|The application context.| +#### On Focus + +```lua +function on_focus(context) end +``` + +This function is called when the terminal gains focus. + +| Argument | Type | Description | +|----------|------|-------------| +|`context`|`Context`|The application context.| + +#### On Blur + +```lua +function on_blur(context) end +``` + +This function is called when the terminal loses focus. + +| Argument | Type | Description | +|----------|------|-------------| +|`context`|`Context`|The application context.| + +#### On Paste + +```lua +function on_paste(text, context) end +``` + +This function is called when text is pasted into the terminal. + +| Argument | Type | Description | +|----------|------|-------------| +|`text`|`String`|The text that was pasted.| +|`context`|`Context`|The application context.| + +#### On Resize + +```lua +function on_resize(width, height, context) end +``` + +This function is called when the terminal is resized. +The size stored in the context is the old size, before the resize. + +| Argument | Type | Description | +|----------|------|-------------| +|`width`|`usize`|The new width of the terminal.| +|`height`|`usize`|The new height of the terminal.| +|`context`|`Context`|The application context.| + ### Commands ```lua diff --git a/src/app/events.rs b/src/app/events.rs index 1563e33..a1a3984 100644 --- a/src/app/events.rs +++ b/src/app/events.rs @@ -584,10 +584,12 @@ impl App match event { event::Event::FocusGained => { - // TODO: Maybe add a focus gained event + let mut app_context = get_app_context!(self); + self.plugin_manager.on_focus(&mut app_context); }, event::Event::FocusLost => { - // TODO: Maybe add a focus lost event + let mut app_context = get_app_context!(self); + self.plugin_manager.on_blur(&mut app_context); }, event::Event::Key(ke) => { let mut app_context = get_app_context!(self); @@ -600,11 +602,13 @@ impl App &mut app_context ); }, - event::Event::Paste(_s) => { - // TODO: Maybe add a paste event + event::Event::Paste(s) => { + let mut app_context = get_app_context!(self); + self.plugin_manager.on_paste(s, &mut app_context); }, - event::Event::Resize(_rows, _cols) => { - // TODO: Maybe add a resize event + event::Event::Resize(rows, cols) => { + let mut app_context = get_app_context!(self); + self.plugin_manager.on_resize(*rows, *cols, &mut app_context); }, } Ok(()) diff --git a/src/app/plugins/event.rs b/src/app/plugins/event.rs index bdbb07d..e35dd6a 100644 --- a/src/app/plugins/event.rs +++ b/src/app/plugins/event.rs @@ -15,18 +15,31 @@ pub enum Event<'app> Mouse { event: MouseEvent, }, + Focus, + Blur, + Paste { + text: String, + }, + Resize { + width: u16, + height: u16, + }, } bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq)] - pub struct Events: u8 + pub struct Events: u16 { - const ON_OPEN = 0b0000_0001; - const ON_EDIT = 0b0000_0010; - const ON_SAVE = 0b0000_0100; - const ON_KEY = 0b0000_1000; - const ON_MOUSE = 0b0001_0000; + const ON_OPEN = 0b0000_0000_0000_0001; + const ON_EDIT = 0b0000_0000_0000_0010; + const ON_SAVE = 0b0000_0000_0000_0100; + const ON_KEY = 0b0000_0000_0000_1000; + const ON_MOUSE = 0b0000_0000_0001_0000; + const ON_FOCUS = 0b0000_0000_0010_0000; + const ON_BLUR = 0b0000_0000_0100_0000; + const ON_PASTE = 0b0000_0000_1000_0000; + const ON_RESIZE = 0b0000_0001_0000_0000; - const NONE = 0b0000_0000; + const NONE = 0b0000_0000_0000_0000; } } \ No newline at end of file diff --git a/src/app/plugins/plugin.rs b/src/app/plugins/plugin.rs index 6dc4617..630d9c3 100644 --- a/src/app/plugins/plugin.rs +++ b/src/app/plugins/plugin.rs @@ -72,6 +72,22 @@ impl Plugin { { handlers |= Events::ON_MOUSE; } + if self.lua.globals().get::<_, Function>("on_focus").is_ok() + { + handlers |= Events::ON_FOCUS; + } + if self.lua.globals().get::<_, Function>("on_blur").is_ok() + { + handlers |= Events::ON_BLUR; + } + if self.lua.globals().get::<_, Function>("on_paste").is_ok() + { + handlers |= Events::ON_PASTE; + } + if self.lua.globals().get::<_, Function>("on_resize").is_ok() + { + handlers |= Events::ON_RESIZE; + } handlers } @@ -131,6 +147,42 @@ impl Plugin { on_mouse.call::<_,()>((event, context)) }) }, + Event::Focus => + { + let on_focus = self.lua.globals().get::<_, Function>("on_focus").unwrap(); + self.lua.scope(|scope| { + let context = app_context.to_lua(&self.lua, scope); + on_focus.call::<_,()>(context) + }) + }, + Event::Blur => + { + let on_blur = self.lua.globals().get::<_, Function>("on_blur").unwrap(); + self.lua.scope(|scope| { + let context = app_context.to_lua(&self.lua, scope); + on_blur.call::<_,()>(context) + }) + }, + Event::Paste { + text } => + { + let on_paste = self.lua.globals().get::<_, Function>("on_paste").unwrap(); + self.lua.scope(|scope| { + let text = self.lua.create_string(text).unwrap(); + let context = app_context.to_lua(&self.lua, scope); + on_paste.call::<_,()>((text, context)) + }) + }, + Event::Resize { + width, + height } => + { + let on_resize = self.lua.globals().get::<_, Function>("on_resize").unwrap(); + self.lua.scope(|scope| { + let context = app_context.to_lua(&self.lua, scope); + on_resize.call::<_,()>((width, height, context)) + }) + }, }; self.commands = app_context.take_exported_commands(); ret @@ -218,12 +270,16 @@ mod test function on_save(context) end function on_key(key_event, context) end function on_mouse(mouse_event, context) end + function on_focus(context) end + function on_blur(context) end + function on_paste(text, context) end + function on_resize(width, height, context) end "; let mut app = App::mockup(vec![0;0x100]); let mut app_context = get_app_context!(app); let plugin = Plugin::new_from_source(source, &mut app_context).unwrap(); let handlers = plugin.get_event_handlers(); - assert_eq!(handlers, Events::ON_OPEN | Events::ON_EDIT | Events::ON_SAVE | Events::ON_KEY | Events::ON_MOUSE); + assert!(handlers.is_all()); let source = " function on_open(context) end function on_edit(new_bytes, context) end diff --git a/src/app/plugins/plugin_manager.rs b/src/app/plugins/plugin_manager.rs index 63bd08e..5e5f11f 100644 --- a/src/app/plugins/plugin_manager.rs +++ b/src/app/plugins/plugin_manager.rs @@ -160,6 +160,57 @@ impl PluginManager { } } + pub fn on_focus( + &mut self, + app_context: &mut AppContext) + { + for i in self.on_open.iter() + { + app_context.plugin_index = Some(*i); + let event = Event::Focus; + self.plugins[*i].handle(event, app_context); + } + } + + pub fn on_blur( + &mut self, + app_context: &mut AppContext) + { + for i in self.on_open.iter() + { + app_context.plugin_index = Some(*i); + let event = Event::Blur; + self.plugins[*i].handle(event, app_context); + } + } + + pub fn on_paste( + &mut self, + text: impl AsRef, + app_context: &mut AppContext) + { + for i in self.on_open.iter() + { + app_context.plugin_index = Some(*i); + let event = Event::Paste { text: text.as_ref().to_string() }; + self.plugins[*i].handle(event, app_context); + } + } + + pub fn on_resize( + &mut self, + width: u16, + height: u16, + app_context: &mut AppContext) + { + for i in self.on_open.iter() + { + app_context.plugin_index = Some(*i); + let event = Event::Resize { width, height }; + self.plugins[*i].handle(event, app_context); + } + } + pub fn get_commands(&self) -> Vec<&CommandInfo> { let mut commands = Vec::new(); diff --git a/test/debug_plugins/debug.lua b/test/debug_plugins/debug.lua index bcf85c2..6b007de 100644 --- a/test/debug_plugins/debug.lua +++ b/test/debug_plugins/debug.lua @@ -49,6 +49,22 @@ function on_mouse(mouse_event, context) context.log(1, "Mouse event: " .. mouse_event.kind .. "@" .. mouse_event.row .. "," .. mouse_event.column) end +function on_focus(context) + context.log(1, "Focus gained") +end + +function on_blur(context) + context.log(1, "Focus lost") +end + +function on_paste(text, context) + context.log(1, "Text pasted: " .. text) +end + +function on_resize(width, height, context) + context.log(1, "Resized: " .. width .. "x" .. height .. " from " .. context.screen_width .. "x" .. context.screen_height) +end + function debug(context) context.open_popup("fill_popup") end