summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-07-25 10:04:12 +0200
committerGitHub <noreply@github.com>2023-07-25 10:04:12 +0200
commitc95d0e769f31b21f5e2d4aaf6465468344f1bfd6 (patch)
tree9589f0875b91b73460b807e90817907bf3d7d8c6
parent6cf795a7df6c83b65a4535b6af0338b4a0b1742f (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
-rw-r--r--default-plugins/compact-bar/src/main.rs3
-rw-r--r--default-plugins/fixture-plugin-for-tests/src/main.rs8
-rw-r--r--default-plugins/status-bar/src/main.rs8
-rw-r--r--default-plugins/strider/src/main.rs3
-rw-r--r--default-plugins/tab-bar/src/main.rs3
-rw-r--r--src/main.rs1
-rw-r--r--zellij-server/src/plugins/plugin_loader.rs9
-rw-r--r--zellij-server/src/plugins/unit/plugin_tests.rs138
-rw-r--r--zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__send_configuration_to_plugins.snap19
-rw-r--r--zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__start_or_reload_plugin.snap5
-rw-r--r--zellij-server/src/plugins/zellij_exports.rs5
-rw-r--r--zellij-server/src/screen.rs58
-rw-r--r--zellij-server/src/unit/screen_tests.rs6
-rw-r--r--zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_launch_or_focus_plugin_action.snap5
-rw-r--r--zellij-tile/src/lib.rs9
-rw-r--r--zellij-utils/src/cli.rs8
-rw-r--r--zellij-utils/src/input/actions.rs29
-rw-r--r--zellij-utils/src/input/config.rs4
-rw-r--r--zellij-utils/src/input/layout.rs29
-rw-r--r--zellij-utils/src/input/plugins.rs6
-rw-r--r--zellij-utils/src/input/unit/layout_test.rs25
-rw-r--r--zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__can_load_swap_layouts_from_a_different_file.snap20
-rw-r--r--zellij-utils/src/kdl/kdl_layout_parser.rs65
-rw-r--r--zellij-utils/src/kdl/mod.rs107
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments-2.snap49
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap13
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap13
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_keybinds_override_config_keybinds.snap13
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap16
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap13
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap13
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;