From ffbdb095ec5402455ac7f1cc8ef2f1bb8ebc8df2 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Mon, 22 Jul 2024 18:30:18 +0200 Subject: [PATCH] feat(plugins): some APIs for controlling and receiving information about other panes (#3515) * add context to opening command panes, and events for their start/finish * show/hide other panes plugin apis * get tests to pass * style(fmt): rustfmt * update plugin test snapshots --- .../fixture-plugin-for-tests/src/main.rs | 14 +- zellij-server/src/os_input_output.rs | 1 + ..._command_pane_floating_plugin_command.snap | 9 +- ...sts__open_command_pane_plugin_command.snap | 9 +- ...open_terminal_floating_plugin_command.snap | 3 +- ...n_tests__open_terminal_plugin_command.snap | 3 +- zellij-server/src/plugins/wasm_bridge.rs | 2 + zellij-server/src/plugins/zellij_exports.rs | 116 ++++++++++---- zellij-server/src/pty.rs | 52 ++++++- ..._new_pane_action_with_command_and_cwd.snap | 4 +- ...on_with_floating_pane_and_coordinates.snap | 4 +- zellij-tile/src/shim.rs | 28 +++- zellij-utils/assets/prost/api.event.rs | 30 +++- .../assets/prost/api.plugin_command.rs | 28 +++- zellij-utils/src/data.rs | 36 ++++- zellij-utils/src/input/actions.rs | 1 + zellij-utils/src/input/command.rs | 8 +- ..._test__args_added_to_args_in_template.snap | 4 +- ..._test__args_override_args_in_template.snap | 4 +- ...it_added_to_close_on_exit_in_template.snap | 4 +- ...t_overrides_close_on_exit_in_template.snap | 4 +- ...ut_test__cwd_added_to_cwd_in_template.snap | 4 +- ...ut_test__cwd_override_cwd_in_template.snap | 4 +- ...ayout__layout_test__env_var_expansion.snap | 4 +- ...epended_to_panes_with_and_without_cwd.snap | 3 +- ...ith_and_without_cwd_in_pane_templates.snap | 3 +- ...with_and_without_cwd_in_tab_templates.snap | 3 +- ...global_cwd_given_to_panes_without_cwd.snap | 3 +- ...al_cwd_passed_from_layout_constructor.snap | 3 +- ...r_overrides_global_cwd_in_layout_file.snap | 3 +- ...lobal_cwd_prepended_to_panes_with_cwd.snap | 3 +- ...th_tab_cwd_given_to_panes_without_cwd.snap | 3 +- ..._with_command_panes_and_close_on_exit.snap | 3 +- ...ith_command_panes_and_start_suspended.snap | 3 +- ...t__layout_with_tab_and_pane_templates.snap | 3 +- ...s_overriden_by_its_consumers_bare_cwd.snap | 3 +- ...verriden_by_its_consumers_command_cwd.snap | 3 +- ..._consumer_command_does_not_have_a_cwd.snap | 3 +- ...cwd_is_overriden_by_its_consumers_cwd.snap | 3 +- ...t_cwd_receives_its_consumers_bare_cwd.snap | 3 +- ...ated_to_its_consumer_command_with_cwd.snap | 3 +- ...d_to_its_consumer_command_without_cwd.snap | 3 +- ...t__tab_cwd_given_to_panes_without_cwd.snap | 3 +- ...__tab_cwd_prepended_to_panes_with_cwd.snap | 3 +- zellij-utils/src/kdl/kdl_layout_parser.rs | 1 + zellij-utils/src/kdl/mod.rs | 1 + zellij-utils/src/plugin_api/action.rs | 1 + zellij-utils/src/plugin_api/event.proto | 15 ++ zellij-utils/src/plugin_api/event.rs | 62 ++++++++ .../src/plugin_api/plugin_command.proto | 14 ++ zellij-utils/src/plugin_api/plugin_command.rs | 146 ++++++++++++++---- 51 files changed, 555 insertions(+), 121 deletions(-) diff --git a/default-plugins/fixture-plugin-for-tests/src/main.rs b/default-plugins/fixture-plugin-for-tests/src/main.rs index 918aba72..89af6573 100644 --- a/default-plugins/fixture-plugin-for-tests/src/main.rs +++ b/default-plugins/fixture-plugin-for-tests/src/main.rs @@ -207,11 +207,14 @@ impl ZellijPlugin for State { ); }, BareKey::Char('m') if key.has_modifiers(&[KeyModifier::Ctrl]) => { - open_command_pane(CommandToRun { - path: std::path::PathBuf::from("/path/to/my/file.rs"), - args: vec!["arg1".to_owned(), "arg2".to_owned()], - ..Default::default() - }); + open_command_pane( + CommandToRun { + path: std::path::PathBuf::from("/path/to/my/file.rs"), + args: vec!["arg1".to_owned(), "arg2".to_owned()], + ..Default::default() + }, + BTreeMap::new(), + ); }, BareKey::Char('n') if key.has_modifiers(&[KeyModifier::Ctrl]) => { open_command_pane_floating( @@ -221,6 +224,7 @@ impl ZellijPlugin for State { ..Default::default() }, None, + BTreeMap::new(), ); }, BareKey::Char('o') if key.has_modifiers(&[KeyModifier::Ctrl]) => { diff --git a/zellij-server/src/os_input_output.rs b/zellij-server/src/os_input_output.rs index 426d3485..099a3434 100644 --- a/zellij-server/src/os_input_output.rs +++ b/zellij-server/src/os_input_output.rs @@ -337,6 +337,7 @@ fn spawn_terminal( cwd, hold_on_close: false, hold_on_start: false, + ..Default::default() } }, TerminalAction::RunCommand(command) => command, diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap index a1ab0475..f8262b52 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_floating_plugin_command.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4400 +assertion_line: 4557 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -16,6 +16,13 @@ Some( cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), }, ), ), diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap index 935f72bb..a1247d5e 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_command_pane_plugin_command.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4323 +assertion_line: 4479 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -16,6 +16,13 @@ Some( cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: Some( + OriginatingPlugin { + plugin_id: 0, + client_id: 1, + context: {}, + }, + ), }, ), ), diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap index 09752304..0ade1098 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_floating_plugin_command.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4390 +assertion_line: 4401 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -15,6 +15,7 @@ Some( ), hold_on_close: false, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap index 425190e1..3491f831 100644 --- a/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap +++ b/zellij-server/src/plugins/unit/snapshots/zellij_server__plugins__plugin_tests__open_terminal_plugin_command.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/plugins/./unit/plugin_tests.rs -assertion_line: 4312 +assertion_line: 4323 expression: "format!(\"{:#?}\", new_tab_event)" --- Some( @@ -15,6 +15,7 @@ Some( ), hold_on_close: false, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs index 00a7795b..ce68c109 100644 --- a/zellij-server/src/plugins/wasm_bridge.rs +++ b/zellij-server/src/plugins/wasm_bridge.rs @@ -1314,6 +1314,8 @@ fn check_event_permission( | Event::SessionUpdate(..) | Event::CopyToClipboard(..) | Event::SystemClipboardFailure + | Event::CommandPaneOpened(..) + | Event::CommandPaneExited(..) | Event::InputReceived => PermissionType::ReadApplicationState, _ => return (PermissionStatus::Granted, None), }; diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs index 0006e048..8722d64a 100644 --- a/zellij-server/src/plugins/zellij_exports.rs +++ b/zellij-server/src/plugins/zellij_exports.rs @@ -18,7 +18,7 @@ use std::{ use wasmtime::{Caller, Linker}; use zellij_utils::data::{ CommandType, ConnectToSession, FloatingPaneCoordinates, HttpVerb, LayoutInfo, MessageToPlugin, - PermissionStatus, PermissionType, PluginPermission, + OriginatingPlugin, PermissionStatus, PermissionType, PluginPermission, }; use zellij_utils::input::permission::PermissionCache; use zellij_utils::{ @@ -99,13 +99,19 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => { open_terminal_floating(env, cwd.path.try_into()?, floating_pane_coordinates) }, - PluginCommand::OpenCommandPane(command_to_run) => { - open_command_pane(env, command_to_run) + PluginCommand::OpenCommandPane(command_to_run, context) => { + open_command_pane(env, command_to_run, context) }, PluginCommand::OpenCommandPaneFloating( command_to_run, floating_pane_coordinates, - ) => open_command_pane_floating(env, command_to_run, floating_pane_coordinates), + context, + ) => open_command_pane_floating( + env, + command_to_run, + floating_pane_coordinates, + context, + ), PluginCommand::SwitchTabTo(tab_index) => switch_tab_to(env, tab_index), PluginCommand::SetTimeout(seconds) => set_timeout(env, seconds), PluginCommand::ExecCmd(command_line) => exec_cmd(env, command_line), @@ -221,8 +227,8 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { PluginCommand::OpenTerminalInPlace(cwd) => { open_terminal_in_place(env, cwd.path.try_into()?) }, - PluginCommand::OpenCommandPaneInPlace(command_to_run) => { - open_command_pane_in_place(env, command_to_run) + PluginCommand::OpenCommandPaneInPlace(command_to_run, context) => { + open_command_pane_in_place(env, command_to_run, context) }, PluginCommand::RenameSession(new_session_name) => { rename_session(env, new_session_name) @@ -246,6 +252,12 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) { PluginCommand::DumpSessionLayout => dump_session_layout(env), PluginCommand::CloseSelf => close_self(env), PluginCommand::Reconfigure(new_config) => reconfigure(env, new_config)?, + PluginCommand::HidePaneWithId(pane_id) => { + hide_pane_with_id(env, pane_id.into())? + }, + PluginCommand::ShowPaneWithId(pane_id, should_float_if_hidden) => { + show_pane_with_id(env, pane_id.into(), should_float_if_hidden) + }, }, (PermissionStatus::Denied, permission) => { log::error!( @@ -530,31 +542,10 @@ fn open_terminal_in_place(env: &PluginEnv, cwd: PathBuf) { apply_action!(action, error_msg, env); } -fn open_command_pane(env: &PluginEnv, command_to_run: CommandToRun) { - let error_msg = || format!("failed to open command in plugin {}", env.name()); - let command = command_to_run.path; - let cwd = command_to_run.cwd.map(|cwd| env.plugin_cwd.join(cwd)); - let args = command_to_run.args; - let direction = None; - let hold_on_close = true; - let hold_on_start = false; - let name = None; - let run_command_action = RunCommandAction { - command, - args, - cwd, - direction, - hold_on_close, - hold_on_start, - }; - let action = Action::NewTiledPane(direction, Some(run_command_action), name); - apply_action!(action, error_msg, env); -} - -fn open_command_pane_floating( +fn open_command_pane( env: &PluginEnv, command_to_run: CommandToRun, - floating_pane_coordinates: Option, + context: BTreeMap, ) { let error_msg = || format!("failed to open command in plugin {}", env.name()); let command = command_to_run.path; @@ -571,12 +562,22 @@ fn open_command_pane_floating( direction, hold_on_close, hold_on_start, + originating_plugin: Some(OriginatingPlugin::new( + env.plugin_id, + env.client_id, + context, + )), }; - let action = Action::NewFloatingPane(Some(run_command_action), name, floating_pane_coordinates); + let action = Action::NewTiledPane(direction, Some(run_command_action), name); apply_action!(action, error_msg, env); } -fn open_command_pane_in_place(env: &PluginEnv, command_to_run: CommandToRun) { +fn open_command_pane_floating( + env: &PluginEnv, + command_to_run: CommandToRun, + floating_pane_coordinates: Option, + context: BTreeMap, +) { let error_msg = || format!("failed to open command in plugin {}", env.name()); let command = command_to_run.path; let cwd = command_to_run.cwd.map(|cwd| env.plugin_cwd.join(cwd)); @@ -592,6 +593,41 @@ fn open_command_pane_in_place(env: &PluginEnv, command_to_run: CommandToRun) { direction, hold_on_close, hold_on_start, + originating_plugin: Some(OriginatingPlugin::new( + env.plugin_id, + env.client_id, + context, + )), + }; + let action = Action::NewFloatingPane(Some(run_command_action), name, floating_pane_coordinates); + apply_action!(action, error_msg, env); +} + +fn open_command_pane_in_place( + env: &PluginEnv, + command_to_run: CommandToRun, + context: BTreeMap, +) { + let error_msg = || format!("failed to open command in plugin {}", env.name()); + let command = command_to_run.path; + let cwd = command_to_run.cwd.map(|cwd| env.plugin_cwd.join(cwd)); + let args = command_to_run.args; + let direction = None; + let hold_on_close = true; + let hold_on_start = false; + let name = None; + let run_command_action = RunCommandAction { + command, + args, + cwd, + direction, + hold_on_close, + hold_on_start, + originating_plugin: Some(OriginatingPlugin::new( + env.plugin_id, + env.client_id, + context, + )), }; let action = Action::NewInPlacePane(Some(run_command_action), name); apply_action!(action, error_msg, env); @@ -762,12 +798,28 @@ fn hide_self(env: &PluginEnv) -> Result<()> { .with_context(|| format!("failed to hide self")) } +fn hide_pane_with_id(env: &PluginEnv, pane_id: PaneId) -> Result<()> { + env.senders + .send_to_screen(ScreenInstruction::SuppressPane(pane_id, env.client_id)) + .with_context(|| format!("failed to hide self")) +} + fn show_self(env: &PluginEnv, should_float_if_hidden: bool) { let action = Action::FocusPluginPaneWithId(env.plugin_id, should_float_if_hidden); let error_msg = || format!("Failed to show self for plugin"); apply_action!(action, error_msg, env); } +fn show_pane_with_id(env: &PluginEnv, pane_id: PaneId, should_float_if_hidden: bool) { + let _ = env + .senders + .send_to_screen(ScreenInstruction::FocusPaneWithId( + pane_id, + should_float_if_hidden, + env.client_id, + )); +} + fn close_self(env: &PluginEnv) { env.senders .send_to_screen(ScreenInstruction::ClosePane( @@ -1448,6 +1500,8 @@ fn check_command_permission( | PluginCommand::RenameSession(..) | PluginCommand::RenameTab(..) | PluginCommand::DisconnectOtherClients + | PluginCommand::ShowPaneWithId(..) + | PluginCommand::HidePaneWithId(..) | PluginCommand::KillSessions(..) => PermissionType::ChangeApplicationState, PluginCommand::UnblockCliPipeInput(..) | PluginCommand::BlockCliPipeInput(..) diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs index 2d91e3ac..74d66a57 100644 --- a/zellij-server/src/pty.rs +++ b/zellij-server/src/pty.rs @@ -9,11 +9,12 @@ use crate::{ ClientId, ServerInstruction, }; use async_std::task::{self, JoinHandle}; +use std::sync::Arc; use std::{collections::HashMap, os::unix::io::RawFd, path::PathBuf}; use zellij_utils::nix::unistd::Pid; use zellij_utils::{ async_std, - data::FloatingPaneCoordinates, + data::{Event, FloatingPaneCoordinates}, errors::prelude::*, errors::{ContextType, PtyContext}, input::{ @@ -173,6 +174,24 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box) -> Result<()> { } else { None }; + + // if this command originated in a plugin, we send the plugin back an event + // to let it know the command started and which pane_id it has + if let Some(originating_plugin) = + run_command.and_then(|r| r.originating_plugin) + { + let update_event = + Event::CommandPaneOpened(pid, originating_plugin.context.clone()); + pty.bus + .senders + .send_to_plugin(PluginInstruction::Update(vec![( + Some(originating_plugin.plugin_id), + Some(originating_plugin.client_id), + update_event, + )])) + .with_context(err_context)?; + } + pty.bus .senders .send_to_screen(ScreenInstruction::NewPane( @@ -764,6 +783,7 @@ impl Pty { cwd, // note: this might also be filled by the calling function, eg. spawn_terminal hold_on_close: false, hold_on_start: false, + ..Default::default() }) }, } @@ -827,11 +847,13 @@ impl Pty { terminal_action }, }; - let (hold_on_start, hold_on_close) = match &terminal_action { - TerminalAction::RunCommand(run_command) => { - (run_command.hold_on_start, run_command.hold_on_close) - }, - _ => (false, false), + let (hold_on_start, hold_on_close, originating_plugin) = match &terminal_action { + TerminalAction::RunCommand(run_command) => ( + run_command.hold_on_start, + run_command.hold_on_close, + run_command.originating_plugin.clone(), + ), + _ => (false, false, None), }; if hold_on_start { @@ -847,9 +869,27 @@ impl Pty { return Ok((terminal_id, starts_held)); } + let originating_plugin = Arc::new(originating_plugin.clone()); let quit_cb = Box::new({ let senders = self.bus.senders.clone(); move |pane_id, exit_status, command| { + // if this command originated in a plugin, we send the plugin an event letting it + // know the command exited and some other useful information + if let PaneId::Terminal(pane_id) = pane_id { + if let Some(originating_plugin) = originating_plugin.as_ref() { + let update_event = Event::CommandPaneExited( + pane_id, + exit_status, + originating_plugin.context.clone(), + ); + let _ = senders.send_to_plugin(PluginInstruction::Update(vec![( + Some(originating_plugin.plugin_id), + Some(originating_plugin.client_id), + update_event, + )])); + } + } + if hold_on_close { let _ = senders.send_to_screen(ScreenInstruction::HoldPane( pane_id, diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap index 1e88d09c..0f9b59e1 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_command_and_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 1915 +assertion_line: 2306 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminalVertically(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false })), None, 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminalVertically(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), None, 10), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap index bb30c0d2..a1fd2b91 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_pane_action_with_floating_pane_and_coordinates.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2040 +assertion_line: 2349 expression: "format!(\"{:?}\", * received_pty_instructions.lock().unwrap())" --- -[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None }), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] +[SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None })), Some(true), None, Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None }), ClientId(10)), UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), Exit] diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs index d46b904a..61e193c0 100644 --- a/zellij-tile/src/shim.rs +++ b/zellij-tile/src/shim.rs @@ -131,8 +131,8 @@ pub fn open_terminal_in_place>(path: P) { } /// Open a new command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI). -pub fn open_command_pane(command_to_run: CommandToRun) { - let plugin_command = PluginCommand::OpenCommandPane(command_to_run); +pub fn open_command_pane(command_to_run: CommandToRun, context: BTreeMap) { + let plugin_command = PluginCommand::OpenCommandPane(command_to_run, context); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); object_to_stdout(&protobuf_plugin_command.encode_to_vec()); unsafe { host_run_plugin_command() }; @@ -142,16 +142,18 @@ pub fn open_command_pane(command_to_run: CommandToRun) { pub fn open_command_pane_floating( command_to_run: CommandToRun, coordinates: Option, + context: BTreeMap, ) { - let plugin_command = PluginCommand::OpenCommandPaneFloating(command_to_run, coordinates); + let plugin_command = + PluginCommand::OpenCommandPaneFloating(command_to_run, coordinates, context); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); object_to_stdout(&protobuf_plugin_command.encode_to_vec()); unsafe { host_run_plugin_command() }; } /// Open a new in place command pane with the specified command and args (this sort of pane allows the user to control the command, re-run it and see its exit status through the Zellij UI). -pub fn open_command_pane_in_place(command_to_run: CommandToRun) { - let plugin_command = PluginCommand::OpenCommandPaneInPlace(command_to_run); +pub fn open_command_pane_in_place(command_to_run: CommandToRun, context: BTreeMap) { + let plugin_command = PluginCommand::OpenCommandPaneInPlace(command_to_run, context); let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); object_to_stdout(&protobuf_plugin_command.encode_to_vec()); unsafe { host_run_plugin_command() }; @@ -241,6 +243,14 @@ pub fn hide_self() { unsafe { host_run_plugin_command() }; } +/// Hide the pane (suppress it) with the specified [PaneId] from the UI +pub fn hide_pane_with_id(pane_id: PaneId) { + let plugin_command = PluginCommand::HidePaneWithId(pane_id); + let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); + object_to_stdout(&protobuf_plugin_command.encode_to_vec()); + unsafe { host_run_plugin_command() }; +} + /// Show the plugin pane (unsuppress it if it is suppressed), focus it and switch to its tab pub fn show_self(should_float_if_hidden: bool) { let plugin_command = PluginCommand::ShowSelf(should_float_if_hidden); @@ -249,6 +259,14 @@ pub fn show_self(should_float_if_hidden: bool) { unsafe { host_run_plugin_command() }; } +/// Show the pane (unsuppress it if it is suppressed) with the specified [PaneId], focus it and switch to its tab +pub fn show_pane_with_id(pane_id: PaneId, should_float_if_hidden: bool) { + let plugin_command = PluginCommand::ShowPaneWithId(pane_id, should_float_if_hidden); + let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap(); + object_to_stdout(&protobuf_plugin_command.encode_to_vec()); + unsafe { host_run_plugin_command() }; +} + /// Close this plugin pane pub fn close_self() { let plugin_command = PluginCommand::CloseSelf; diff --git a/zellij-utils/assets/prost/api.event.rs b/zellij-utils/assets/prost/api.event.rs index 6277b309..10de020d 100644 --- a/zellij-utils/assets/prost/api.event.rs +++ b/zellij-utils/assets/prost/api.event.rs @@ -11,7 +11,7 @@ pub struct Event { pub name: i32, #[prost( oneof = "event::Payload", - tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15" + tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17" )] pub payload: ::core::option::Option, } @@ -48,10 +48,32 @@ pub mod event { RunCommandResultPayload(super::RunCommandResultPayload), #[prost(message, tag = "15")] WebRequestResultPayload(super::WebRequestResultPayload), + #[prost(message, tag = "16")] + CommandPaneOpenedPayload(super::CommandPaneOpenedPayload), + #[prost(message, tag = "17")] + CommandPaneExitedPayload(super::CommandPaneExitedPayload), } } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct CommandPaneOpenedPayload { + #[prost(uint32, tag = "1")] + pub terminal_pane_id: u32, + #[prost(message, repeated, tag = "2")] + pub context: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CommandPaneExitedPayload { + #[prost(uint32, tag = "1")] + pub terminal_pane_id: u32, + #[prost(int32, optional, tag = "2")] + pub exit_code: ::core::option::Option, + #[prost(message, repeated, tag = "3")] + pub context: ::prost::alloc::vec::Vec, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct SessionUpdatePayload { #[prost(message, repeated, tag = "1")] pub session_manifests: ::prost::alloc::vec::Vec, @@ -349,6 +371,8 @@ pub enum EventType { SessionUpdate = 16, RunCommandResult = 17, WebRequestResult = 18, + CommandPaneOpened = 19, + CommandPaneExited = 20, } impl EventType { /// String value of the enum field names used in the ProtoBuf definition. @@ -376,6 +400,8 @@ impl EventType { EventType::SessionUpdate => "SessionUpdate", EventType::RunCommandResult => "RunCommandResult", EventType::WebRequestResult => "WebRequestResult", + EventType::CommandPaneOpened => "CommandPaneOpened", + EventType::CommandPaneExited => "CommandPaneExited", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -400,6 +426,8 @@ impl EventType { "SessionUpdate" => Some(Self::SessionUpdate), "RunCommandResult" => Some(Self::RunCommandResult), "WebRequestResult" => Some(Self::WebRequestResult), + "CommandPaneOpened" => Some(Self::CommandPaneOpened), + "CommandPaneExited" => Some(Self::CommandPaneExited), _ => None, } } diff --git a/zellij-utils/assets/prost/api.plugin_command.rs b/zellij-utils/assets/prost/api.plugin_command.rs index 1e57602e..9ac2d7bf 100644 --- a/zellij-utils/assets/prost/api.plugin_command.rs +++ b/zellij-utils/assets/prost/api.plugin_command.rs @@ -5,7 +5,7 @@ pub struct PluginCommand { pub name: i32, #[prost( oneof = "plugin_command::Payload", - tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63" + tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65" )] pub payload: ::core::option::Option, } @@ -120,10 +120,28 @@ pub mod plugin_command { NewTabsWithLayoutInfoPayload(super::NewTabsWithLayoutInfoPayload), #[prost(string, tag = "63")] ReconfigurePayload(::prost::alloc::string::String), + #[prost(message, tag = "64")] + HidePaneWithIdPayload(super::HidePaneWithIdPayload), + #[prost(message, tag = "65")] + ShowPaneWithIdPayload(super::ShowPaneWithIdPayload), } } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct HidePaneWithIdPayload { + #[prost(message, optional, tag = "1")] + pub pane_id: ::core::option::Option, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ShowPaneWithIdPayload { + #[prost(message, optional, tag = "1")] + pub pane_id: ::core::option::Option, + #[prost(bool, tag = "2")] + pub should_float_if_hidden: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct NewTabsWithLayoutInfoPayload { #[prost(message, optional, tag = "1")] pub layout_info: ::core::option::Option, @@ -235,6 +253,8 @@ pub struct OpenCommandPanePayload { pub command_to_run: ::core::option::Option, #[prost(message, optional, tag = "2")] pub floating_pane_coordinates: ::core::option::Option, + #[prost(message, repeated, tag = "3")] + pub context: ::prost::alloc::vec::Vec, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] @@ -434,6 +454,8 @@ pub enum CommandName { CloseSelf = 85, NewTabsWithLayoutInfo = 86, Reconfigure = 87, + HidePaneWithId = 88, + ShowPaneWithId = 89, } impl CommandName { /// String value of the enum field names used in the ProtoBuf definition. @@ -530,6 +552,8 @@ impl CommandName { CommandName::CloseSelf => "CloseSelf", CommandName::NewTabsWithLayoutInfo => "NewTabsWithLayoutInfo", CommandName::Reconfigure => "Reconfigure", + CommandName::HidePaneWithId => "HidePaneWithId", + CommandName::ShowPaneWithId => "ShowPaneWithId", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -623,6 +647,8 @@ impl CommandName { "CloseSelf" => Some(Self::CloseSelf), "NewTabsWithLayoutInfo" => Some(Self::NewTabsWithLayoutInfo), "Reconfigure" => Some(Self::Reconfigure), + "HidePaneWithId" => Some(Self::HidePaneWithId), + "ShowPaneWithId" => Some(Self::ShowPaneWithId), _ => None, } } diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 0ebb6f1b..cb27a706 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -910,9 +910,12 @@ pub enum Event { Vec, BTreeMap, ), // status, - // headers, - // body, - // context + // headers, + // body, + // context + CommandPaneOpened(u32, Context), // u32 - terminal_pane_id + CommandPaneExited(u32, Option, Context), // u32 - terminal_pane_id, Option - + // exit_code } #[derive( @@ -1671,6 +1674,25 @@ impl FloatingPaneCoordinates { } } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct OriginatingPlugin { + pub plugin_id: u32, + pub client_id: ClientId, + pub context: Context, +} + +impl OriginatingPlugin { + pub fn new(plugin_id: u32, client_id: ClientId, context: Context) -> Self { + OriginatingPlugin { + plugin_id, + client_id, + context, + } + } +} + +type Context = BTreeMap; + #[derive(Debug, Clone, EnumDiscriminants, ToString)] #[strum_discriminants(derive(EnumString, Hash, Serialize, Deserialize))] #[strum_discriminants(name(CommandType))] @@ -1684,8 +1706,8 @@ pub enum PluginCommand { OpenFileFloating(FileToOpen, Option), OpenTerminal(FileToOpen), // only used for the path as cwd OpenTerminalFloating(FileToOpen, Option), // only used for the path as cwd - OpenCommandPane(CommandToRun), - OpenCommandPaneFloating(CommandToRun, Option), + OpenCommandPane(CommandToRun, Context), + OpenCommandPaneFloating(CommandToRun, Option, Context), SwitchTabTo(u32), // tab index SetTimeout(f64), // seconds ExecCmd(Vec), @@ -1747,7 +1769,7 @@ pub enum PluginCommand { DeleteAllDeadSessions, // String -> session name OpenTerminalInPlace(FileToOpen), // only used for the path as cwd OpenFileInPlace(FileToOpen), - OpenCommandPaneInPlace(CommandToRun), + OpenCommandPaneInPlace(CommandToRun, Context), RunCommand( Vec, // command BTreeMap, // env_variables @@ -1774,4 +1796,6 @@ pub enum PluginCommand { CloseSelf, NewTabsWithLayoutInfo(LayoutInfo), Reconfigure(String), // String -> stringified configuration + HidePaneWithId(PaneId), + ShowPaneWithId(PaneId, bool), // bool -> should_float_if_hidden } diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index 32a8a828..50bcf2af 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -432,6 +432,7 @@ impl Action { direction, hold_on_close, hold_on_start, + ..Default::default() }; if floating { Ok(vec![Action::NewFloatingPane( diff --git a/zellij-utils/src/input/command.rs b/zellij-utils/src/input/command.rs index c05aa644..2b860f66 100644 --- a/zellij-utils/src/input/command.rs +++ b/zellij-utils/src/input/command.rs @@ -1,5 +1,5 @@ //! Trigger a command -use crate::data::Direction; +use crate::data::{Direction, OriginatingPlugin}; use serde::{Deserialize, Serialize}; use std::path::PathBuf; @@ -35,6 +35,8 @@ pub struct RunCommand { pub hold_on_close: bool, #[serde(default)] pub hold_on_start: bool, + #[serde(default)] + pub originating_plugin: Option, } impl std::fmt::Display for RunCommand { @@ -68,6 +70,8 @@ pub struct RunCommandAction { pub hold_on_close: bool, #[serde(default)] pub hold_on_start: bool, + #[serde(default)] + pub originating_plugin: Option, } impl From for RunCommand { @@ -78,6 +82,7 @@ impl From for RunCommand { cwd: action.cwd, hold_on_close: action.hold_on_close, hold_on_start: action.hold_on_start, + originating_plugin: action.originating_plugin, } } } @@ -91,6 +96,7 @@ impl From for RunCommandAction { direction: None, hold_on_close: run_command.hold_on_close, hold_on_start: run_command.hold_on_start, + originating_plugin: run_command.originating_plugin, } } } diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_added_to_args_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_added_to_args_in_template.snap index 0d8a3635..32af5be5 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_added_to_args_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_added_to_args_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1352 +assertion_line: 1410 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -54,6 +55,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_override_args_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_override_args_in_template.snap index 65db8169..83c3040b 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_override_args_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__args_override_args_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1317 +assertion_line: 1375 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -28,6 +28,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -57,6 +58,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_added_to_close_on_exit_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_added_to_close_on_exit_in_template.snap index f9208fc3..7ad4d582 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_added_to_close_on_exit_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_added_to_close_on_exit_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1369 +assertion_line: 1427 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -51,6 +52,7 @@ Layout { cwd: None, hold_on_close: false, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_overrides_close_on_exit_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_overrides_close_on_exit_in_template.snap index adc88ee8..17c1b957 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_overrides_close_on_exit_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__close_on_exit_overrides_close_on_exit_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1335 +assertion_line: 1393 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -51,6 +52,7 @@ Layout { cwd: None, hold_on_close: false, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_added_to_cwd_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_added_to_cwd_in_template.snap index 721b37d5..fd2c4367 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_added_to_cwd_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_added_to_cwd_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1404 +assertion_line: 1462 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -53,6 +54,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_override_cwd_in_template.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_override_cwd_in_template.snap index bad9bf62..065c224e 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_override_cwd_in_template.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__cwd_override_cwd_in_template.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1387 +assertion_line: 1445 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -55,6 +56,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__env_var_expansion.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__env_var_expansion.snap index 25cfceb5..96b3368e 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__env_var_expansion.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__env_var_expansion.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 2141 +assertion_line: 2230 expression: "format!(\"{layout:#?}\")" --- Layout { @@ -107,6 +107,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), @@ -183,6 +184,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd.snap index 8bf48d27..506f125a 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1789 +assertion_line: 1847 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -46,6 +46,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_pane_templates.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_pane_templates.snap index a8938ed8..d3ca7b10 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_pane_templates.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_pane_templates.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1810 +assertion_line: 1868 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -50,6 +50,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_tab_templates.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_tab_templates.snap index 3abbaaee..f378d730 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_tab_templates.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_and_tab_cwd_prepended_to_panes_with_and_without_cwd_in_tab_templates.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1829 +assertion_line: 1887 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -46,6 +46,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_given_to_panes_without_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_given_to_panes_without_cwd.snap index adb41072..45cceeae 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_given_to_panes_without_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_given_to_panes_without_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1674 +assertion_line: 1732 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -47,6 +47,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor.snap index 3ae5eee2..5fa90d82 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1707 +assertion_line: 1765 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -47,6 +47,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor_overrides_global_cwd_in_layout_file.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor_overrides_global_cwd_in_layout_file.snap index dcd2d932..5cb9b89f 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor_overrides_global_cwd_in_layout_file.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_passed_from_layout_constructor_overrides_global_cwd_in_layout_file.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1728 +assertion_line: 1786 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -47,6 +47,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_prepended_to_panes_with_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_prepended_to_panes_with_cwd.snap index d292e95f..9b090525 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_prepended_to_panes_with_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_prepended_to_panes_with_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1687 +assertion_line: 1745 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -47,6 +47,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_with_tab_cwd_given_to_panes_without_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_with_tab_cwd_given_to_panes_without_cwd.snap index 2abeb3d1..56daf176 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_with_tab_cwd_given_to_panes_without_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__global_cwd_with_tab_cwd_given_to_panes_without_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1744 +assertion_line: 1802 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -46,6 +46,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_close_on_exit.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_close_on_exit.snap index 1c3e5a38..ed00fc5e 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_close_on_exit.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_close_on_exit.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 481 +assertion_line: 511 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: false, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_start_suspended.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_start_suspended.snap index 11986040..711a3107 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_start_suspended.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_command_panes_and_start_suspended.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 494 +assertion_line: 524 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -25,6 +25,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: true, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_tab_and_pane_templates.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_tab_and_pane_templates.snap index 30bd1b85..7bcdec0e 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_tab_and_pane_templates.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__layout_with_tab_and_pane_templates.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 834 +assertion_line: 892 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -48,6 +48,7 @@ Layout { cwd: None, hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_is_overriden_by_its_consumers_bare_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_is_overriden_by_its_consumers_bare_cwd.snap index e8cbac56..fa2cac82 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_is_overriden_by_its_consumers_bare_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_is_overriden_by_its_consumers_bare_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1558 +assertion_line: 1616 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_overriden_by_its_consumers_command_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_overriden_by_its_consumers_command_cwd.snap index e03609cf..b70dca22 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_overriden_by_its_consumers_command_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_overriden_by_its_consumers_command_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1504 +assertion_line: 1562 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_remains_when_its_consumer_command_does_not_have_a_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_remains_when_its_consumer_command_does_not_have_a_cwd.snap index c7214bb2..03a02e4a 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_remains_when_its_consumer_command_does_not_have_a_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_with_cwd_remains_when_its_consumer_command_does_not_have_a_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1521 +assertion_line: 1579 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_is_overriden_by_its_consumers_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_is_overriden_by_its_consumers_cwd.snap index e3308e18..3f803880 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_is_overriden_by_its_consumers_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_is_overriden_by_its_consumers_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1539 +assertion_line: 1597 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_receives_its_consumers_bare_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_receives_its_consumers_bare_cwd.snap index 748f5f91..1bb20e26 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_receives_its_consumers_bare_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_command_without_cwd_receives_its_consumers_bare_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1576 +assertion_line: 1634 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_with_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_with_cwd.snap index 4923ab97..98b99d53 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_with_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_with_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1628 +assertion_line: 1686 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_without_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_without_cwd.snap index 5067ae79..131d89fd 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_without_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__pane_template_with_bare_propagated_to_its_consumer_command_without_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1610 +assertion_line: 1668 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -27,6 +27,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_given_to_panes_without_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_given_to_panes_without_cwd.snap index 49019f51..1f4a0dd7 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_given_to_panes_without_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_given_to_panes_without_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1759 +assertion_line: 1817 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -46,6 +46,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_prepended_to_panes_with_cwd.snap b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_prepended_to_panes_with_cwd.snap index ffc6958e..0d4a6f4a 100644 --- a/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_prepended_to_panes_with_cwd.snap +++ b/zellij-utils/src/input/unit/snapshots/zellij_utils__input__layout__layout_test__tab_cwd_prepended_to_panes_with_cwd.snap @@ -1,6 +1,6 @@ --- source: zellij-utils/src/input/./unit/layout_test.rs -assertion_line: 1774 +assertion_line: 1832 expression: "format!(\"{:#?}\", layout)" --- Layout { @@ -46,6 +46,7 @@ Layout { ), hold_on_close: true, hold_on_start: false, + originating_plugin: None, }, ), ), diff --git a/zellij-utils/src/kdl/kdl_layout_parser.rs b/zellij-utils/src/kdl/kdl_layout_parser.rs index b2952501..f19cc9a2 100644 --- a/zellij-utils/src/kdl/kdl_layout_parser.rs +++ b/zellij-utils/src/kdl/kdl_layout_parser.rs @@ -455,6 +455,7 @@ impl<'a> KdlLayoutParser<'a> { cwd, hold_on_close, hold_on_start, + ..Default::default() }))), (None, Some(edit), Some(cwd)) => { Ok(Some(Run::EditFile(cwd.join(edit), None, Some(cwd)))) diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index 95b534fd..b22c8112 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -946,6 +946,7 @@ impl TryFrom<(&KdlNode, &Options)> for Action { direction, hold_on_close, hold_on_start, + ..Default::default() }; let x = command_metadata .and_then(|c_m| kdl_child_string_value_for_entry(c_m, "x")) diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs index d148541e..b206dba0 100644 --- a/zellij-utils/src/plugin_api/action.rs +++ b/zellij-utils/src/plugin_api/action.rs @@ -1385,6 +1385,7 @@ impl TryFrom for RunCommandAction { direction, hold_on_close, hold_on_start, + ..Default::default() }) } } diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto index c48030aa..ac1bdd29 100644 --- a/zellij-utils/src/plugin_api/event.proto +++ b/zellij-utils/src/plugin_api/event.proto @@ -42,6 +42,8 @@ enum EventType { SessionUpdate = 16; RunCommandResult = 17; WebRequestResult = 18; + CommandPaneOpened = 19; + CommandPaneExited = 20; } message EventNameList { @@ -65,9 +67,22 @@ message Event { SessionUpdatePayload session_update_payload = 13; RunCommandResultPayload run_command_result_payload = 14; WebRequestResultPayload web_request_result_payload = 15; + CommandPaneOpenedPayload command_pane_opened_payload = 16; + CommandPaneExitedPayload command_pane_exited_payload = 17; } } +message CommandPaneOpenedPayload { + uint32 terminal_pane_id = 1; + repeated ContextItem context = 2; +} + +message CommandPaneExitedPayload { + uint32 terminal_pane_id = 1; + optional int32 exit_code = 2; + repeated ContextItem context = 3; +} + message SessionUpdatePayload { repeated SessionManifest session_manifests = 1; repeated ResurrectableSession resurrectable_sessions = 2; diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs index 7996801c..c10c6ec0 100644 --- a/zellij-utils/src/plugin_api/event.rs +++ b/zellij-utils/src/plugin_api/event.rs @@ -235,6 +235,33 @@ impl TryFrom for Event { }, _ => Err("Malformed payload for the WebRequestResult Event"), }, + Some(ProtobufEventType::CommandPaneOpened) => match protobuf_event.payload { + Some(ProtobufEventPayload::CommandPaneOpenedPayload( + command_pane_opened_payload, + )) => Ok(Event::CommandPaneOpened( + command_pane_opened_payload.terminal_pane_id, + command_pane_opened_payload + .context + .into_iter() + .map(|c_i| (c_i.name, c_i.value)) + .collect(), + )), + _ => Err("Malformed payload for the CommandPaneOpened Event"), + }, + Some(ProtobufEventType::CommandPaneExited) => match protobuf_event.payload { + Some(ProtobufEventPayload::CommandPaneExitedPayload( + command_pane_exited_payload, + )) => Ok(Event::CommandPaneExited( + command_pane_exited_payload.terminal_pane_id, + command_pane_exited_payload.exit_code, + command_pane_exited_payload + .context + .into_iter() + .map(|c_i| (c_i.name, c_i.value)) + .collect(), + )), + _ => Err("Malformed payload for the CommandPaneExited Event"), + }, None => Err("Unknown Protobuf Event"), } } @@ -460,6 +487,37 @@ impl TryFrom for ProtobufEvent { )), }) }, + Event::CommandPaneOpened(terminal_pane_id, context) => { + let command_pane_opened_payload = CommandPaneOpenedPayload { + terminal_pane_id, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + }; + Ok(ProtobufEvent { + name: ProtobufEventType::CommandPaneOpened as i32, + payload: Some(event::Payload::CommandPaneOpenedPayload( + command_pane_opened_payload, + )), + }) + }, + Event::CommandPaneExited(terminal_pane_id, exit_code, context) => { + let command_pane_exited_payload = CommandPaneExitedPayload { + terminal_pane_id, + exit_code, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + }; + Ok(ProtobufEvent { + name: ProtobufEventType::CommandPaneExited as i32, + payload: Some(event::Payload::CommandPaneExitedPayload( + command_pane_exited_payload, + )), + }) + }, } } } @@ -963,6 +1021,8 @@ impl TryFrom for EventType { ProtobufEventType::SessionUpdate => EventType::SessionUpdate, ProtobufEventType::RunCommandResult => EventType::RunCommandResult, ProtobufEventType::WebRequestResult => EventType::WebRequestResult, + ProtobufEventType::CommandPaneOpened => EventType::CommandPaneOpened, + ProtobufEventType::CommandPaneExited => EventType::CommandPaneExited, }) } } @@ -990,6 +1050,8 @@ impl TryFrom for ProtobufEventType { EventType::SessionUpdate => ProtobufEventType::SessionUpdate, EventType::RunCommandResult => ProtobufEventType::RunCommandResult, EventType::WebRequestResult => ProtobufEventType::WebRequestResult, + EventType::CommandPaneOpened => ProtobufEventType::CommandPaneOpened, + EventType::CommandPaneExited => ProtobufEventType::CommandPaneExited, }) } } diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto index 5442909e..3e3567dd 100644 --- a/zellij-utils/src/plugin_api/plugin_command.proto +++ b/zellij-utils/src/plugin_api/plugin_command.proto @@ -99,6 +99,8 @@ enum CommandName { CloseSelf = 85; NewTabsWithLayoutInfo = 86; Reconfigure = 87; + HidePaneWithId = 88; + ShowPaneWithId = 89; } message PluginCommand { @@ -157,9 +159,20 @@ message PluginCommand { string scan_host_folder_payload = 61; NewTabsWithLayoutInfoPayload new_tabs_with_layout_info_payload = 62; string reconfigure_payload = 63; + HidePaneWithIdPayload hide_pane_with_id_payload = 64; + ShowPaneWithIdPayload show_pane_with_id_payload = 65; } } +message HidePaneWithIdPayload { + PaneId pane_id = 1; +} + +message ShowPaneWithIdPayload { + PaneId pane_id = 1; + bool should_float_if_hidden = 2; +} + message NewTabsWithLayoutInfoPayload { event.LayoutInfo layout_info = 1; } @@ -230,6 +243,7 @@ message OpenFilePayload { message OpenCommandPanePayload { command.Command command_to_run = 1; optional FloatingPaneCoordinates floating_pane_coordinates = 2; + repeated ContextItem context = 3; } message SwitchTabToPayload { diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs index a6514b1b..e72001e2 100644 --- a/zellij-utils/src/plugin_api/plugin_command.rs +++ b/zellij-utils/src/plugin_api/plugin_command.rs @@ -6,14 +6,14 @@ pub use super::generated_api::api::{ plugin_command::Payload, CliPipeOutputPayload, CommandName, ContextItem, EnvVariable, ExecCmdPayload, FixedOrPercent as ProtobufFixedOrPercent, FixedOrPercentValue as ProtobufFixedOrPercentValue, - FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HttpVerb as ProtobufHttpVerb, - IdAndNewName, KillSessionsPayload, MessageToPluginPayload, MovePayload, - NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload, + FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HidePaneWithIdPayload, + HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, MessageToPluginPayload, + MovePayload, NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload, OpenCommandPanePayload, OpenFilePayload, PaneId as ProtobufPaneId, PaneType as ProtobufPaneType, PluginCommand as ProtobufPluginCommand, PluginMessagePayload, RequestPluginPermissionPayload, ResizePayload, RunCommandPayload, SetTimeoutPayload, - SubscribePayload, SwitchSessionPayload, SwitchTabToPayload, UnsubscribePayload, - WebRequestPayload, + ShowPaneWithIdPayload, SubscribePayload, SwitchSessionPayload, SwitchTabToPayload, + UnsubscribePayload, WebRequestPayload, }, plugin_permission::PermissionType as ProtobufPermissionType, resize::ResizeAction as ProtobufResizeAction, @@ -278,7 +278,15 @@ impl TryFrom for PluginCommand { Some(Payload::OpenCommandPanePayload(command_to_run_payload)) => { match command_to_run_payload.command_to_run { Some(command_to_run) => { - Ok(PluginCommand::OpenCommandPane(command_to_run.try_into()?)) + let context: BTreeMap = command_to_run_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPane( + command_to_run.try_into()?, + context, + )) }, None => Err("Malformed open open command pane payload"), } @@ -291,10 +299,18 @@ impl TryFrom for PluginCommand { .floating_pane_coordinates .map(|f| f.into()); match command_to_run_payload.command_to_run { - Some(command_to_run) => Ok(PluginCommand::OpenCommandPaneFloating( - command_to_run.try_into()?, - floating_pane_coordinates, - )), + Some(command_to_run) => { + let context: BTreeMap = command_to_run_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneFloating( + command_to_run.try_into()?, + floating_pane_coordinates, + context, + )) + }, None => Err("Malformed open command pane floating payload"), } }, @@ -719,9 +735,17 @@ impl TryFrom for PluginCommand { Some(CommandName::OpenCommandInPlace) => match protobuf_plugin_command.payload { Some(Payload::OpenCommandPaneInPlacePayload(command_to_run_payload)) => { match command_to_run_payload.command_to_run { - Some(command_to_run) => Ok(PluginCommand::OpenCommandPaneInPlace( - command_to_run.try_into()?, - )), + Some(command_to_run) => { + let context: BTreeMap = command_to_run_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneInPlace( + command_to_run.try_into()?, + context, + )) + }, None => Err("Malformed open command pane in-place payload"), } }, @@ -894,6 +918,30 @@ impl TryFrom for PluginCommand { }, _ => Err("Mismatched payload for Reconfigure"), }, + Some(CommandName::HidePaneWithId) => match protobuf_plugin_command.payload { + Some(Payload::HidePaneWithIdPayload(hide_pane_with_id_payload)) => { + let pane_id = hide_pane_with_id_payload + .pane_id + .and_then(|p_id| PaneId::try_from(p_id).ok()) + .ok_or("Failed to parse HidePaneWithId command")?; + Ok(PluginCommand::HidePaneWithId(pane_id)) + }, + _ => Err("Mismatched payload for HidePaneWithId"), + }, + Some(CommandName::ShowPaneWithId) => match protobuf_plugin_command.payload { + Some(Payload::ShowPaneWithIdPayload(show_pane_with_id_payload)) => { + let pane_id = show_pane_with_id_payload + .pane_id + .and_then(|p_id| PaneId::try_from(p_id).ok()) + .ok_or("Failed to parse ShowPaneWithId command")?; + let should_float_if_hidden = show_pane_with_id_payload.should_float_if_hidden; + Ok(PluginCommand::ShowPaneWithId( + pane_id, + should_float_if_hidden, + )) + }, + _ => Err("Mismatched payload for ShowPaneWithId"), + }, None => Err("Unrecognized plugin command"), } } @@ -965,20 +1013,36 @@ impl TryFrom for ProtobufPluginCommand { })), }) }, - PluginCommand::OpenCommandPane(command_to_run) => Ok(ProtobufPluginCommand { - name: CommandName::OpenCommandPane as i32, - payload: Some(Payload::OpenCommandPanePayload(OpenCommandPanePayload { - command_to_run: Some(command_to_run.try_into()?), - floating_pane_coordinates: None, - })), - }), - PluginCommand::OpenCommandPaneFloating(command_to_run, floating_pane_coordinates) => { + PluginCommand::OpenCommandPane(command_to_run, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPane as i32, + payload: Some(Payload::OpenCommandPanePayload(OpenCommandPanePayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: None, + context, + })), + }) + }, + PluginCommand::OpenCommandPaneFloating( + command_to_run, + floating_pane_coordinates, + context, + ) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); Ok(ProtobufPluginCommand { name: CommandName::OpenCommandPaneFloating as i32, payload: Some(Payload::OpenCommandPaneFloatingPayload( OpenCommandPanePayload { command_to_run: Some(command_to_run.try_into()?), floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context, }, )), }) @@ -1277,15 +1341,22 @@ impl TryFrom for ProtobufPluginCommand { floating_pane_coordinates: None, })), }), - PluginCommand::OpenCommandPaneInPlace(command_to_run) => Ok(ProtobufPluginCommand { - name: CommandName::OpenCommandInPlace as i32, - payload: Some(Payload::OpenCommandPaneInPlacePayload( - OpenCommandPanePayload { - command_to_run: Some(command_to_run.try_into()?), - floating_pane_coordinates: None, - }, - )), - }), + PluginCommand::OpenCommandPaneInPlace(command_to_run, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandInPlace as i32, + payload: Some(Payload::OpenCommandPaneInPlacePayload( + OpenCommandPanePayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: None, + context, + }, + )), + }) + }, PluginCommand::RunCommand(command_line, env_variables, cwd, context) => { let env_variables: Vec<_> = env_variables .into_iter() @@ -1430,6 +1501,21 @@ impl TryFrom for ProtobufPluginCommand { name: CommandName::Reconfigure as i32, payload: Some(Payload::ReconfigurePayload(reconfigure_payload)), }), + PluginCommand::HidePaneWithId(pane_id_to_hide) => Ok(ProtobufPluginCommand { + name: CommandName::HidePaneWithId as i32, + payload: Some(Payload::HidePaneWithIdPayload(HidePaneWithIdPayload { + pane_id: ProtobufPaneId::try_from(pane_id_to_hide).ok(), + })), + }), + PluginCommand::ShowPaneWithId(pane_id_to_show, should_float_if_hidden) => { + Ok(ProtobufPluginCommand { + name: CommandName::ShowPaneWithId as i32, + payload: Some(Payload::ShowPaneWithIdPayload(ShowPaneWithIdPayload { + pane_id: ProtobufPaneId::try_from(pane_id_to_show).ok(), + should_float_if_hidden, + })), + }) + }, } } }