diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-05-16 12:47:18 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-16 12:47:18 +0200 |
commit | 5fe4d60c220c872c1e77a7ddf24fec6686c28e95 (patch) | |
tree | b6abec3006de7cd2eaecee149005d55ee4671a6b /zellij-tile/src | |
parent | 4b7d7c34b72e67168a2ec53b27776047ccddf522 (diff) |
feat(plugins): Plugin workers and strider (#2449)
* mvp of strider fuzzy find
* improve search ui
* various refactoringz
* moar refactoring
* even more refactoring
* tests and more refactoring
* refactor: remove unused stuff
* style(fmt): rustfmt
* debug ci
* debug ci
* correct path for plugin system tests
* fix plugin system ci tests
* remove debugging statements from test
* fix plugin worker persistence
* add test for plugin worker persistence
* style(fmt): rustfmt
* final cleanups
* remove outdated comments
Diffstat (limited to 'zellij-tile/src')
-rw-r--r-- | zellij-tile/src/lib.rs | 68 | ||||
-rw-r--r-- | zellij-tile/src/shim.rs | 26 |
2 files changed, 94 insertions, 0 deletions
diff --git a/zellij-tile/src/lib.rs b/zellij-tile/src/lib.rs index 800b6d684..685de4afe 100644 --- a/zellij-tile/src/lib.rs +++ b/zellij-tile/src/lib.rs @@ -1,6 +1,7 @@ pub mod prelude; pub mod shim; +use serde::{Deserialize, Serialize}; use zellij_utils::data::Event; #[allow(unused_variables)] @@ -12,6 +13,12 @@ pub trait ZellijPlugin { fn render(&mut self, rows: usize, cols: usize) {} } +#[allow(unused_variables)] +// TODO: can we get rid of the lifetime? maybe with generics? +pub trait ZellijWorker<'de>: Default + Serialize + Deserialize<'de> { + fn on_message(&mut self, message: String, payload: String) {} +} + pub const PLUGIN_MISMATCH: &str = "An error occured in a plugin while receiving an Event from zellij. This means that the plugins aren't compatible with the current zellij version. @@ -36,7 +43,10 @@ macro_rules! register_plugin { std::panic::set_hook(Box::new(|info| { report_panic(info); })); + } + #[no_mangle] + fn load() { STATE.with(|state| { state.borrow_mut().load(); }); @@ -65,3 +75,61 @@ macro_rules! register_plugin { } }; } + +#[macro_export] +macro_rules! register_worker { + ($worker:ty, $worker_name:ident) => { + #[no_mangle] + pub fn $worker_name() { + use serde_json::*; + let worker_display_name = std::stringify!($worker_name); + + // read message from STDIN + let (message, payload): (String, String) = $crate::shim::object_from_stdin() + .unwrap_or_else(|e| { + eprintln!( + "Failed to deserialize message to worker \"{}\": {:?}", + worker_display_name, e + ); + Default::default() + }); + + // read previous worker state from HD if it exists + let mut worker_instance = match std::fs::read(&format!("/data/{}", worker_display_name)) + .map_err(|e| format!("Failed to read file: {:?}", e)) + .and_then(|s| { + serde_json::from_str::<$worker>(&String::from_utf8_lossy(&s)) + .map_err(|e| format!("Failed to deserialize: {:?}", e)) + }) { + Ok(s) => s, + Err(e) => { + eprintln!( + "Failed to read existing state ({:?}), creating new state for worker", + e + ); + <$worker>::default() + }, + }; + + // invoke worker + worker_instance.on_message(message, payload); + + // persist worker state to HD for next run + match serde_json::to_string(&worker_instance) + .map_err(|e| format!("Failed to serialize worker state")) + .and_then(|serialized_state| { + std::fs::write( + &format!("/data/{}", worker_display_name), + serialized_state.as_bytes(), + ) + .map_err(|e| format!("Failed to persist state to HD: {:?}", e)) + }) { + Ok(()) => {}, + Err(e) => eprintln!( + "Failed to serialize and persist worker state to hd: {:?}", + e + ), + } + } + }; +} diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs index 0aa8d3e0e..f1c1fb54d 100644 --- a/zellij-tile/src/shim.rs +++ b/zellij-tile/src/shim.rs @@ -39,6 +39,11 @@ pub fn open_file(path: &Path) { unsafe { host_open_file() }; } +pub fn open_file_with_line(path: &Path, line: usize) { + object_to_stdout(&(path, line)); + unsafe { host_open_file_with_line() }; +} + pub fn switch_tab_to(tab_idx: u32) { unsafe { host_switch_tab_to(tab_idx) }; } @@ -74,6 +79,24 @@ pub fn object_to_stdout(object: &impl Serialize) { println!("{}", serde_json::to_string(object).unwrap()); } +#[doc(hidden)] +pub fn post_message_to(worker_name: &str, message: String, payload: String) { + match serde_json::to_string(&(worker_name, message, payload)) { + Ok(serialized) => println!("{}", serialized), + Err(e) => eprintln!("Failed to serialize message: {:?}", e), + } + unsafe { host_post_message_to() }; +} + +#[doc(hidden)] +pub fn post_message_to_plugin(message: String, payload: String) { + match serde_json::to_string(&(message, payload)) { + Ok(serialized) => println!("{}", serialized), + Err(e) => eprintln!("Failed to serialize message: {:?}", e), + } + unsafe { host_post_message_to_plugin() }; +} + #[link(wasm_import_module = "zellij")] extern "C" { fn host_subscribe(); @@ -82,8 +105,11 @@ extern "C" { fn host_get_plugin_ids(); fn host_get_zellij_version(); fn host_open_file(); + fn host_open_file_with_line(); fn host_switch_tab_to(tab_idx: u32); fn host_set_timeout(secs: f64); fn host_exec_cmd(); fn host_report_panic(); + fn host_post_message_to(); + fn host_post_message_to_plugin(); } |