diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs index 1f2d770bb1..626ec811dd 100644 --- a/zellij-server/src/panes/floating_panes/mod.rs +++ b/zellij-server/src/panes/floating_panes/mod.rs @@ -872,6 +872,11 @@ impl FloatingPanes { } pub fn get_plugin_pane_id(&self, run_plugin: &RunPlugin) -> Option { let run = Some(Run::Plugin(run_plugin.clone())); + let currently_running_invoked_with: Vec> = self + .panes + .iter() + .map(|(_, p)| p.invoked_with().clone()) + .collect(); self.panes .iter() .find(|(_id, s_p)| s_p.invoked_with() == &run) diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index 4bef0683d1..c72356699d 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -22,7 +22,10 @@ use zellij_utils::{ errors::{prelude::*, ContextType, PluginContext}, input::{ command::TerminalAction, - layout::{FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginLocation, TiledPaneLayout}, + layout::{ + FloatingPaneLayout, Layout, PluginUserConfiguration, Run, RunPlugin, RunPluginLocation, + TiledPaneLayout, + }, plugins::PluginsConfig, }, ipc::ClientAttributes, @@ -225,7 +228,10 @@ pub(crate) fn plugin_thread_main( tab_index, client_id, ) => { - let mut plugin_ids: HashMap> = HashMap::new(); + let mut plugin_ids: HashMap< + (RunPluginLocation, PluginUserConfiguration), + Vec, + > = HashMap::new(); let mut extracted_run_instructions = tab_layout .clone() .unwrap_or_else(|| layout.new_tab().0) @@ -246,7 +252,10 @@ pub(crate) fn plugin_thread_main( if let Some(Run::Plugin(run)) = run_instruction { let plugin_id = wasm_bridge.load_plugin(&run, tab_index, size, Some(client_id))?; - plugin_ids.entry(run.location).or_default().push(plugin_id); + plugin_ids + .entry((run.location, run.configuration)) + .or_default() + .push(plugin_id); } } drop(bus.senders.send_to_pty(PtyInstruction::NewTab( diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index f571d4381d..a785f536db 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -15,7 +15,10 @@ use zellij_utils::{ errors::{ContextType, PtyContext}, input::{ command::{RunCommand, TerminalAction}, - layout::{FloatingPaneLayout, Layout, Run, RunPluginLocation, TiledPaneLayout}, + layout::{ + FloatingPaneLayout, Layout, PluginUserConfiguration, Run, RunPluginLocation, + TiledPaneLayout, + }, }, }; @@ -52,8 +55,8 @@ pub enum PtyInstruction { Option, Option, Vec, - usize, // tab_index - HashMap>, // plugin_ids + usize, // tab_index + HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, // plugin_ids ClientId, ), // the String is the tab name ClosePane(PaneId), @@ -595,7 +598,7 @@ impl Pty { layout: TiledPaneLayout, floating_panes_layout: Vec, default_shell: Option, - plugin_ids: HashMap>, + plugin_ids: HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, tab_index: usize, client_id: ClientId, ) -> Result<()> { diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 8015075fcb..5cf1938562 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -16,8 +16,8 @@ use zellij_utils::pane_size::{Size, SizeInPixels}; use zellij_utils::{ input::command::TerminalAction, input::layout::{ - FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginLocation, SwapFloatingLayout, - SwapTiledLayout, TiledPaneLayout, + FloatingPaneLayout, Layout, PluginUserConfiguration, Run, RunPlugin, RunPluginLocation, + SwapFloatingLayout, SwapTiledLayout, TiledPaneLayout, }, position::Position, }; @@ -208,7 +208,7 @@ pub enum ScreenInstruction { Vec, Vec<(u32, HoldForCommand)>, // new pane pids Vec<(u32, HoldForCommand)>, // new floating pane pids - HashMap>, + HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, usize, // tab_index ClientId, ), @@ -1125,7 +1125,7 @@ impl Screen { floating_panes_layout: Vec, new_terminal_ids: Vec<(u32, HoldForCommand)>, new_floating_terminal_ids: Vec<(u32, HoldForCommand)>, - new_plugin_ids: HashMap>, + new_plugin_ids: HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, tab_index: usize, client_id: ClientId, ) -> Result<()> { diff --git a/zellij-server/src/tab/layout_applier.rs b/zellij-server/src/tab/layout_applier.rs index b93bb52fd9..ed3cdef1a0 100644 --- a/zellij-server/src/tab/layout_applier.rs +++ b/zellij-server/src/tab/layout_applier.rs @@ -18,7 +18,9 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use std::rc::Rc; use zellij_utils::{ data::{Palette, Style}, - input::layout::{FloatingPaneLayout, Run, RunPluginLocation, TiledPaneLayout}, + input::layout::{ + FloatingPaneLayout, PluginUserConfiguration, Run, RunPluginLocation, TiledPaneLayout, + }, pane_size::{Offset, PaneGeom, Size, SizeInPixels, Viewport}, }; @@ -96,7 +98,7 @@ impl<'a> LayoutApplier<'a> { floating_panes_layout: Vec, new_terminal_ids: Vec<(u32, HoldForCommand)>, new_floating_terminal_ids: Vec<(u32, HoldForCommand)>, - mut new_plugin_ids: HashMap>, + mut new_plugin_ids: HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, client_id: ClientId, ) -> Result { // true => layout has floating panes @@ -198,7 +200,7 @@ impl<'a> LayoutApplier<'a> { &mut self, layout: TiledPaneLayout, new_terminal_ids: Vec<(u32, HoldForCommand)>, - new_plugin_ids: &mut HashMap>, + new_plugin_ids: &mut HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, client_id: ClientId, ) -> Result<()> { let err_context = || format!("failed to apply tiled panes layout"); @@ -230,7 +232,7 @@ impl<'a> LayoutApplier<'a> { } else if let Some(Run::Plugin(run)) = layout.run.clone() { let pane_title = run.location.to_string(); let pid = new_plugin_ids - .get_mut(&run.location) + .get_mut(&(run.location, run.configuration)) .and_then(|ids| ids.pop()) .with_context(err_context)?; let mut new_plugin = PluginPane::new( @@ -324,7 +326,7 @@ impl<'a> LayoutApplier<'a> { &mut self, floating_panes_layout: Vec, new_floating_terminal_ids: Vec<(u32, HoldForCommand)>, - new_plugin_ids: &mut HashMap>, + new_plugin_ids: &mut HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, layout_name: Option, ) -> Result { // true => has floating panes @@ -346,7 +348,7 @@ impl<'a> LayoutApplier<'a> { } else if let Some(Run::Plugin(run)) = floating_pane_layout.run.clone() { let pane_title = run.location.to_string(); let pid = new_plugin_ids - .get_mut(&run.location) + .get_mut(&(run.location, run.configuration)) .and_then(|ids| ids.pop()) .with_context(err_context)?; let mut new_pane = PluginPane::new( diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 799cebcb25..9483a94bf5 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -49,8 +49,8 @@ use zellij_utils::{ input::{ command::TerminalAction, layout::{ - FloatingPaneLayout, Run, RunPlugin, RunPluginLocation, SwapFloatingLayout, - SwapTiledLayout, TiledPaneLayout, + FloatingPaneLayout, PluginUserConfiguration, Run, RunPlugin, RunPluginLocation, + SwapFloatingLayout, SwapTiledLayout, TiledPaneLayout, }, parse_keys, }, @@ -621,7 +621,7 @@ impl Tab { floating_panes_layout: Vec, new_terminal_ids: Vec<(u32, HoldForCommand)>, new_floating_terminal_ids: Vec<(u32, HoldForCommand)>, - new_plugin_ids: HashMap>, + new_plugin_ids: HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, client_id: ClientId, ) -> Result<()> { self.swap_layouts diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs index 5a04d9c145..56dff4d72b 100644 --- a/zellij-server/src/tab/unit/tab_integration_tests.rs +++ b/zellij-server/src/tab/unit/tab_integration_tests.rs @@ -20,8 +20,8 @@ use zellij_utils::data::ResizeStrategy; use zellij_utils::envs::set_session_name; use zellij_utils::errors::{prelude::*, ErrorContext}; use zellij_utils::input::layout::{ - FloatingPaneLayout, Layout, RunPluginLocation, SwapFloatingLayout, SwapTiledLayout, - TiledPaneLayout, + FloatingPaneLayout, Layout, PluginUserConfiguration, RunPluginLocation, SwapFloatingLayout, + SwapTiledLayout, TiledPaneLayout, }; use zellij_utils::input::plugins::PluginTag; use zellij_utils::ipc::IpcReceiverWithContext; @@ -268,7 +268,7 @@ fn create_new_tab_with_swap_layouts( Vec, Vec<(u32, Option)>, Vec<(u32, Option)>, - HashMap>, + HashMap<(RunPluginLocation, PluginUserConfiguration), Vec>, )>, draw_pane_frames: bool, ) -> Tab { @@ -4955,11 +4955,17 @@ fn layout_with_plugins_and_commands_swaped_properly() { let new_floating_terminal_ids = vec![]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5050,11 +5056,17 @@ fn base_layout_is_included_in_swap_layouts() { let new_floating_terminal_ids = vec![]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5142,11 +5154,17 @@ fn swap_layouts_including_command_panes_absent_from_existing_layout() { let new_floating_terminal_ids = vec![]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5237,11 +5255,17 @@ fn swap_layouts_not_including_command_panes_present_in_existing_layout() { let new_floating_terminal_ids = vec![]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5405,11 +5429,17 @@ fn swap_layouts_not_including_plugin_panes_present_in_existing_layout() { let new_floating_terminal_ids = vec![]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5889,11 +5919,17 @@ fn floating_layout_with_plugins_and_commands_swaped_properly() { let new_terminal_ids = vec![(4, None)]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -5982,11 +6018,17 @@ fn base_floating_layout_is_included_in_swap_layouts() { let new_terminal_ids = vec![(4, None)]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -6074,11 +6116,17 @@ fn swap_floating_layouts_including_command_panes_absent_from_existing_layout() { let new_terminal_ids = vec![(4, None)]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -6169,11 +6217,17 @@ fn swap_floating_layouts_not_including_command_panes_present_in_existing_layout( let new_terminal_ids = vec![(4, None)]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); @@ -6326,11 +6380,17 @@ fn swap_floating_layouts_not_including_plugin_panes_present_in_existing_layout() let new_terminal_ids = vec![(4, None)]; let mut new_plugin_ids = HashMap::new(); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("tab-bar")), + Default::default(), + ), vec![1], ); new_plugin_ids.insert( - RunPluginLocation::Zellij(PluginTag::new("status-bar")), + ( + RunPluginLocation::Zellij(PluginTag::new("status-bar")), + Default::default(), + ), vec![2], ); diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs index 2f123ddccd..beaa19cda5 100644 --- a/zellij-server/src/unit/screen_tests.rs +++ b/zellij-server/src/unit/screen_tests.rs @@ -311,7 +311,10 @@ impl MockScreen { let mut floating_pane_ids = vec![]; let mut plugin_ids = HashMap::new(); plugin_ids.insert( - RunPluginLocation::File(PathBuf::from("/path/to/fake/plugin")), + ( + RunPluginLocation::File(PathBuf::from("/path/to/fake/plugin")), + Default::default(), + ), vec![1], ); for i in 0..pane_count { diff --git a/zellij-utils/src/input/layout.rs b/zellij-utils/src/input/layout.rs index bd0396a1cd..262f27788c 100644 --- a/zellij-utils/src/input/layout.rs +++ b/zellij-utils/src/input/layout.rs @@ -207,7 +207,8 @@ impl Run { } } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Default)] +#[allow(clippy::derive_hash_xor_eq)] +#[derive(Debug, Serialize, Deserialize, Clone, Hash, Default)] pub struct RunPlugin { #[serde(default)] pub _allow_exec_host_cmd: bool, @@ -225,11 +226,30 @@ impl RunPlugin { } } +#[allow(clippy::derive_hash_xor_eq)] +impl PartialEq for RunPlugin { + fn eq(&self, other: &Self) -> bool { + // TODO: normalize paths here if the location is a file so that relative/absolute paths + // will work properly + (&self.location, &self.configuration) == (&other.location, &other.configuration) + } +} +impl Eq for RunPlugin {} + #[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] pub struct PluginUserConfiguration(BTreeMap); impl PluginUserConfiguration { - pub fn new(configuration: BTreeMap) -> Self { + pub fn new(mut configuration: BTreeMap) -> Self { + // reserved words + configuration.remove("hold_on_close"); + configuration.remove("hold_on_start"); + configuration.remove("cwd"); + configuration.remove("name"); + configuration.remove("direction"); + configuration.remove("floating"); + configuration.remove("move_to_focused_tab"); + PluginUserConfiguration(configuration) } pub fn inner(&self) -> &BTreeMap { diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap index 06c90a6891..2f0a54b9d5 100644 --- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap +++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap @@ -2501,10 +2501,7 @@ Config { ), ), configuration: PluginUserConfiguration( - { - "floating": "true", - "move_to_focused_tab": "true", - }, + {}, ), }, true, diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap index b2c4305cb7..7ceedc6810 100644 --- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap +++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap @@ -2501,10 +2501,7 @@ Config { ), ), configuration: PluginUserConfiguration( - { - "floating": "true", - "move_to_focused_tab": "true", - }, + {}, ), }, true, diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap index 42cd12c25b..9c8dda6719 100644 --- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap +++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap @@ -2501,10 +2501,7 @@ Config { ), ), configuration: PluginUserConfiguration( - { - "floating": "true", - "move_to_focused_tab": "true", - }, + {}, ), }, true, diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap index 9f5749f556..d9ead2b96b 100644 --- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap +++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap @@ -2501,10 +2501,7 @@ Config { ), ), configuration: PluginUserConfiguration( - { - "floating": "true", - "move_to_focused_tab": "true", - }, + {}, ), }, true, diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap index 8da67cf042..7f05ec5c4d 100644 --- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap +++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap @@ -2501,10 +2501,7 @@ Config { ), ), configuration: PluginUserConfiguration( - { - "floating": "true", - "move_to_focused_tab": "true", - }, + {}, ), }, true,