diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-10-31 20:15:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-31 20:15:32 +0100 |
| commit | 82f30e2cde5207e5b51301633686b2c7feac54f3 (patch) | |
| tree | 2bdc9a39be42b9e781619730fc6558afe0783838 /zellij-utils | |
| parent | Feature: watcher clients (#4487) (diff) | |
| download | sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.tar.gz sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.tar.xz sl0ppij-82f30e2cde5207e5b51301633686b2c7feac54f3.zip | |
Improve CLI interface (add detach, switch session, blocking zellij run and more) (#4492)
* initial implementation
* fix tests
* move more ations
* screen adjustments (does not compile)
* plugin/pty adjustments (does not compile)
* more progress, tests not compiling
* fix tests
* more progress, does not compile
* more progress, compiles, tests failing
* tests passing
* rely on Drop for NotificationEnd
* atomicify some more actions
* fmt
* move unblock input to route
* don't pass hard-coded action names
* refactor: consolidate completion channel logic
* comment
* track last active client
* track cli clients explicitly
* use the last active client for cli commands when possible
* fix focus-next-pane for multiple clients
* various fixes for multi-client actions from the cli
* add detach action
* fix tests
* add switch session cli action
* fix switch session deadlock
* add and layout to switch-session cli action
* blocking zellij run: add NewBlockingPane variant
* blocking zellij run: wait forever mechanism
* blocking zellij run: thread NotificationEnd as needed until TerminalPane (tests not compiling)
* blocking zellij run: update cli
* blocking zellij run: add command
* blocking zellij run: finish implementation
* fix tests
* e2e test and close_on_exit fixes
* fmt
* fix e2e tests
* fix plugin tests
Diffstat (limited to 'zellij-utils')
| -rw-r--r-- | zellij-utils/assets/prost/api.action.rs | 3 | ||||
| -rw-r--r-- | zellij-utils/assets/prost_ipc/client_server_contract.rs | 68 | ||||
| -rw-r--r-- | zellij-utils/src/cli.rs | 27 | ||||
| -rw-r--r-- | zellij-utils/src/client_server_contract/client_to_server.proto | 1 | ||||
| -rw-r--r-- | zellij-utils/src/client_server_contract/common_types.proto | 34 | ||||
| -rw-r--r-- | zellij-utils/src/data.rs | 76 | ||||
| -rw-r--r-- | zellij-utils/src/input/actions.rs | 118 | ||||
| -rw-r--r-- | zellij-utils/src/ipc.rs | 3 | ||||
| -rw-r--r-- | zellij-utils/src/ipc/protobuf_conversion.rs | 181 | ||||
| -rw-r--r-- | zellij-utils/src/ipc/tests/roundtrip_tests.rs | 155 | ||||
| -rw-r--r-- | zellij-utils/src/kdl/mod.rs | 73 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/action.proto | 1 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/action.rs | 4 |
13 files changed, 719 insertions, 25 deletions
diff --git a/zellij-utils/assets/prost/api.action.rs b/zellij-utils/assets/prost/api.action.rs index b835236b..8f381ee0 100644 --- a/zellij-utils/assets/prost/api.action.rs +++ b/zellij-utils/assets/prost/api.action.rs @@ -476,6 +476,7 @@ pub enum ActionName { TogglePaneInGroup = 87, ToggleGroupMarking = 88, NewStackedPane = 89, + SwitchSession = 90, } impl ActionName { /// String value of the enum field names used in the ProtoBuf definition. @@ -571,6 +572,7 @@ impl ActionName { ActionName::TogglePaneInGroup => "TogglePaneInGroup", ActionName::ToggleGroupMarking => "ToggleGroupMarking", ActionName::NewStackedPane => "NewStackedPane", + ActionName::SwitchSession => "SwitchSession", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -663,6 +665,7 @@ impl ActionName { "TogglePaneInGroup" => Some(Self::TogglePaneInGroup), "ToggleGroupMarking" => Some(Self::ToggleGroupMarking), "NewStackedPane" => Some(Self::NewStackedPane), + "SwitchSession" => Some(Self::SwitchSession), _ => None, } } diff --git a/zellij-utils/assets/prost_ipc/client_server_contract.rs b/zellij-utils/assets/prost_ipc/client_server_contract.rs index 26b5a155..c977170c 100644 --- a/zellij-utils/assets/prost_ipc/client_server_contract.rs +++ b/zellij-utils/assets/prost_ipc/client_server_contract.rs @@ -119,7 +119,7 @@ pub struct RgbColor { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Action { - #[prost(oneof="action::ActionType", tags="1, 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, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91")] + #[prost(oneof="action::ActionType", tags="1, 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, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93")] pub action_type: ::core::option::Option<action::ActionType>, } /// Nested message and enum types in `Action`. @@ -309,9 +309,13 @@ pub mod action { TogglePaneInGroup(super::TogglePaneInGroupAction), #[prost(message, tag="91")] ToggleGroupMarking(super::ToggleGroupMarkingAction), + #[prost(message, tag="92")] + SwitchSession(super::SwitchSessionAction), + #[prost(message, tag="93")] + NewBlockingPane(super::NewBlockingPaneAction), } } -// Action message definitions (all 91 variants) +// Action message definitions (all 92 variants) /// Simple action types (no data) #[allow(clippy::derive_partial_eq_without_eq)] @@ -629,6 +633,16 @@ pub struct NewStackedPaneAction { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewBlockingPaneAction { + #[prost(message, optional, tag="1")] + pub placement: ::core::option::Option<NewPanePlacement>, + #[prost(string, optional, tag="2")] + pub pane_name: ::core::option::Option<::prost::alloc::string::String>, + #[prost(message, optional, tag="3")] + pub command: ::core::option::Option<RunCommandAction>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PaneNameInputAction { #[prost(uint32, repeated, tag="1")] pub input: ::prost::alloc::vec::Vec<u32>, @@ -984,6 +998,51 @@ pub struct ConnectToSession { } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] +pub struct SwitchSessionAction { + #[prost(string, tag="1")] + pub name: ::prost::alloc::string::String, + #[prost(uint32, optional, tag="2")] + pub tab_position: ::core::option::Option<u32>, + #[prost(message, optional, tag="3")] + pub pane_id: ::core::option::Option<PaneIdWithPlugin>, + #[prost(message, optional, tag="4")] + pub layout: ::core::option::Option<LayoutInfo>, + #[prost(string, optional, tag="5")] + pub cwd: ::core::option::Option<::prost::alloc::string::String>, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewPanePlacement { + #[prost(oneof="new_pane_placement::PlacementType", tags="1, 2, 3, 4, 5")] + pub placement_type: ::core::option::Option<new_pane_placement::PlacementType>, +} +/// Nested message and enum types in `NewPanePlacement`. +pub mod new_pane_placement { + #[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum PlacementType { + #[prost(bool, tag="1")] + NoPreference(bool), + #[prost(enumeration="super::Direction", tag="2")] + Tiled(i32), + #[prost(message, tag="3")] + Floating(super::FloatingPaneCoordinates), + #[prost(message, tag="4")] + InPlace(super::NewPanePlacementInPlace), + #[prost(message, tag="5")] + Stacked(super::PaneId), + } +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct NewPanePlacementInPlace { + #[prost(message, optional, tag="1")] + pub pane_id_to_replace: ::core::option::Option<PaneId>, + #[prost(bool, tag="2")] + pub close_replaced_pane: bool, +} +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] pub struct PaneIdWithPlugin { #[prost(uint32, tag="1")] pub pane_id: u32, @@ -1813,6 +1872,7 @@ pub enum ExitReason { Disconnect = 5, WebClientsForbidden = 6, Error = 7, + CustomExitStatus = 8, } impl ExitReason { /// String value of the enum field names used in the ProtoBuf definition. @@ -1829,6 +1889,7 @@ impl ExitReason { ExitReason::Disconnect => "EXIT_REASON_DISCONNECT", ExitReason::WebClientsForbidden => "EXIT_REASON_WEB_CLIENTS_FORBIDDEN", ExitReason::Error => "EXIT_REASON_ERROR", + ExitReason::CustomExitStatus => "EXIT_REASON_CUSTOM_EXIT_STATUS", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -1842,6 +1903,7 @@ impl ExitReason { "EXIT_REASON_DISCONNECT" => Some(Self::Disconnect), "EXIT_REASON_WEB_CLIENTS_FORBIDDEN" => Some(Self::WebClientsForbidden), "EXIT_REASON_ERROR" => Some(Self::Error), + "EXIT_REASON_CUSTOM_EXIT_STATUS" => Some(Self::CustomExitStatus), _ => None, } } @@ -2396,6 +2458,8 @@ pub struct ActionMsg { pub terminal_id: ::core::option::Option<u32>, #[prost(uint32, optional, tag="3")] pub client_id: ::core::option::Option<u32>, + #[prost(bool, tag="4")] + pub is_cli_client: bool, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs index da1f777a..0fd52473 100644 --- a/zellij-utils/src/cli.rs +++ b/zellij-utils/src/cli.rs @@ -388,6 +388,9 @@ pub enum Sessions { takes_value(false) )] stacked: bool, + /// Whether to block until this command has finished + #[clap(long, value_parser, default_value("false"), takes_value(false))] + blocking: bool, }, /// Load a plugin #[clap(visible_alias = "p")] @@ -686,6 +689,8 @@ pub enum CliAction { takes_value(false) )] stacked: bool, + #[clap(short, long)] + blocking: bool, }, /// Open the specified file in a new zellij pane with your default EDITOR Edit { @@ -940,4 +945,26 @@ tail -f /tmp/my-live-logfile | zellij action pipe --name logs --plugin https://e #[clap(long)] pinned: Option<bool>, }, + /// Detach from the current session + Detach, + /// Switch to a different session + SwitchSession { + /// Name of the session to switch to + name: String, + /// Optional tab position to focus + #[clap(long)] + tab_position: Option<usize>, + /// Optional pane ID to focus (eg. "terminal_1" for terminal pane with id 1, or "plugin_2" for plugin pane with id 2) + #[clap(long)] + pane_id: Option<String>, + /// Layout to apply when switching to the session (relative paths start at layout-dir) + #[clap(short, long, value_parser)] + layout: Option<PathBuf>, + /// Default folder to look for layouts + #[clap(long, value_parser, requires("layout"))] + layout_dir: Option<PathBuf>, + /// Change the working directory when switching + #[clap(short, long, value_parser)] + cwd: Option<PathBuf>, + }, } diff --git a/zellij-utils/src/client_server_contract/client_to_server.proto b/zellij-utils/src/client_server_contract/client_to_server.proto index 9ec0a49f..cae8b6d3 100644 --- a/zellij-utils/src/client_server_contract/client_to_server.proto +++ b/zellij-utils/src/client_server_contract/client_to_server.proto @@ -68,6 +68,7 @@ message ActionMsg { Action action = 1; optional uint32 terminal_id = 2; optional uint32 client_id = 3; + bool is_cli_client = 4; } message KeyMsg { diff --git a/zellij-utils/src/client_server_contract/common_types.proto b/zellij-utils/src/client_server_contract/common_types.proto index be86e0d1..254a2a75 100644 --- a/zellij-utils/src/client_server_contract/common_types.proto +++ b/zellij-utils/src/client_server_contract/common_types.proto @@ -227,10 +227,12 @@ message Action { ChangeFloatingPaneCoordinatesAction change_floating_pane_coordinates = 89; TogglePaneInGroupAction toggle_pane_in_group = 90; ToggleGroupMarkingAction toggle_group_marking = 91; + SwitchSessionAction switch_session = 92; + NewBlockingPaneAction new_blocking_pane = 93; } } -// Action message definitions (all 91 variants) +// Action message definitions (all 92 variants) // Simple action types (no data) message QuitAction {} @@ -364,6 +366,12 @@ message NewStackedPaneAction { optional string pane_name = 2; } +message NewBlockingPaneAction { + NewPanePlacement placement = 1; + optional string pane_name = 2; + optional RunCommandAction command = 3; +} + message PaneNameInputAction { repeated uint32 input = 1; } @@ -605,6 +613,29 @@ message ConnectToSession { optional string cwd = 5; } +message SwitchSessionAction { + string name = 1; + optional uint32 tab_position = 2; + optional PaneIdWithPlugin pane_id = 3; + optional LayoutInfo layout = 4; + optional string cwd = 5; +} + +message NewPanePlacement { + oneof placement_type { + bool no_preference = 1; + Direction tiled = 2; + FloatingPaneCoordinates floating = 3; + NewPanePlacementInPlace in_place = 4; + PaneId stacked = 5; + } +} + +message NewPanePlacementInPlace { + optional PaneId pane_id_to_replace = 1; + bool close_replaced_pane = 2; +} + message PaneIdWithPlugin { uint32 pane_id = 1; bool is_plugin = 2; @@ -619,6 +650,7 @@ enum ExitReason { EXIT_REASON_DISCONNECT = 5; EXIT_REASON_WEB_CLIENTS_FORBIDDEN = 6; EXIT_REASON_ERROR = 7; + EXIT_REASON_CUSTOM_EXIT_STATUS = 8; } // Additional supporting types for Action messages diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs index 53425e0b..7f700d4d 100644 --- a/zellij-utils/src/data.rs +++ b/zellij-utils/src/data.rs @@ -2582,6 +2582,82 @@ impl FromStr for WebSharing { } } +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum NewPanePlacement { + NoPreference, + Tiled(Option<Direction>), + Floating(Option<FloatingPaneCoordinates>), + InPlace { + pane_id_to_replace: Option<PaneId>, + close_replaced_pane: bool, + }, + Stacked(Option<PaneId>), +} + +impl Default for NewPanePlacement { + fn default() -> Self { + NewPanePlacement::NoPreference + } +} + +impl NewPanePlacement { + pub fn with_floating_pane_coordinates( + floating_pane_coordinates: Option<FloatingPaneCoordinates>, + ) -> Self { + NewPanePlacement::Floating(floating_pane_coordinates) + } + pub fn with_should_be_in_place( + self, + should_be_in_place: bool, + close_replaced_pane: bool, + ) -> Self { + if should_be_in_place { + NewPanePlacement::InPlace { + pane_id_to_replace: None, + close_replaced_pane, + } + } else { + self + } + } + pub fn with_pane_id_to_replace( + pane_id_to_replace: Option<PaneId>, + close_replaced_pane: bool, + ) -> Self { + NewPanePlacement::InPlace { + pane_id_to_replace, + close_replaced_pane, + } + } + pub fn should_float(&self) -> Option<bool> { + match self { + NewPanePlacement::Floating(_) => Some(true), + NewPanePlacement::Tiled(_) => Some(false), + _ => None, + } + } + pub fn floating_pane_coordinates(&self) -> Option<FloatingPaneCoordinates> { + match self { + NewPanePlacement::Floating(floating_pane_coordinates) => { + floating_pane_coordinates.clone() + }, + _ => None, + } + } + pub fn should_stack(&self) -> bool { + match self { + NewPanePlacement::Stacked(_) => true, + _ => false, + } + } + pub fn id_of_stack_root(&self) -> Option<PaneId> { + match self { + NewPanePlacement::Stacked(id) => *id, + _ => None, + } + } +} + type Context = BTreeMap<String, String>; #[derive(Debug, Clone, EnumDiscriminants, ToString)] diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs index fa5374f0..d623197b 100644 --- a/zellij-utils/src/input/actions.rs +++ b/zellij-utils/src/input/actions.rs @@ -6,7 +6,7 @@ use super::layout::{ SwapFloatingLayout, SwapTiledLayout, TiledPaneLayout, }; use crate::cli::CliAction; -use crate::data::{Direction, KeyWithModifier, PaneId, Resize}; +use crate::data::{Direction, KeyWithModifier, LayoutInfo, NewPanePlacement, PaneId, Resize}; use crate::data::{FloatingPaneCoordinates, InputMode}; use crate::home::{find_default_config_dir, get_layout_dir}; use crate::input::config::{Config, ConfigError, KdlError}; @@ -99,7 +99,7 @@ impl FromStr for SearchOption { // They might need to be adjusted in the default config // as well `../../assets/config/default.yaml` /// Actions that can be bound to keys. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, strum_macros::Display)] pub enum Action { /// Quit Zellij. Quit, @@ -190,6 +190,11 @@ pub enum Action { pane_name: Option<String>, start_suppressed: bool, }, + NewBlockingPane { + placement: NewPanePlacement, + pane_name: Option<String>, + command: Option<RunCommandAction>, + }, /// Open the file in a new pane using the default editor EditFile { payload: OpenFilePayload, @@ -269,6 +274,14 @@ pub enum Action { }, /// Detach session and exit Detach, + /// Switch to a different session + SwitchSession { + name: String, + tab_position: Option<usize>, + pane_id: Option<(u32, bool)>, // (id, is_plugin) + layout: Option<LayoutInfo>, + cwd: Option<PathBuf>, + }, LaunchOrFocusPlugin { plugin: RunPluginOrAlias, should_float: bool, @@ -478,6 +491,7 @@ impl Action { height, pinned, stacked, + blocking, } => { let current_dir = get_current_dir(); // cwd should only be specified in a plugin alias if it was explicitly given to us, @@ -486,7 +500,51 @@ impl Action { let cwd = cwd .map(|cwd| current_dir.join(cwd)) .or_else(|| Some(current_dir.clone())); - if let Some(plugin) = plugin { + if blocking { + // For blocking panes, we don't support plugins + if plugin.is_some() { + return Err("Blocking panes do not support plugin variants".to_string()); + } + + let command = if !command.is_empty() { + let mut command = command.clone(); + let (command, args) = (PathBuf::from(command.remove(0)), command); + let hold_on_start = start_suspended; + let hold_on_close = !close_on_exit; + Some(RunCommandAction { + command, + args, + cwd, + direction, + hold_on_close, + hold_on_start, + ..Default::default() + }) + } else { + None + }; + + let placement = if floating { + NewPanePlacement::Floating(FloatingPaneCoordinates::new( + x, y, width, height, pinned, + )) + } else if in_place { + NewPanePlacement::InPlace { + pane_id_to_replace: None, + close_replaced_pane: false, + } + } else if stacked { + NewPanePlacement::Stacked(None) + } else { + NewPanePlacement::Tiled(direction) + }; + + Ok(vec![Action::NewBlockingPane { + placement, + pane_name: name, + command, + }]) + } else if let Some(plugin) = plugin { let plugin = match RunPluginLocation::parse(&plugin, cwd.clone()) { Ok(location) => { let user_configuration = configuration.unwrap_or_default(); @@ -633,9 +691,7 @@ impl Action { coordinates: FloatingPaneCoordinates::new(x, y, width, height, pinned), }]) }, - CliAction::SwitchMode { input_mode } => { - Ok(vec![Action::SwitchModeForAllClients { input_mode }]) - }, + CliAction::SwitchMode { input_mode } => Ok(vec![Action::SwitchToMode { input_mode }]), CliAction::TogglePaneEmbedOrFloating => Ok(vec![Action::TogglePaneEmbedOrFloating]), CliAction::ToggleFloatingPanes => Ok(vec![Action::ToggleFloatingPanes]), CliAction::ClosePane => Ok(vec![Action::CloseFocus]), @@ -939,6 +995,56 @@ impl Action { } } }, + CliAction::Detach => Ok(vec![Action::Detach]), + CliAction::SwitchSession { + name, + tab_position, + pane_id, + layout, + layout_dir, + cwd, + } => { + let pane_id = match pane_id { + Some(stringified_pane_id) => match PaneId::from_str(&stringified_pane_id) { + Ok(PaneId::Terminal(id)) => Some((id, false)), + Ok(PaneId::Plugin(id)) => Some((id, true)), + Err(_e) => { + return Err(format!( + "Malformed pane id: {}, expecting either a bare integer (eg. 1), a terminal pane id (eg. terminal_1) or a plugin pane id (eg. plugin_1)", + stringified_pane_id + )); + }, + }, + None => None, + }; + + let cwd = cwd.map(|cwd| { + let current_dir = get_current_dir(); + current_dir.join(cwd) + }); + + let layout_dir = layout_dir.map(|layout_dir| { + let current_dir = get_current_dir(); + current_dir.join(layout_dir) + }); + + let layout_info = if let Some(layout_path) = layout { + let layout_dir = layout_dir + .or_else(|| config.and_then(|c| c.options.layout_dir.clone())) + .or_else(|| get_layout_dir(find_default_config_dir())); + LayoutInfo::from_config(&layout_dir, &Some(layout_path)) + } else { + None + }; + + Ok(vec![Action::SwitchSession { + name: name.clone(), + tab_position: tab_position.clone(), + pane_id, + layout: layout_info, + cwd, + }]) + }, } } pub fn launches_plugin(&self, plugin_url: &str) -> bool { diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index 1f37b2e7..53dd4d9f 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -121,6 +121,7 @@ pub enum ClientToServerMsg { action: Action, terminal_id: Option<u32>, client_id: Option<ClientId>, + is_cli_client: bool, }, Key { key: KeyWithModifier, @@ -181,6 +182,7 @@ pub enum ExitReason { CannotAttach, Disconnect, WebClientsForbidden, + CustomExitStatus(i32), Error(String), } @@ -225,6 +227,7 @@ There are a few things you can try now: " ) }, + Self::CustomExitStatus(exit_status) => write!(f, "Exit {}", exit_status), Self::Error(e) => write!(f, "Error occurred in server:\n{}", e), } } diff --git a/zellij-utils/src/ipc/protobuf_conversion.rs b/zellij-utils/src/ipc/protobuf_conversion.rs index 658c10f3..ab06faae 100644 --- a/zellij-utils/src/ipc/protobuf_conversion.rs +++ b/zellij-utils/src/ipc/protobuf_conversion.rs @@ -78,10 +78,12 @@ impl From<ClientToServerMsg> for ProtoClientToServerMsg { action, terminal_id, client_id, + is_cli_client, } => client_to_server_msg::Message::Action(ActionMsg { action: Some(action.into()), terminal_id, client_id: client_id.map(|id| id as u32), + is_cli_client, }), ClientToServerMsg::Key { key, @@ -198,6 +200,7 @@ impl TryFrom<ProtoClientToServerMsg> for ClientToServerMsg { .try_into()?, terminal_id: action.terminal_id, client_id: action.client_id.map(|id| id as u16), + is_cli_client: action.is_cli_client, }), Some(client_to_server_msg::Message::Key(key)) => Ok(ClientToServerMsg::Key { key: key.key.ok_or_else(|| anyhow!("Missing key"))?.try_into()?, @@ -239,6 +242,9 @@ impl From<ServerToClientMsg> for ProtoServerToClientMsg { ServerToClientMsg::Exit { exit_reason } => { let (proto_exit_reason, payload) = match exit_reason { ExitReason::Error(ref msg) => (ProtoExitReason::Error, Some(msg.clone())), + ExitReason::CustomExitStatus(status) => { + (ProtoExitReason::CustomExitStatus, Some(status.to_string())) + }, other => (ProtoExitReason::from(other), None), }; server_to_client_msg::Message::Exit(ExitMsg { @@ -310,6 +316,13 @@ impl TryFrom<ProtoServerToClientMsg> for ServerToClientMsg { exit.payload.unwrap_or_else(|| "Protobuf error".to_string()); ExitReason::Error(error_msg) }, + ProtoExitReason::CustomExitStatus => { + let status_str = exit.payload.unwrap_or_else(|| "0".to_string()); + let status = status_str + .parse::<i32>() + .map_err(|_| anyhow!("Invalid custom exit status: {}", status_str))?; + ExitReason::CustomExitStatus(status) + }, other => other.try_into()?, }; @@ -704,21 +717,22 @@ impl From<crate::input::actions::Action> HalfPageScrollDownAction, HalfPageScrollUpAction, KeybindPipeAction, LaunchOrFocusPluginAction, LaunchPluginAction, ListClientsAction, MouseEventAction, MoveFocusAction, MoveFocusOrTabAction, MovePaneAction, MovePaneBackwardsAction, - MoveTabAction, NewFloatingPaneAction, NewFloatingPluginPaneAction, - NewInPlacePaneAction, NewInPlacePluginPaneAction, NewPaneAction, NewStackedPaneAction, - NewTabAction, NewTiledPaneAction, NewTiledPluginPaneAction, NextSwapLayoutAction, - NoOpAction, PageScrollDownAction, PageScrollUpAction, PaneNameInputAction, - PreviousSwapLayoutAction, QueryTabNamesAction, QuitAction, RenamePluginPaneAction, - RenameSessionAction, RenameTabAction, RenameTerminalPaneAction, ResizeAction, - RunAction, ScrollDownAction, ScrollDownAtAction, ScrollToBottomAction, - ScrollToTopAction, ScrollUpAction, ScrollUpAtAction, SearchAction, SearchInputAction, - SearchToggleOptionAction, SkipConfirmAction, StackPanesAction, - StartOrReloadPluginAction, SwitchFocusAction, SwitchModeForAllClientsAction, - SwitchToModeAction, TabNameInputAction, ToggleActiveSyncTabAction, - ToggleFloatingPanesAction, ToggleFocusFullscreenAction, ToggleGroupMarkingAction, - ToggleMouseModeAction, TogglePaneEmbedOrFloatingAction, TogglePaneFramesAction, - TogglePaneInGroupAction, TogglePanePinnedAction, ToggleTabAction, UndoRenamePaneAction, - UndoRenameTabAction, WriteAction, WriteCharsAction, + MoveTabAction, NewBlockingPaneAction, NewFloatingPaneAction, + NewFloatingPluginPaneAction, NewInPlacePaneAction, NewInPlacePluginPaneAction, + NewPaneAction, NewStackedPaneAction, NewTabAction, NewTiledPaneAction, + NewTiledPluginPaneAction, NextSwapLayoutAction, NoOpAction, PageScrollDownAction, + PageScrollUpAction, PaneIdWithPlugin, PaneNameInputAction, PreviousSwapLayoutAction, + QueryTabNamesAction, QuitAction, RenamePluginPaneAction, RenameSessionAction, + RenameTabAction, RenameTerminalPaneAction, ResizeAction, RunAction, ScrollDownAction, + ScrollDownAtAction, ScrollToBottomAction, ScrollToTopAction, ScrollUpAction, + ScrollUpAtAction, SearchAction, SearchInputAction, SearchToggleOptionAction, + SkipConfirmAction, StackPanesAction, StartOrReloadPluginAction, SwitchFocusAction, + SwitchModeForAllClientsAction, SwitchSessionAction, SwitchToModeAction, + TabNameInputAction, ToggleActiveSyncTabAction, ToggleFloatingPanesAction, + ToggleFocusFullscreenAction, ToggleGroupMarkingAction, ToggleMouseModeAction, + TogglePaneEmbedOrFloatingAction, TogglePaneFramesAction, TogglePaneInGroupAction, + TogglePanePinnedAction, ToggleTabAction, UndoRenamePaneAction, UndoRenameTabAction, + WriteAction, WriteCharsAction, }; use std::collections::HashMap; @@ -890,6 +904,15 @@ impl From<crate::input::actions::Action> pane_name, }) }, + crate::input::actions::Action::NewBlockingPane { + placement, + pane_name, + command, + } => ActionType::NewBlockingPane(NewBlockingPaneAction { + placement: Some(placement.into()), + pane_name, + command: command.map(|c| c.into()), + }), crate::input::actions::Action::TogglePaneEmbedOrFloating => { ActionType::TogglePaneEmbedOrFloating(TogglePaneEmbedOrFloatingAction {}) }, @@ -960,6 +983,22 @@ impl From<crate::input::actions::Action> command: Some(command.into()), }), crate::input::actions::Action::Detach => ActionType::Detach(DetachAction {}), + crate::input::actions::Action::SwitchSession { + name, + tab_position, + pane_id, + layout, + cwd, + } => ActionType::SwitchSession(SwitchSessionAction { + name: name.clone(), + tab_position: tab_position.map(|p| p as u32), + pane_id: pane_id.map(|(id, is_plugin)| PaneIdWithPlugin { + pane_id: id, + is_plugin: is_plugin, + }), + layout: layout.as_ref().map(|l| l.clone().into()), + cwd: cwd.as_ref().map(|p| p.to_string_lossy().to_string()), + }), crate::input::actions::Action::LaunchOrFocusPlugin { plugin, should_float, @@ -1383,6 +1422,19 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action> pane_name: new_stacked_action.pane_name, }) }, + ActionType::NewBlockingPane(new_blocking_action) => { + Ok(crate::input::actions::Action::NewBlockingPane { + placement: new_blocking_action + .placement + .ok_or_else(|| anyhow!("NewBlockingPane missing placement"))? + .try_into()?, + pane_name: new_blocking_action.pane_name, + command: new_blocking_action + .command + .map(|c| c.try_into()) + .transpose()?, + }) + }, ActionType::TogglePaneEmbedOrFloating(_) => { Ok(crate::input::actions::Action::TogglePaneEmbedOrFloating) }, @@ -1466,6 +1518,21 @@ impl TryFrom<crate::client_server_contract::client_server_contract::Action> .try_into()?, }), ActionType::Detach(_) => Ok(crate::input::actions::Action::Detach), + ActionType::SwitchSession(switch_session_action) => { + Ok(crate::input::actions::Action::SwitchSession { + name: switch_session_action.name.clone(), + tab_position: switch_session_action.tab_position.map(|p| p as usize), + pane_id: switch_session_action + .pane_id + .as_ref() + .map(|p| (p.pane_id, p.is_plugin)), + layout: switch_session_action + .layout + .map(|l| l.try_into()) + .transpose()?, + cwd: switch_session_action.cwd.map(PathBuf::from), + }) + }, ActionType::LaunchOrFocusPlugin(launch_plugin_action) => { Ok(crate::input::actions::Action::LaunchOrFocusPlugin { plugin: launch_plugin_action @@ -1870,6 +1937,7 @@ impl From<ExitReason> for ProtoExitReason { ExitReason::Disconnect => ProtoExitReason::Disconnect, ExitReason::WebClientsForbidden => ProtoExitReason::WebClientsForbidden, ExitReason::Error(_msg) => ProtoExitReason::Error, + ExitReason::CustomExitStatus(_status) => ProtoExitReason::CustomExitStatus, } } } @@ -1885,6 +1953,7 @@ impl TryFrom<ProtoExitReason> for ExitReason { ProtoExitReason::Disconnect => Ok(ExitReason::Disconnect), ProtoExitReason::WebClientsForbidden => Ok(ExitReason::WebClientsForbidden), ProtoExitReason::Error => Ok(ExitReason::Error("Protobuf error".to_string())), + ProtoExitReason::CustomExitStatus => Ok(ExitReason::CustomExitStatus(0)), ProtoExitReason::Unspecified => Err(anyhow!("Unspecified exit reason")), } } @@ -2197,6 +2266,88 @@ impl TryFrom<crate::client_server_contract::client_server_contract::FloatingPane } } +// NewPanePlacement conversion +impl From<crate::data::NewPanePlacement> + for crate::client_server_contract::client_server_contract::NewPanePlacement +{ + fn from(placement: crate::data::NewPanePlacement) -> Self { + use crate::client_server_contract::client_server_contract::new_pane_placement::PlacementType; + let placement_type = match placement { + crate::data::NewPanePlacement::NoPreference => PlacementType::NoPreference(true), + crate::data::NewPanePlacement::Tiled(direction) => { + PlacementType::Tiled(direction.map(direction_to_proto_i32).unwrap_or(0)) + }, + crate::data::NewPanePlacement::Floating(coords) => { + PlacementType::Floating(coords.map(|c| c.into()).unwrap_or_default()) + }, + crate::data::NewPanePlacement::InPlace { + pane_id_to_replace, + close_replaced_pane, + } => PlacementType::InPlace( + crate::client_server_contract::client_server_contract::NewPanePlacementInPlace { + pane_id_to_replace: pane_id_to_replace.map(|id| id.into()), + close_replaced_pane, + }, + ), + crate::data::NewPanePlacement::Stacked(pane_id) => { + PlacementType::Stacked(pane_id.map(|id| id.into()).unwrap_or_default()) + }, + }; + Self { + placement_type: Some(placement_type), + } + } +} + +// Reverse NewPanePlacement conversion +impl TryFrom<crate::client_server_contract::client_server_contract::NewPanePlacement> + for crate::data::NewPanePlacement +{ + type Error = anyhow::Error; + fn try_from( + placement: crate::client_server_contract::client_server_contract::NewPanePlacement, + ) -> Result<Self> { + use crate::client_server_contract::client_server_contract::new_pane_placement::PlacementType; + match placement + .placement_type + .ok_or_else(|| anyhow!("NewPanePlacement missing placement_type"))? + { + PlacementType::NoPreference(_) => Ok(crate::data::NewPanePlacement::NoPreference), + PlacementType::Tiled(direction) => { + let direction = if direction == 0 { + None + } else { + Some(proto_i32_to_direction(direction)?) + }; + Ok(crate::data::NewPanePlacement::Tiled(direction)) + }, + PlacementType::Floating(coords) => { + let coords = if coords == Default::default() { + None + } else { + Some(coords.try_into()?) + }; + Ok(crate::data::NewPanePlacement::Floating(coords)) + }, + PlacementType::InPlace(in_place) => Ok(crate::data::NewPanePlacement::InPlace { + pane_id_to_replace: in_place + .pane_id_to_replace + .map(|id| id.try_into()) + .transpose()?, + close_replaced_pane: in_place.close_replaced_pane, + }), + PlacementType::Stacked(pane_id) => { + let pane_id = if pane_id == Default::default() { + None + } else { + Some(pane_id.try_into()?) + }; + Ok(crate::data::NewPanePlacement::Stacked(pane_id)) + }, + } + } +} + // MouseEvent conversion impl From<crate::input::mouse::MouseEvent> for crate::client_server_contract::client_server_contract::MouseEvent diff --git a/zellij-utils/src/ipc/tests/roundtrip_tests.rs b/zellij-utils/src/ipc/tests/roundtrip_tests.rs index a2585181..2ec513da 100644 --- a/zellij-utils/src/ipc/tests/roundtrip_tests.rs +++ b/zellij-utils/src/ipc/tests/roundtrip_tests.rs @@ -696,11 +696,13 @@ fn test_client_messages() { action: Action::Quit, terminal_id: None, client_id: None, + is_cli_client: false, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Quit, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Write { @@ -710,6 +712,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Write { @@ -720,6 +723,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::WriteChars { @@ -727,6 +731,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchToMode { @@ -735,6 +740,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchModeForAllClients { @@ -743,6 +749,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -751,6 +758,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -759,6 +767,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -767,6 +776,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -775,6 +785,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -783,6 +794,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Resize { @@ -791,21 +803,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusNextPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPreviousPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SwitchFocus, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveFocus { @@ -814,6 +830,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveFocusOrTab { @@ -821,11 +838,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePane { direction: None }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePane { @@ -833,16 +852,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MovePaneBackwards, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ClearScreen, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpScreen { @@ -851,6 +873,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpScreen { @@ -859,21 +882,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::DumpLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditScrollback, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUpAt { @@ -881,6 +908,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollUpAt { @@ -888,11 +916,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollDownAt { @@ -900,51 +930,61 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollToBottom, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ScrollToTop, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PageScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PageScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::HalfPageScrollUp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::HalfPageScrollDown, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleFocusFullscreen, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneFrames, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleActiveSyncTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewPane { @@ -954,6 +994,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewPane { @@ -963,6 +1004,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -980,6 +1022,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1001,6 +1044,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1022,6 +1066,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1043,6 +1088,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1070,6 +1116,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1097,6 +1144,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1124,6 +1172,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::EditFile { @@ -1145,6 +1194,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1154,6 +1204,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1178,6 +1229,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPane { @@ -1206,6 +1258,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPane { @@ -1215,6 +1268,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPane { @@ -1237,6 +1291,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePane { @@ -1258,6 +1313,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePane { @@ -1266,6 +1322,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewStackedPane { @@ -1287,6 +1344,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewStackedPane { @@ -1295,21 +1353,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneEmbedOrFloating, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleFloatingPanes, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseFocus, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PaneNameInput { @@ -1317,11 +1379,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::UndoRenamePane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1335,6 +1399,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1348,6 +1413,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1364,6 +1430,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1380,6 +1447,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1397,6 +1465,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1426,6 +1495,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1442,6 +1512,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1458,6 +1529,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1476,6 +1548,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1495,6 +1568,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1514,6 +1588,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1533,6 +1608,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1552,6 +1628,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1571,6 +1648,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1590,6 +1668,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1609,6 +1688,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1628,6 +1708,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1644,6 +1725,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1666,6 +1748,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1690,6 +1773,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1718,6 +1802,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1734,6 +1819,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1754,6 +1840,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1770,6 +1857,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1806,6 +1894,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1827,6 +1916,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1840,6 +1930,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTab { @@ -1853,31 +1944,37 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NoOp, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToNextTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToPreviousTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTab { index: 0 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTabName { @@ -1886,6 +1983,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::GoToTabName { @@ -1894,11 +1992,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TabNameInput { @@ -1906,11 +2006,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::UndoRenameTab, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MoveTab { @@ -1918,6 +2020,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Run { @@ -1935,11 +2038,13 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Detach, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchOrFocusPlugin { @@ -1952,6 +2057,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchOrFocusPlugin { @@ -1964,6 +2070,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchPlugin { @@ -1976,6 +2083,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::LaunchPlugin { @@ -1988,6 +2096,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2006,6 +2115,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2024,6 +2134,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::MouseEvent { @@ -2042,21 +2153,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Copy, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Confirm, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Deny, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SkipConfirm { @@ -2064,6 +2179,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchInput { @@ -2071,6 +2187,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Search { @@ -2078,6 +2195,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::Search { @@ -2085,6 +2203,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2092,6 +2211,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2099,6 +2219,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::SearchToggleOption { @@ -2106,26 +2227,31 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleMouseMode, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::PreviousSwapLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NextSwapLayout, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::QueryTabNames, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewTiledPluginPane { @@ -2136,6 +2262,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPluginPane { @@ -2147,6 +2274,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewFloatingPluginPane { @@ -2164,6 +2292,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::NewInPlacePluginPane { @@ -2173,6 +2302,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StartOrReloadPlugin { @@ -2180,16 +2310,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CloseTerminalPane { pane_id: 11 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ClosePluginPane { pane_id: 12 }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusTerminalPaneWithId { @@ -2198,6 +2331,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusTerminalPaneWithId { @@ -2206,6 +2340,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPluginPaneWithId { @@ -2214,6 +2349,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::FocusPluginPaneWithId { @@ -2222,6 +2358,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameTerminalPane { @@ -2230,6 +2367,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenamePluginPane { @@ -2238,6 +2376,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameTab { @@ -2246,21 +2385,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPane, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPaneRight, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::BreakPaneLeft, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::RenameSession { @@ -2268,6 +2411,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CliPipe { @@ -2286,6 +2430,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::CliPipe { @@ -2304,6 +2449,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::KeybindPipe { @@ -2322,6 +2468,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::KeybindPipe { @@ -2340,21 +2487,25 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ListClients, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePanePinned, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StackPanes { pane_ids: vec![] }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::StackPanes { @@ -2367,6 +2518,7 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ChangeFloatingPaneCoordinates { @@ -2382,16 +2534,19 @@ fn test_client_messages() { }, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::TogglePaneInGroup, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Action { action: Action::ToggleGroupMarking, terminal_id: Some(1), client_id: Some(100), + is_cli_client: true, }); test_client_roundtrip!(ClientToServerMsg::Key { key: KeyWithModifier { diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs index ad541a48..789c3d96 100644 --- a/zellij-utils/src/kdl/mod.rs +++ b/zellij-utils/src/kdl/mod.rs @@ -1022,6 +1022,35 @@ impl Action { }, }, Action::Detach => Some(KdlNode::new("Detach")), + Action::SwitchSession { + name, + tab_position, + pane_id, + layout, + cwd, + } => { + let mut node = KdlNode::new("SwitchSession"); + node.push(KdlEntry::new_prop("name", name.clone())); + if let Some(pos) = tab_position { + node.push(KdlEntry::new_prop("tab_position", *pos as i64)); + } + if let Some((id, is_plugin)) = pane_id { + node.push(KdlEntry::new_prop("pane_id", *id as i64)); + if *is_plugin { + node.push(KdlEntry::new_prop("is_plugin", true)); + } + } + if let Some(layout_info) = layout { + node.push(KdlEntry::new_prop("layout", layout_info.name())); + } + if let Some(cwd_path) = cwd { + node.push(KdlEntry::new_prop( + "cwd", + cwd_path.to_string_lossy().to_string(), + )); + } + Some(node) + }, Action::LaunchOrFocusPlugin { plugin: run_plugin_or_alias, should_float, @@ -1466,6 +1495,50 @@ impl TryFrom<(&KdlNode, &Options)> for Action { parse_kdl_action_arguments!(action_name, action_arguments, kdl_action) }, "Detach" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), + "SwitchSession" => { + let name = kdl_get_string_property_or_child_value!(kdl_action, "name") + .map(|s| s.to_string()) + .ok_or(ConfigError::new_kdl_error( + "SwitchSession action requires a 'name' property".into(), + kdl_action.span().offset(), + kdl_action.span().len(), + ))?; + let tab_position = + crate::kdl_get_int_property_or_child_value!(kdl_action, "tab_position") + .map(|i| i as usize); + let pane_id = crate::kdl_get_int_property_or_child_value!(kdl_action, "pane_id") + .map(|i| i as u32); + let is_plugin = + crate::kdl_get_bool_property_or_child_value!(kdl_action, "is_plugin") + .unwrap_or(false); + let pane_id_tuple = pane_id.map(|id| (id, is_plugin)); + + // Parse layout + let layout = if let Some(layout_str) = + kdl_get_string_property_or_child_value!(kdl_action, "layout") + { + let layout_path = PathBuf::from(layout_str); + let layout_dir = config_options + .layout_dir + .clone() + .or_else(|| get_layout_dir(find_default_config_dir())); + LayoutInfo::from_config(&layout_dir, &Some(layout_path)) + } else { + None + }; + + // Parse cwd + let cwd = + kdl_get_string_property_or_child_value!(kdl_action, "cwd").map(PathBuf::from); + + Ok(Action::SwitchSession { + name, + tab_position, + pane_id: pane_id_tuple, + layout, + cwd, + }) + }, "Copy" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), "Clear" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), "Confirm" => parse_kdl_action_arguments!(action_name, action_arguments, kdl_action), diff --git a/zellij-utils/src/plugin_api/action.proto b/zellij-utils/src/plugin_api/action.proto index 5bdd34e9..2772e725 100644 --- a/zellij-utils/src/plugin_api/action.proto +++ b/zellij-utils/src/plugin_api/action.proto @@ -244,6 +244,7 @@ enum ActionName { TogglePaneInGroup = 87; ToggleGroupMarking = 88; NewStackedPane = 89; + SwitchSession = 90; } message Position { diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs index 2b48ffe1..c442144a 100644 --- a/zellij-utils/src/plugin_api/action.rs +++ b/zellij-utils/src/plugin_api/action.rs @@ -1388,7 +1388,9 @@ impl TryFrom<Action> for ProtobufAction { pane_id: _, coordinates: _, } - | Action::SkipConfirm { action: _ } => Err("Unsupported action"), + | Action::SkipConfirm { action: _ } + | Action::NewBlockingPane { .. } + | Action::SwitchSession { .. } => Err("Unsupported action"), } } } |
