diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-07-25 10:04:12 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-25 10:04:12 +0200 |
commit | c95d0e769f31b21f5e2d4aaf6465468344f1bfd6 (patch) | |
tree | 9589f0875b91b73460b807e90817907bf3d7d8c6 | |
parent | 6cf795a7df6c83b65a4535b6af0338b4a0b1742f (diff) |
feat(plugins): make plugins configurable (#2646)
* work
* make every plugin entry point configurable
* make integration tests pass
* make e2e tests pass
* add test for plugin configuration
* add test snapshot
* add plugin config parsing test
* cleanups
* style(fmt): rustfmt
* style(comment): remove commented code
31 files changed, 605 insertions, 98 deletions
diff --git a/default-plugins/compact-bar/src/main.rs b/default-plugins/compact-bar/src/main.rs index 40fa65f52..18c9f12b4 100644 --- a/default-plugins/compact-bar/src/main.rs +++ b/default-plugins/compact-bar/src/main.rs @@ -2,6 +2,7 @@ mod line; mod tab; use std::cmp::{max, min}; +use std::collections::BTreeMap; use std::convert::TryInto; use tab::get_tab_to_focus; @@ -30,7 +31,7 @@ static ARROW_SEPARATOR: &str = ""; register_plugin!(State); impl ZellijPlugin for State { - fn load(&mut self) { + fn load(&mut self, configuration: BTreeMap<String, String>) { set_selectable(false); subscribe(&[ EventType::TabUpdate, diff --git a/default-plugins/fixture-plugin-for-tests/src/main.rs b/default-plugins/fixture-plugin-for-tests/src/main.rs index 20457f13f..074aa1a4d 100644 --- a/default-plugins/fixture-plugin-for-tests/src/main.rs +++ b/default-plugins/fixture-plugin-for-tests/src/main.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; use zellij_tile::prelude::*; // This is a fixture plugin used only for tests in Zellij @@ -9,6 +10,7 @@ use zellij_tile::prelude::*; struct State { received_events: Vec<Event>, received_payload: Option<String>, + configuration: BTreeMap<String, String>, } #[derive(Default, Serialize, Deserialize)] @@ -35,7 +37,8 @@ register_plugin!(State); register_worker!(TestWorker, test_worker, TEST_WORKER); impl ZellijPlugin for State { - fn load(&mut self) { + fn load(&mut self, configuration: BTreeMap<String, String>) { + self.configuration = configuration; subscribe(&[ EventType::InputReceived, EventType::Key, @@ -210,6 +213,9 @@ impl ZellijPlugin for State { Key::Ctrl('x') => { rename_tab(1, "new tab name"); }, + Key::Ctrl('z') => { + go_to_tab_name(&format!("{:?}", self.configuration)); + }, _ => {}, }, Event::CustomMessage(message, payload) => { diff --git a/default-plugins/status-bar/src/main.rs b/default-plugins/status-bar/src/main.rs index ee14e45d5..d768b35ed 100644 --- a/default-plugins/status-bar/src/main.rs +++ b/default-plugins/status-bar/src/main.rs @@ -8,6 +8,7 @@ use ansi_term::{ Style, }; +use std::collections::BTreeMap; use std::fmt::{Display, Error, Formatter}; use zellij_tile::prelude::actions::Action; use zellij_tile::prelude::*; @@ -196,7 +197,7 @@ fn color_elements(palette: Palette, different_color_alternates: bool) -> Colored } impl ZellijPlugin for State { - fn load(&mut self) { + fn load(&mut self, configuration: BTreeMap<String, String>) { // TODO: Should be able to choose whether to use the cache through config. self.tip_name = get_cached_tip_name(); set_selectable(false); @@ -207,7 +208,10 @@ impl ZellijPlugin for State { EventType::InputReceived, EventType::SystemClipboardFailure, ]); - self.supermode = false; // TODO: from config + self.supermode = configuration + .get("supermode") + .and_then(|s| s.trim().parse().ok()) + .unwrap_or(false); self.standby_mode = InputMode::Pane; if self.supermode { switch_to_input_mode(&InputMode::Locked); // supermode should start locked (TODO: only diff --git a/default-plugins/strider/src/main.rs b/default-plugins/strider/src/main.rs index 24d443d10..35ff92ea7 100644 --- a/default-plugins/strider/src/main.rs +++ b/default-plugins/strider/src/main.rs @@ -6,6 +6,7 @@ use search::{FileContentsWorker, FileNameWorker, MessageToSearch, ResultsOfSearc use serde::{Deserialize, Serialize}; use serde_json; use state::{refresh_directory, FsEntry, State}; +use std::collections::BTreeMap; use std::{cmp::min, time::Instant}; use zellij_tile::prelude::*; @@ -18,7 +19,7 @@ register_worker!( ); impl ZellijPlugin for State { - fn load(&mut self) { + fn load(&mut self, configuration: BTreeMap<String, String>) { refresh_directory(self); self.search_state.loading = true; subscribe(&[ diff --git a/default-plugins/tab-bar/src/main.rs b/default-plugins/tab-bar/src/main.rs index 05fdd5608..fc67ef918 100644 --- a/default-plugins/tab-bar/src/main.rs +++ b/default-plugins/tab-bar/src/main.rs @@ -2,6 +2,7 @@ mod line; mod tab; use std::cmp::{max, min}; +use std::collections::BTreeMap; use std::convert::TryInto; use tab::get_tab_to_focus; @@ -30,7 +31,7 @@ static ARROW_SEPARATOR: &str = ""; register_plugin!(State); impl ZellijPlugin for State { - fn load(&mut self) { + fn load(&mut self, configuration: BTreeMap<String, String>) { set_selectable(false); subscribe(&[ EventType::TabUpdate, diff --git a/src/main.rs b/src/main.rs index e3737b19e..f32d76cd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,6 +39,7 @@ fn main() { name, close_on_exit, start_suspended, + configuration: None, }; commands::send_action_to_session(command_cli_action, opts.session, config); std::process::exit(0); diff --git a/zellij-server/src/plugins/plugin_loader.rs b/zellij-server/src/plugins/plugin_loader.rs index 324b540d5..73957cf7c 100644 --- a/zellij-server/src/plugins/plugin_loader.rs +++ b/zellij-server/src/plugins/plugin_loader.rs @@ -1,6 +1,6 @@ use crate::plugins::plugin_map::{PluginEnv, PluginMap, RunningPlugin, Subscriptions}; use crate::plugins::plugin_worker::{plugin_worker, RunningWorker}; -use crate::plugins::zellij_exports::{wasi_read_string, zellij_exports}; +use crate::plugins::zellij_exports::{wasi_read_string, wasi_write_object, zellij_exports}; use crate::plugins::PluginId; use highway::{HighwayHash, PortableHash}; use log::info; @@ -723,7 +723,14 @@ impl<'a> PluginLoader<'a> { } } start_function.call(&[]).with_context(err_context)?; + + wasi_write_object( + &plugin_env.wasi_env, + &self.plugin.userspace_configuration.inner(), + ) + .with_context(err_context)?; load_function.call(&[]).with_context(err_context)?; + display_loading_stage!( indicate_starting_plugin_success, self.loading_indication, diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index 3ec8485b0..663ca94ee 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -2,12 +2,13 @@ use super::plugin_thread_main; use crate::screen::ScreenInstruction; use crate::{channels::SenderWithContext, thread_bus::Bus, ServerInstruction}; use insta::assert_snapshot; +use std::collections::BTreeMap; use std::path::PathBuf; use tempfile::tempdir; use wasmer::Store; use zellij_utils::data::{Event, Key, PluginCapabilities}; use zellij_utils::errors::ErrorContext; -use zellij_utils::input::layout::{Layout, RunPlugin, RunPluginLocation}; +use zellij_utils::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginLocation}; use zellij_utils::input::plugins::PluginsConfig; use zellij_utils::ipc::ClientAttributes; use zellij_utils::lazy_static::lazy_static; @@ -349,6 +350,7 @@ pub fn load_new_plugin_from_hd() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -407,6 +409,7 @@ pub fn plugin_workers() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -468,6 +471,7 @@ pub fn plugin_workers_persist_state() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -541,6 +545,7 @@ pub fn can_subscribe_to_hd_events() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -605,6 +610,7 @@ pub fn switch_to_mode_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -666,6 +672,7 @@ pub fn new_tabs_with_layout_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -741,6 +748,7 @@ pub fn new_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -802,6 +810,7 @@ pub fn go_to_next_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -862,6 +871,7 @@ pub fn go_to_previous_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -922,6 +932,7 @@ pub fn resize_focused_pane_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -982,6 +993,7 @@ pub fn resize_focused_pane_with_direction_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1042,6 +1054,7 @@ pub fn focus_next_pane_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1102,6 +1115,7 @@ pub fn focus_previous_pane_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1162,6 +1176,7 @@ pub fn move_focus_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1222,6 +1237,7 @@ pub fn move_focus_or_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1282,6 +1298,7 @@ pub fn edit_scrollback_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1342,6 +1359,7 @@ pub fn write_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1402,6 +1420,7 @@ pub fn write_chars_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1462,6 +1481,7 @@ pub fn toggle_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1522,6 +1542,7 @@ pub fn move_pane_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1582,6 +1603,7 @@ pub fn move_pane_with_direction_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1642,6 +1664,7 @@ pub fn clear_screen_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1702,6 +1725,7 @@ pub fn scroll_up_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1762,6 +1786,7 @@ pub fn scroll_down_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1822,6 +1847,7 @@ pub fn scroll_to_top_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1882,6 +1908,7 @@ pub fn scroll_to_bottom_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -1942,6 +1969,7 @@ pub fn page_scroll_up_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2002,6 +2030,7 @@ pub fn page_scroll_down_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2062,6 +2091,7 @@ pub fn toggle_focus_fullscreen_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2122,6 +2152,7 @@ pub fn toggle_pane_frames_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2182,6 +2213,7 @@ pub fn toggle_pane_embed_or_eject_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2242,6 +2274,7 @@ pub fn undo_rename_pane_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2302,6 +2335,7 @@ pub fn close_focus_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2362,6 +2396,7 @@ pub fn toggle_active_tab_sync_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2422,6 +2457,7 @@ pub fn close_focused_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2482,6 +2518,7 @@ pub fn undo_rename_tab_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), + configuration: Default::default(), }; let tab_index = 1; let client_id = 1; @@ -2542,6 +2579,7 @@ pub fn previous_swap_layout_plugin_command() { let run_plugin = RunPlugin { _allow_exec_host_cmd: false, location: RunPluginLocation::File(PathBuf::from(&*PLUGIN_FIXTURE)), |