diff options
author | Aram Drevekenin <aram@poor.dev> | 2024-02-23 18:21:59 +0100 |
---|---|---|
committer | Aram Drevekenin <aram@poor.dev> | 2024-02-23 18:21:59 +0100 |
commit | 779baa1e6762ca640ead0a193365e520ff679515 (patch) | |
tree | a95ae61de3c2e34bdaa9c32b63e2aa4b695c6454 | |
parent | 0836da7843cc92e21c2b2d3430c5f85f912643d1 (diff) |
aliases working from config file and all tests passing
17 files changed, 518 insertions, 182 deletions
diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 640cbcd80..06c2477a8 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -242,7 +242,7 @@ pub fn start_client( Box::new(opts), Box::new(config_options.clone()), Box::new(layout.unwrap()), - Some(config.plugins.clone()), + Box::new(config.plugins.clone()), ), ipc_pipe, ) diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 008955705..acab5c27a 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -50,7 +50,7 @@ use zellij_utils::{ get_mode_info, layout::Layout, options::Options, - plugins::PluginsConfig, + plugins::PluginAliases, }, ipc::{ClientAttributes, ExitReason, ServerToClientMsg}, }; @@ -65,8 +65,8 @@ pub enum ServerInstruction { Box<CliArgs>, Box<Options>, Box<Layout>, + Box<PluginAliases>, ClientId, - Option<PluginsConfig>, ), Render(Option<HashMap<ClientId, String>>), UnblockInputThread, @@ -365,8 +365,8 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { opts, config_options, layout, + plugin_aliases, client_id, - plugins, ) => { let session = init_session( os_input.clone(), @@ -375,9 +375,9 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) { SessionOptions { opts, layout: layout.clone(), - plugins, config_options: config_options.clone(), }, + plugin_aliases, ); *session_data.write().unwrap() = Some(session); session_state @@ -832,7 +832,6 @@ pub struct SessionOptions { pub opts: Box<CliArgs>, pub config_options: Box<Options>, pub layout: Box<Layout>, - pub plugins: Option<PluginsConfig>, } fn init_session( @@ -840,12 +839,12 @@ fn init_session( to_server: SenderWithContext<ServerInstruction>, client_attributes: ClientAttributes, options: SessionOptions, + plugin_aliases: Box<PluginAliases>, ) -> SessionMetaData { let SessionOptions { opts, config_options, layout, - plugins, } = options; let _ = SCROLL_BUFFER_SIZE.set( @@ -975,13 +974,13 @@ fn init_session( plugin_bus, store, data_dir, - plugins.unwrap_or_default(), layout, path_to_default_shell, zellij_cwd, capabilities, client_attributes, default_shell, + plugin_aliases, ) .fatal() } diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index 5179c6f00..adf13ce4f 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -34,9 +34,9 @@ use zellij_utils::{ command::TerminalAction, layout::{ FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginOrAlias, - TiledPaneLayout, + TiledPaneLayout }, - plugins::PluginsConfig, + plugins::PluginAliases, }, ipc::ClientAttributes, pane_size::Size, @@ -173,35 +173,18 @@ pub(crate) fn plugin_thread_main( bus: Bus<PluginInstruction>, store: Store, data_dir: PathBuf, - plugins: PluginsConfig, mut layout: Box<Layout>, path_to_default_shell: PathBuf, zellij_cwd: PathBuf, capabilities: PluginCapabilities, client_attributes: ClientAttributes, default_shell: Option<TerminalAction>, + plugin_aliases: Box<PluginAliases>, ) -> Result<()> { info!("Wasm main thread starts"); - let plugin_dir = data_dir.join("plugins/"); let plugin_global_data_dir = plugin_dir.join("data"); - - // TODO: better, not hard coded here, etc. - let mut plugin_aliases = HashMap::new(); - let mut filter_configuration = BTreeMap::new(); - filter_configuration.insert("key_from_dict".to_owned(), "value_from_dict".to_owned()); - - // TODO: from config - plugin_aliases.insert("session-manager-alias", RunPlugin::from_url("zellij:session-manager").unwrap()); - plugin_aliases.insert("filepicker", RunPlugin::from_url("zellij:strider").unwrap()); - plugin_aliases.insert("fixture_plugin_for_tests", RunPlugin::from_url(&format!("file:{}/../target/e2e-data/plugins/fixture-plugin-for-tests.wasm", std::env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy())).unwrap()); - plugin_aliases.insert( - "filter", - RunPlugin::from_url("file:/home/aram/code/rust-plugin-example/target/wasm32-wasi/debug/rust-plugin-example.wasm").unwrap().with_configuration(filter_configuration) - ); - layout.populate_plugin_aliases_in_layout(&plugin_aliases); - let store = Arc::new(Mutex::new(store)); // use this channel to ensure that tasks spawned from this thread terminate before exiting @@ -209,7 +192,6 @@ pub(crate) fn plugin_thread_main( let (shutdown_send, shutdown_receive) = channel::bounded::<()>(1); let mut wasm_bridge = WasmBridge::new( - plugins, bus.senders.clone(), store, plugin_dir, @@ -697,7 +679,7 @@ fn pipe_to_specific_plugins( args: &Option<BTreeMap<String, String>>, bus: &Bus<PluginInstruction>, wasm_bridge: &mut WasmBridge, - plugin_aliases: &HashMap<&str, RunPlugin>, + plugin_aliases: &PluginAliases, ) { let is_private = true; let size = Size::default(); diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs index d8ef6ca2e..3c19a5bc6 100644 --- a/zellij-server/src/plugins/unit/plugin_tests.rs +++ b/zellij-server/src/plugins/unit/plugin_tests.rs @@ -10,7 +10,7 @@ use zellij_utils::data::{Event, Key, PermissionStatus, PermissionType, PluginCap use zellij_utils::errors::ErrorContext; use zellij_utils::input::layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginOrAlias, RunPluginLocation, PluginAlias}; use zellij_utils::input::permission::PermissionCache; -use zellij_utils::input::plugins::PluginsConfig; +use zellij_utils::input::plugins::PluginAliases; use zellij_utils::ipc::ClientAttributes; use zellij_utils::lazy_static::lazy_static; use zellij_utils::pane_size::Size; @@ -249,6 +249,13 @@ fn create_plugin_thread( let plugin_capabilities = PluginCapabilities::default(); let client_attributes = ClientAttributes::default(); let default_shell_action = None; // TODO: change me + let mut plugin_aliases = PluginAliases::default(); + plugin_aliases.aliases.insert("fixture_plugin_for_tests".to_owned(), + RunPlugin::from_url( + &format!( + "file:{}/../target/e2e-data/plugins/fixture-plugin-for-tests.wasm", + std::env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy())).unwrap() + ); let plugin_thread = std::thread::Builder::new() .name("plugin_thread".to_string()) .spawn(move || { @@ -257,13 +264,13 @@ fn create_plugin_thread( plugin_bus, store, data_dir, - PluginsConfig::default(), Box::new(Layout::default()), default_shell, zellij_cwd, plugin_capabilities, client_attributes, default_shell_action, + Box::new(plugin_aliases), ) .expect("TEST") }) @@ -335,13 +342,13 @@ fn create_plugin_thread_with_server_receiver( plugin_bus, store, data_dir, - PluginsConfig::default(), Box::new(Layout::default()), default_shell, zellij_cwd, plugin_capabilities, client_attributes, default_shell_action, + Box::new(PluginAliases::default()), ) .expect("TEST"); }) @@ -419,13 +426,13 @@ fn create_plugin_thread_with_pty_receiver( plugin_bus, store, data_dir, - PluginsConfig::default(), Box::new(Layout::default()), default_shell, zellij_cwd, plugin_capabilities, client_attributes, default_shell_action, + Box::new(PluginAliases::default()), ) .expect("TEST") }) @@ -498,13 +505,13 @@ fn create_plugin_thread_with_background_jobs_receiver( plugin_bus, store, data_dir, - PluginsConfig::default(), Box::new(Layout::default()), default_shell, zellij_cwd, plugin_capabilities, client_attributes, default_shell_action, + Box::new(PluginAliases::default()), ) .expect("TEST") }) diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index 197bad759..84e1740c1 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -38,7 +38,7 @@ use zellij_utils::{ input::{ command::TerminalAction, layout::{Layout, PluginUserConfiguration, RunPlugin, RunPluginOrAlias, RunPluginLocation}, - plugins::PluginsConfig, + plugins::PluginConfig, }, ipc::ClientAttributes, pane_size::Size, @@ -76,7 +76,6 @@ impl PluginRenderAsset { pub struct WasmBridge { connected_clients: Arc<Mutex<Vec<ClientId>>>, - plugins: PluginsConfig, senders: ThreadSenders, store: Arc<Mutex<Store>>, plugin_dir: PathBuf, @@ -106,7 +105,6 @@ pub struct WasmBridge { impl WasmBridge { pub fn new( - plugins: PluginsConfig, senders: ThreadSenders, store: Arc<Mutex<Store>>, plugin_dir: PathBuf, @@ -124,7 +122,6 @@ impl WasmBridge { let watcher = None; WasmBridge { connected_clients, - plugins, senders, store, plugin_dir, @@ -178,9 +175,7 @@ impl WasmBridge { match run { Some(run) => { - let mut plugin = self - .plugins - .get(run) + let mut plugin = PluginConfig::from_run_plugin(run) .with_context(|| format!("failed to resolve plugin {run:?}")) .with_context(err_context)?; let plugin_name = run.location.to_string(); diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 0dd2946ca..b62bcd8ae 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -1013,15 +1013,15 @@ pub(crate) fn route_thread_main( cli_args, opts, layout, - plugin_config, + plugin_aliases, ) => { let new_client_instruction = ServerInstruction::NewClient( client_attributes, cli_args, opts, layout, + plugin_aliases, client_id, - plugin_config, ); to_server .send(new_client_instruction) diff --git a/zellij-utils/assets/config/default.kdl b/zellij-utils/assets/config/default.kdl index 04879ecf4..16a3450b8 100644 --- a/zellij-utils/assets/config/default.kdl +++ b/zellij-utils/assets/config/default.kdl @@ -184,11 +184,15 @@ keybinds { } plugins { - tab-bar { path "tab-bar"; } - status-bar { path "status-bar"; } - strider { path "strider"; } - compact-bar { path "compact-bar"; } - session-manager { path "session-manager"; } + tab-bar location="zellij:tab-bar" + status-bar location="zellij:status-bar" + strider location="zellij:strider" + compact-bar location="zellij:compact-bar" + session-manager location="zellij:session-manager" + welcome-screen location="zellij:session-manager" { + welcome_screen true + } + filepicker location="zellij:strider" } // Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP diff --git a/zellij-utils/src/input/config.rs b/zellij-utils/src/input/config.rs index 7a34ee7c8..bde0d3af8 100644 --- a/zellij-utils/src/input/config.rs +++ b/zellij-utils/src/input/config.rs @@ -9,7 +9,7 @@ use std::convert::TryFrom; use super::keybinds::Keybinds; use super::options::Options; -use super::plugins::{PluginsConfig, PluginsConfigError}; +use super::plugins::{PluginsConfigError, PluginAliases}; use super::theme::{Themes, UiConfig}; use crate::cli::{CliArgs, Command}; use crate::envs::EnvironmentVariables; @@ -25,7 +25,7 @@ pub struct Config { pub keybinds: Keybinds, pub options: Options, pub themes: Themes, - pub plugins: PluginsConfig, + pub plugins: PluginAliases, pub ui: UiConfig, pub env: EnvironmentVariables, } @@ -226,7 +226,7 @@ impl Config { self.options = self.options.merge(other.options); self.keybinds.merge(other.keybinds.clone()); self.themes = self.themes.merge(other.themes); - self.plugins = self.plugins.merge(other.plugins); + self.plugins.merge(other.plugins); self.ui = self.ui.merge(other.ui); self.env = self.env.merge(other.env); Ok(()) @@ -239,7 +239,7 @@ mod config_test { use crate::data::{InputMode, Palette, PaletteColor, PluginTag}; use crate::input::layout::RunPluginLocation; use crate::input::options::{Clipboard, OnForceClose}; - use crate::input::plugins::{PluginConfig, PluginType, PluginsConfig}; + use crate::input::plugins::{PluginConfig, PluginType}; use crate::input::theme::{FrameConfig, Theme, Themes, UiConfig}; use std::collections::HashMap; use std::io::Write; diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index 3e9bed8e5..d9594acd5 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -20,11 +20,10 @@ use crate::{ }; use std::cmp::Ordering; -use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::str::FromStr; -use super::plugins::{PluginTag, PluginsConfigError}; +use super::plugins::{PluginTag, PluginsConfigError, PluginAliases}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::vec::Vec; @@ -100,12 +99,12 @@ impl RunPluginOrAlias { RunPluginOrAlias::Alias(plugin_alias) => plugin_alias.name.clone(), } } - pub fn populate_run_plugin_if_needed(&mut self, alias_dict: &HashMap<&str, RunPlugin>) { + pub fn populate_run_plugin_if_needed(&mut self, plugin_aliases: &PluginAliases) { if let RunPluginOrAlias::Alias(run_plugin_alias) = self { if run_plugin_alias.run_plugin.is_some() { log::warn!("Overriding plugin alias"); } - let merged_run_plugin = alias_dict + let merged_run_plugin = plugin_aliases.aliases .get(run_plugin_alias.name.as_str()) .map(|r| r.clone().merge_configuration(&run_plugin_alias.configuration.as_ref().map(|c| c.inner().clone()))); run_plugin_alias.run_plugin = merged_run_plugin; @@ -123,7 +122,7 @@ impl RunPluginOrAlias { pub fn from_url( url: &str, configuration: &Option<BTreeMap<String, String>>, - alias_dict: Option<&HashMap<&str, RunPlugin>>, + alias_dict: Option<&PluginAliases>, cwd: Option<PathBuf> ) -> Result<Self, String> { match RunPluginLocation::parse(&url, cwd) { @@ -137,7 +136,7 @@ impl RunPluginOrAlias { Err(PluginsConfigError::InvalidUrlScheme(_)) | Err(PluginsConfigError::InvalidUrl(..))=> { let mut plugin_alias = PluginAlias::new(&url, configuration); if let Some(alias_dict) = alias_dict { - plugin_alias.run_plugin = alias_dict.get(&url).map(|r| r.clone().merge_configuration(configuration)); + plugin_alias.run_plugin = alias_dict.aliases.get(url).map(|r| r.clone().merge_configuration(configuration)); } Ok(RunPluginOrAlias::Alias(plugin_alias)) }, @@ -327,7 +326,7 @@ impl Run { _ => None } } - pub fn populate_run_plugin_if_needed(&mut self, alias_dict: &HashMap<&str, RunPlugin>) { + pub fn populate_run_plugin_if_needed(&mut self, alias_dict: &PluginAliases) { match self { Run::Plugin(run_plugin_alias) => run_plugin_alias.populate_run_plugin_if_needed(alias_dict), _ => {} @@ -844,7 +843,7 @@ impl TiledPaneLayout { child.add_cwd_to_layout(cwd); } } - pub fn populate_plugin_aliases_in_layout(&mut self, plugin_aliases: &HashMap<&str, RunPlugin>) { + pub fn populate_plugin_aliases_in_layout(&mut self, plugin_aliases: &PluginAliases) { match self.run.as_mut() { Some(run) => run.populate_run_plugin_if_needed(plugin_aliases), _ => {} @@ -1288,7 +1287,7 @@ impl Layout { Err(_e) => None, } } - pub fn populate_plugin_aliases_in_layout(&mut self, plugin_aliases: &HashMap<&str, RunPlugin>) { + pub fn populate_plugin_aliases_in_layout(&mut self, plugin_aliases: &PluginAliases) { for tab in self.tabs.iter_mut() { tab.1.populate_plugin_aliases_in_layout(plugin_aliases); for floating_pane_layout in tab.2.iter_mut() { diff --git a/zellij-utils/src/input/plugins.rs b/zellij-utils/src/input/plugins.rs index 48bdc2cc4..4bc6078f1 100644 --- a/zellij-utils/src/input/plugins.rs +++ b/zellij-utils/src/input/plugins.rs @@ -1,6 +1,5 @@ //! Plugins configuration metadata -use std::borrow::Borrow; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::fs; use std::path::{Path, PathBuf}; use thiserror::Error; @@ -14,109 +13,65 @@ use crate::consts::ASSET_MAP; pub use crate::data::PluginTag; use crate::errors::prelude::*; -use std::collections::BTreeMap; -use std::fmt; - -/// Used in the config struct for plugin metadata -#[derive(Clone, PartialEq, Deserialize, Serialize)] -pub struct PluginsConfig(pub HashMap<PluginTag, PluginConfig>); +#[derive(Clone, Debug, Default, Eq, PartialEq, Deserialize, Serialize)] +pub struct PluginAliases { + pub aliases: BTreeMap<String, RunPlugin> +} -impl fmt::Debug for PluginsConfig { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut stable_sorted = BTreeMap::new(); - for (plugin_tag, plugin_config) in self.0.iter() { - stable_sorted.insert(plugin_tag, plugin_config); - } - write!(f, "{:#?}", stable_sorted) +impl PluginAliases { + pub fn merge(&mut self, other: Self) { + self.aliases.extend(other.aliases); } } -impl PluginsConfig { - pub fn new() -> Self { - Self(HashMap::new()) - } - pub fn from_data(data: HashMap<PluginTag, PluginConfig>) -> Self { - PluginsConfig(data) - } +/// Plugin metadata +#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct PluginConfig { + /// Path of the plugin, see resolve_wasm_bytes for resolution semantics + pub path: PathBuf, + /// Plugin type + pub run: PluginType, + /// Allow command execution from plugin + pub _allow_exec_host_cmd: bool, + /// Original location of the + pub location: RunPluginLocation, + /// Custom configuration for this plugin + pub userspace_configuration: PluginUserConfiguration, +} - /// Get plugin config from run configuration specified in layout files. - pub fn get(&self, run: impl Borrow<RunPlugin>) -> Option<PluginConfig> { - let run = run.borrow(); - match &run.location { +impl PluginConfig { + pub fn from_run_plugin(run_plugin: &RunPlugin) -> Option<PluginConfig> { + match &run_plugin.location { RunPluginLocation::File(path) => Some(PluginConfig { path: path.clone(), run: PluginType::Pane(None), - _allow_exec_host_cmd: run._allow_exec_host_cmd, - location: run.location.clone(), - userspace_configuration: run.configuration.clone(), + _allow_exec_host_cmd: run_plugin._allow_exec_host_cmd, + location: run_plugin.location.clone(), + userspace_configuration: run_plugin.configuration.clone(), }), -// RunPluginLocation::Zellij(tag) => self.0.get(tag).cloned().map(|plugin| PluginConfig { -// _allow_exec_host_cmd: run._allow_exec_host_cmd, -// userspace_configuration: run.configuration.clone(), -// ..plugin -// }), RunPluginLocation::Zellij(tag) => { let tag = tag.to_string(); if tag == "status-bar" || tag == "tab-bar" || tag == "strider" || tag == "session-manager" { Some(PluginConfig { path: PathBuf::from(&tag), run: PluginType::Pane(None), - _allow_exec_host_cmd: run._allow_exec_host_cmd, + _allow_exec_host_cmd: run_plugin._allow_exec_host_cmd, location: RunPluginLocation::parse(&format!("zellij:{}", tag), None).ok()?, - userspace_configuration: PluginUserConfiguration::default(), + userspace_configuration: run_plugin.configuration.clone(), }) } else { None } -// _allow_exec_host_cmd: run._allow_exec_host_cmd, -// userspace_configuration: run.configuration.clone(), -// ..plugin }, RunPluginLocation::Remote(_) => Some(PluginConfig { path: PathBuf::new(), run: PluginType::Pan |