diff options
| author | user <user@clank> | 2026-08-12 19:34:15 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-12 19:34:15 +0200 |
| commit | d1c14ff0f5c5b55c46d91ad12f4a291041480a99 (patch) | |
| tree | 9dca9628d228b211a6919c9dd65cd7a9b4fcf6b0 /sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs | |
| parent | chore: initialize sl0ppi monorepo (diff) | |
| download | sl0ppi-d1c14ff0f5c5b55c46d91ad12f4a291041480a99.tar.gz sl0ppi-d1c14ff0f5c5b55c46d91ad12f4a291041480a99.tar.xz sl0ppi-d1c14ff0f5c5b55c46d91ad12f4a291041480a99.zip | |
vendor(sl0ppij): import zellij v0.45.0 tree
Squashed import of upstream zellij at 0e6e4404 ("Support the Kitty Image
Protocol (#5428)"), the merge-base our fork was developed against. Upstream's
3311 commits are deliberately NOT replayed here; only our own fork commits are,
so the monorepo stays small and `git log sl0ppij/` shows sl0p work, not zellij's
entire history.
Upstream provenance is tracked in FORKS.md and can always be re-fetched from
https://github.com/zellij-org/zellij.
Diffstat (limited to 'sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs')
| -rw-r--r-- | sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs | 5388 |
1 files changed, 5388 insertions, 0 deletions
diff --git a/sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs b/sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs new file mode 100644 index 0000000..3d86bc2 --- /dev/null +++ b/sl0ppij/zellij-utils/src/plugin_api/plugin_command.rs @@ -0,0 +1,5388 @@ +pub use super::generated_api::api::{ + action::{Action as ProtobufAction, PaneIdAndShouldFloat, SwitchToModePayload}, + event::{ + EventNameList as ProtobufEventNameList, Header, + ResurrectableSession as ProtobufResurrectableSession, + SessionManifest as ProtobufSessionManifest, + }, + input_mode::InputMode as ProtobufInputMode, + pane_frame_style::PaneFrameStyle as ProtobufPaneFrameStyle, + plugin_command::{ + break_panes_to_new_tab_response, break_panes_to_tab_with_id_response, + break_panes_to_tab_with_index_response, delete_layout_response, dump_layout_response, + dump_session_layout_response, edit_layout_response, focus_or_create_tab_response, + get_focused_pane_info_response, get_pane_cwd_response, get_pane_pid_response, + get_pane_running_command_response, get_session_list_response, hide_floating_panes_response, + highlight_style::Style as ProtobufHighlightStyleVariant, new_tab_response, + new_tab_unfocused_response, parse_layout_response, plugin_command::Payload, + rename_layout_response, save_layout_response, save_session_response, + show_floating_panes_response, BreakPanesToNewTabPayload, + BreakPanesToNewTabResponse as ProtobufBreakPanesToNewTabResponse, + BreakPanesToTabWithIdPayload, + BreakPanesToTabWithIdResponse as ProtobufBreakPanesToTabWithIdResponse, + BreakPanesToTabWithIndexPayload, + BreakPanesToTabWithIndexResponse as ProtobufBreakPanesToTabWithIndexResponse, + ChangeFloatingPanesCoordinatesPayload, ChangeHostFolderPayload, ClearPaneHighlightsPayload, + ClearScreenForPaneIdPayload, CliPipeOutputPayload, CloseMultiplePanesPayload, + CloseTabWithIdPayload, CloseTabWithIndexPayload, CommandName, ContextItem, + CopyToClipboardPayload, CreateTokenResponse as ProtobufCreateTokenResponse, + CreateTokenResponse, CurrentSessionLastSavedTimePayload, + CurrentSessionLastSavedTimeResponse as ProtobufCurrentSessionLastSavedTimeResponse, + CursorPosition, CustomIndexHighlight as ProtobufCustomIndexHighlight, + CustomRgbHighlight as ProtobufCustomRgbHighlight, + DeleteAllDeadSessionsResponse as ProtobufDeleteAllDeadSessionsResponse, + DeleteDeadSessionResponse as ProtobufDeleteDeadSessionResponse, DeleteLayoutPayload, + DeleteLayoutResponse as ProtobufDeleteLayoutResponse, DumpLayoutPayload, + DumpLayoutResponse as ProtobufDumpLayoutResponse, DumpSessionLayoutPayload, + DumpSessionLayoutResponse as ProtobufDumpSessionLayoutResponse, EditLayoutPayload, + EditLayoutResponse as ProtobufEditLayoutResponse, EditScrollbackForPaneWithIdPayload, + EmbedMultiplePanesPayload, EnvVariable, ExecCmdPayload, + FixedOrPercent as ProtobufFixedOrPercent, + FixedOrPercentValue as ProtobufFixedOrPercentValue, FloatMultiplePanesPayload, + FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, + FocusOrCreateTabResponse as ProtobufFocusOrCreateTabResponse, FocusedPaneInfo, + GenerateRandomNamePayload, + GenerateRandomNameResponse as ProtobufGenerateRandomNameResponse, + GenerateWebLoginTokenPayload, GetFocusedPaneInfoPayload, + GetFocusedPaneInfoResponse as ProtobufGetFocusedPaneInfoResponse, GetLayoutDirPayload, + GetLayoutDirResponse as ProtobufGetLayoutDirResponse, + GetPaneCwdPayload as ProtobufGetPaneCwdPayload, + GetPaneCwdResponse as ProtobufGetPaneCwdResponse, GetPaneInfoPayload, + GetPaneInfoResponse as ProtobufGetPaneInfoResponse, GetPanePidPayload, + GetPanePidResponse as ProtobufGetPanePidResponse, + GetPaneRunningCommandPayload as ProtobufGetPaneRunningCommandPayload, + GetPaneRunningCommandResponse as ProtobufGetPaneRunningCommandResponse, + GetPaneScrollbackPayload, + GetSessionEnvironmentVariablesPayload as ProtobufGetSessionEnvironmentVariablesPayload, + GetSessionEnvironmentVariablesResponse as ProtobufGetSessionEnvironmentVariablesResponse, + GetSessionListPayload as ProtobufGetSessionListPayload, + GetSessionListResponse as ProtobufGetSessionListResponse, GetTabInfoPayload, + GetTabInfoResponse as ProtobufGetTabInfoResponse, GoToTabWithIdPayload, + GroupAndUngroupPanesPayload, HideFloatingPanesPayload as ProtobufHideFloatingPanesPayload, + HideFloatingPanesResponse as ProtobufHideFloatingPanesResponse, HidePaneWithIdPayload, + HighlightAndUnhighlightPanesPayload, HighlightLayer as ProtobufHighlightLayer, + HighlightStyle as ProtobufHighlightStyle, HttpVerb as ProtobufHttpVerb, IdAndNewName, + KeyToRebind, KeyToUnbind, KillSessionsPayload, + KillSessionsResponse as ProtobufKillSessionsResponse, ListTokensResponse, + LoadNewPluginPayload, MessageToPluginPayload, MovePaneWithPaneIdInDirectionPayload, + MovePaneWithPaneIdPayload, MovePayload, NewPluginArgs as ProtobufNewPluginArgs, + NewTabPayload, NewTabResponse as ProtobufNewTabResponse, NewTabUnfocusedPayload, + NewTabUnfocusedResponse as ProtobufNewTabUnfocusedResponse, + NewTabsResponse as ProtobufNewTabsResponse, NewTabsWithLayoutInfoPayload, + NewTiledPaneInTabPayload, NewTiledPaneInTabResponse as ProtobufNewTiledPaneInTabResponse, + OpenCommandPaneBackgroundResponse as ProtobufOpenCommandPaneBackgroundResponse, + OpenCommandPaneFloatingNearPluginPayload, + OpenCommandPaneFloatingNearPluginResponse as ProtobufOpenCommandPaneFloatingNearPluginResponse, + OpenCommandPaneFloatingResponse as ProtobufOpenCommandPaneFloatingResponse, + OpenCommandPaneInPlaceOfPaneIdPayload, + OpenCommandPaneInPlaceOfPaneIdResponse as ProtobufOpenCommandPaneInPlaceOfPaneIdResponse, + OpenCommandPaneInPlaceOfPluginPayload, + OpenCommandPaneInPlaceOfPluginResponse as ProtobufOpenCommandPaneInPlaceOfPluginResponse, + OpenCommandPaneInPlaceResponse as ProtobufOpenCommandPaneInPlaceResponse, + OpenCommandPaneNearPluginPayload, + OpenCommandPaneNearPluginResponse as ProtobufOpenCommandPaneNearPluginResponse, + OpenCommandPanePayload, OpenCommandPaneResponse as ProtobufOpenCommandPaneResponse, + OpenEditPaneInPlaceOfPaneIdPayload, + OpenEditPaneInPlaceOfPaneIdResponse as ProtobufOpenEditPaneInPlaceOfPaneIdResponse, + OpenFileFloatingNearPluginPayload, + OpenFileFloatingNearPluginResponse as ProtobufOpenFileFloatingNearPluginResponse, + OpenFileFloatingResponse as ProtobufOpenFileFloatingResponse, + OpenFileInPlaceOfPluginPayload, + OpenFileInPlaceOfPluginResponse as ProtobufOpenFileInPlaceOfPluginResponse, + OpenFileInPlaceResponse as ProtobufOpenFileInPlaceResponse, OpenFileNearPluginPayload, + OpenFileNearPluginResponse as ProtobufOpenFileNearPluginResponse, OpenFilePayload, + OpenFileResponse as ProtobufOpenFileResponse, + OpenPaneInNewTabResponse as ProtobufOpenPaneInNewTabResponse, + OpenPluginPaneFloatingPayload, + OpenPluginPaneFloatingResponse as ProtobufOpenPluginPaneFloatingResponse, + OpenPluginPaneInNewTabPayload as ProtobufOpenPluginPaneInNewTabPayload, + OpenTerminalFloatingNearPluginPayload, + OpenTerminalFloatingNearPluginResponse as ProtobufOpenTerminalFloatingNearPluginResponse, + OpenTerminalFloatingResponse as ProtobufOpenTerminalFloatingResponse, + OpenTerminalInPlaceOfPluginPayload, + OpenTerminalInPlaceOfPluginResponse as ProtobufOpenTerminalInPlaceOfPluginResponse, + OpenTerminalInPlaceResponse as ProtobufOpenTerminalInPlaceResponse, + OpenTerminalNearPluginPayload, + OpenTerminalNearPluginResponse as ProtobufOpenTerminalNearPluginResponse, + OpenTerminalPaneInPlaceOfPaneIdPayload, + OpenTerminalPaneInPlaceOfPaneIdResponse as ProtobufOpenTerminalPaneInPlaceOfPaneIdResponse, + OpenTerminalResponse as ProtobufOpenTerminalResponse, OverrideLayoutPayload, + PageScrollDownInPaneIdPayload, PageScrollUpInPaneIdPayload, PaneId as ProtobufPaneId, + PaneIdAndFloatingPaneCoordinates, PaneType as ProtobufPaneType, ParseLayoutPayload, + ParseLayoutResponse as ProtobufParseLayoutResponse, PluginCommand as ProtobufPluginCommand, + PluginMessagePayload, RebindKeysPayload, ReconfigurePayload, + RegexHighlight as ProtobufRegexHighlight, ReloadPluginPayload, RenameLayoutPayload, + RenameLayoutResponse as ProtobufRenameLayoutResponse, RenameTabWithIdPayload, + RenameWebLoginTokenPayload, RenameWebTokenResponse, ReplacePaneWithExistingPanePayload, + RequestPluginPermissionPayload, RerunCommandPanePayload, ResizePaneIdWithDirectionPayload, + ResizePayload, RevokeAllWebTokensResponse, RevokeTokenResponse, RevokeWebLoginTokenPayload, + RunActionPayload, RunCommandPayload, RunningCommand as ProtobufRunningCommand, + SaveLayoutPayload, SaveLayoutResponse as ProtobufSaveLayoutResponse, SaveSessionPayload, + SaveSessionResponse as ProtobufSaveSessionResponse, ScrollDownInPaneIdPayload, + ScrollToBottomInPaneIdPayload, ScrollToTopInPaneIdPayload, ScrollUpInPaneIdPayload, + SessionListSnapshot as ProtobufSessionListSnapshot, SetFloatingPanePinnedPayload, + SetPaneBorderlessPayload, SetPaneColorPayload, + SetPaneFrameStylePayload as ProtobufSetPaneFrameStylePayload, + SetPaneRegexHighlightsPayload, SetSelfMouseSelectionSupportPayload, + SetSoftKeyboardPayload as ProtobufSetSoftKeyboardPayload, + SetTabFitPayload as ProtobufSetTabFitPayload, SetTimeoutPayload, ShowCursorPayload, + ShowFloatingPanesPayload as ProtobufShowFloatingPanesPayload, + ShowFloatingPanesResponse as ProtobufShowFloatingPanesResponse, ShowPaneWithIdPayload, + Size as ProtobufSize, StackPanesPayload, SubscribePayload, SwitchSessionPayload, + SwitchTabToIdPayload, SwitchTabToPayload, ToggleFloatingPanesPayload, + TogglePaneBorderlessPayload, TogglePaneEmbedOrEjectForPaneIdPayload, + TogglePaneIdFullscreenPayload, UnsubscribePayload, WebRequestPayload, + WriteCharsToPaneIdPayload, WriteToPaneIdPayload, + }, + plugin_permission::PermissionType as ProtobufPermissionType, + resize::ResizeAction as ProtobufResizeAction, +}; + +use crate::data::{ + ConnectToSession, DeleteAllDeadSessionsResponse, DeleteDeadSessionResponse, + DeleteLayoutResponse, EditLayoutResponse, FloatingPaneCoordinates, GetFocusedPaneInfoResponse, + GetPaneCwdResponse, GetPanePidResponse, GetPaneRunningCommandResponse, GetSessionListResponse, + HighlightLayer, HighlightStyle, HttpVerb, InputMode, KeyWithModifier, KillSessionsResponse, + MessageToPlugin, NewPluginArgs, PaneId, PermissionType, PluginCommand, RegexHighlight, + RenameLayoutResponse, SaveLayoutResponse, SessionInfo, SessionListSnapshot, +}; +use crate::input::actions::Action; +use crate::input::layout::PercentOrFixed; +use crate::pane_size::Size; + +use std::collections::BTreeMap; +use std::convert::TryFrom; +use std::path::PathBuf; + +fn size_from_protobuf(size: ProtobufSize) -> Size { + Size { + rows: size.rows as usize, + cols: size.cols as usize, + } +} + +fn size_to_protobuf(size: Size) -> ProtobufSize { + ProtobufSize { + rows: size.rows as u32, + cols: size.cols as u32, + } +} + +impl Into<FloatingPaneCoordinates> for ProtobufFloatingPaneCoordinates { + fn into(self) -> FloatingPaneCoordinates { + FloatingPaneCoordinates { + x: self + .x + .and_then(|x| match ProtobufFixedOrPercent::from_i32(x.r#type) { + Some(ProtobufFixedOrPercent::Percent) => { + Some(PercentOrFixed::Percent(x.value as usize)) + }, + Some(ProtobufFixedOrPercent::Fixed) => { + Some(PercentOrFixed::Fixed(x.value as usize)) + }, + None => None, + }), + y: self + .y + .and_then(|y| match ProtobufFixedOrPercent::from_i32(y.r#type) { + Some(ProtobufFixedOrPercent::Percent) => { + Some(PercentOrFixed::Percent(y.value as usize)) + }, + Some(ProtobufFixedOrPercent::Fixed) => { + Some(PercentOrFixed::Fixed(y.value as usize)) + }, + None => None, + }), + width: self.width.and_then(|width| { + match ProtobufFixedOrPercent::from_i32(width.r#type) { + Some(ProtobufFixedOrPercent::Percent) => { + Some(PercentOrFixed::Percent(width.value as usize)) + }, + Some(ProtobufFixedOrPercent::Fixed) => { + Some(PercentOrFixed::Fixed(width.value as usize)) + }, + None => None, + } + }), + height: self.height.and_then(|height| { + match ProtobufFixedOrPercent::from_i32(height.r#type) { + Some(ProtobufFixedOrPercent::Percent) => { + Some(PercentOrFixed::Percent(height.value as usize)) + }, + Some(ProtobufFixedOrPercent::Fixed) => { + Some(PercentOrFixed::Fixed(height.value as usize)) + }, + None => None, + } + }), + pinned: self.pinned, + borderless: self.borderless, + } + } +} + +impl Into<ProtobufFloatingPaneCoordinates> for FloatingPaneCoordinates { + fn into(self) -> ProtobufFloatingPaneCoordinates { + ProtobufFloatingPaneCoordinates { + x: match self.x { + Some(PercentOrFixed::Percent(percent)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Percent as i32, + value: percent as u32, + }), + Some(PercentOrFixed::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Fixed as i32, + value: fixed as u32, + }), + None => None, + }, + y: match self.y { + Some(PercentOrFixed::Percent(percent)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Percent as i32, + value: percent as u32, + }), + Some(PercentOrFixed::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Fixed as i32, + value: fixed as u32, + }), + None => None, + }, + width: match self.width { + Some(PercentOrFixed::Percent(percent)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Percent as i32, + value: percent as u32, + }), + Some(PercentOrFixed::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Fixed as i32, + value: fixed as u32, + }), + None => None, + }, + height: match self.height { + Some(PercentOrFixed::Percent(percent)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Percent as i32, + value: percent as u32, + }), + Some(PercentOrFixed::Fixed(fixed)) => Some(ProtobufFixedOrPercentValue { + r#type: ProtobufFixedOrPercent::Fixed as i32, + value: fixed as u32, + }), + None => None, + }, + pinned: self.pinned, + borderless: self.borderless, + } + } +} + +impl Into<HttpVerb> for ProtobufHttpVerb { + fn into(self) -> HttpVerb { + match self { + ProtobufHttpVerb::Get => HttpVerb::Get, + ProtobufHttpVerb::Post => HttpVerb::Post, + ProtobufHttpVerb::Put => HttpVerb::Put, + ProtobufHttpVerb::Delete => HttpVerb::Delete, + } + } +} + +impl Into<ProtobufHttpVerb> for HttpVerb { + fn into(self) -> ProtobufHttpVerb { + match self { + HttpVerb::Get => ProtobufHttpVerb::Get, + HttpVerb::Post => ProtobufHttpVerb::Post, + HttpVerb::Put => ProtobufHttpVerb::Put, + HttpVerb::Delete => ProtobufHttpVerb::Delete, + } + } +} + +impl TryFrom<ProtobufPaneId> for PaneId { + type Error = &'static str; + fn try_from(protobuf_pane_id: ProtobufPaneId) -> Result<Self, &'static str> { + match ProtobufPaneType::from_i32(protobuf_pane_id.pane_type) { + Some(ProtobufPaneType::Terminal) => Ok(PaneId::Terminal(protobuf_pane_id.id)), + Some(ProtobufPaneType::Plugin) => Ok(PaneId::Plugin(protobuf_pane_id.id)), + None => Err("Failed to convert PaneId"), + } + } +} + +impl TryFrom<PaneId> for ProtobufPaneId { + type Error = &'static str; + fn try_from(pane_id: PaneId) -> Result<Self, &'static str> { + match pane_id { + PaneId::Terminal(id) => Ok(ProtobufPaneId { + pane_type: ProtobufPaneType::Terminal as i32, + id, + }), + PaneId::Plugin(id) => Ok(ProtobufPaneId { + pane_type: ProtobufPaneType::Plugin as i32, + id, + }), + } + } +} + +impl TryFrom<ProtobufGetPanePidResponse> for GetPanePidResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufGetPanePidResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(get_pane_pid_response::Result::Pid(pid)) => Ok(GetPanePidResponse::Ok(pid)), + Some(get_pane_pid_response::Result::Error(error)) => Ok(GetPanePidResponse::Err(error)), + None => Err("Empty GetPanePidResponse"), + } + } +} + +impl From<GetPanePidResponse> for ProtobufGetPanePidResponse { + fn from(response: GetPanePidResponse) -> Self { + match response { + GetPanePidResponse::Ok(pid) => ProtobufGetPanePidResponse { + result: Some(get_pane_pid_response::Result::Pid(pid)), + }, + GetPanePidResponse::Err(error) => ProtobufGetPanePidResponse { + result: Some(get_pane_pid_response::Result::Error(error)), + }, + } + } +} + +impl From<GetPaneRunningCommandResponse> for ProtobufGetPaneRunningCommandResponse { + fn from(response: GetPaneRunningCommandResponse) -> Self { + match response { + GetPaneRunningCommandResponse::Ok(args) => ProtobufGetPaneRunningCommandResponse { + result: Some(get_pane_running_command_response::Result::Command( + ProtobufRunningCommand { args }, + )), + }, + GetPaneRunningCommandResponse::Err(err) => ProtobufGetPaneRunningCommandResponse { + result: Some(get_pane_running_command_response::Result::Error(err)), + }, + } + } +} + +impl From<GetSessionListResponse> for ProtobufGetSessionListResponse { + fn from(response: GetSessionListResponse) -> Self { + match response { + GetSessionListResponse::Ok(snapshot) => { + let live_sessions = snapshot + .live_sessions + .into_iter() + .filter_map(|si| ProtobufSessionManifest::try_from(si).ok()) + .collect(); + let resurrectable_sessions = snapshot + .resurrectable_sessions + .into_iter() + .map(|entry| ProtobufResurrectableSession::from(entry)) + .collect(); + ProtobufGetSessionListResponse { + result: Some(get_session_list_response::Result::Snapshot( + ProtobufSessionListSnapshot { + live_sessions, + resurrectable_sessions, + }, + )), + } + }, + GetSessionListResponse::Err(err) => ProtobufGetSessionListResponse { + result: Some(get_session_list_response::Result::Error(err)), + }, + } + } +} + +impl TryFrom<ProtobufGetSessionListResponse> for GetSessionListResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufGetSessionListResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(get_session_list_response::Result::Snapshot(snapshot)) => { + let mut live_sessions: Vec<SessionInfo> = Vec::new(); + for manifest in snapshot.live_sessions { + live_sessions.push(SessionInfo::try_from(manifest)?); + } + let resurrectable_sessions = snapshot + .resurrectable_sessions + .into_iter() + .map(<(String, std::time::Duration)>::from) + .collect(); + Ok(GetSessionListResponse::Ok(SessionListSnapshot { + live_sessions, + resurrectable_sessions, + })) + }, + Some(get_session_list_response::Result::Error(err)) => { + Ok(GetSessionListResponse::Err(err)) + }, + None => Err("Empty GetSessionListResponse"), + } + } +} + +impl From<KillSessionsResponse> for ProtobufKillSessionsResponse { + fn from(response: KillSessionsResponse) -> Self { + match response { + KillSessionsResponse::Ok => ProtobufKillSessionsResponse { error: None }, + KillSessionsResponse::Err(err) => ProtobufKillSessionsResponse { error: Some(err) }, + } + } +} + +impl From<ProtobufKillSessionsResponse> for KillSessionsResponse { + fn from(protobuf_response: ProtobufKillSessionsResponse) -> Self { + match protobuf_response.error { + Some(err) => KillSessionsResponse::Err(err), + None => KillSessionsResponse::Ok, + } + } +} + +impl From<DeleteDeadSessionResponse> for ProtobufDeleteDeadSessionResponse { + fn from(response: DeleteDeadSessionResponse) -> Self { + match response { + DeleteDeadSessionResponse::Ok => ProtobufDeleteDeadSessionResponse { error: None }, + DeleteDeadSessionResponse::Err(err) => { + ProtobufDeleteDeadSessionResponse { error: Some(err) } + }, + } + } +} + +impl From<ProtobufDeleteDeadSessionResponse> for DeleteDeadSessionResponse { + fn from(protobuf_response: ProtobufDeleteDeadSessionResponse) -> Self { + match protobuf_response.error { + Some(err) => DeleteDeadSessionResponse::Err(err), + None => DeleteDeadSessionResponse::Ok, + } + } +} + +impl From<DeleteAllDeadSessionsResponse> for ProtobufDeleteAllDeadSessionsResponse { + fn from(response: DeleteAllDeadSessionsResponse) -> Self { + match response { + DeleteAllDeadSessionsResponse::Ok => { + ProtobufDeleteAllDeadSessionsResponse { error: None } + }, + DeleteAllDeadSessionsResponse::Err(err) => { + ProtobufDeleteAllDeadSessionsResponse { error: Some(err) } + }, + } + } +} + +impl From<ProtobufDeleteAllDeadSessionsResponse> for DeleteAllDeadSessionsResponse { + fn from(protobuf_response: ProtobufDeleteAllDeadSessionsResponse) -> Self { + match protobuf_response.error { + Some(err) => DeleteAllDeadSessionsResponse::Err(err), + None => DeleteAllDeadSessionsResponse::Ok, + } + } +} + +impl From<GetPaneCwdResponse> for ProtobufGetPaneCwdResponse { + fn from(response: GetPaneCwdResponse) -> Self { + match response { + GetPaneCwdResponse::Ok(path) => { + let cwd_string = path + .to_str() + .map(|s| s.to_string()) + .unwrap_or_else(|| String::from("")); + ProtobufGetPaneCwdResponse { + result: Some(get_pane_cwd_response::Result::Cwd(cwd_string)), + } + }, + GetPaneCwdResponse::Err(err) => ProtobufGetPaneCwdResponse { + result: Some(get_pane_cwd_response::Result::Error(err)), + }, + } + } +} + +impl From<GetFocusedPaneInfoResponse> for ProtobufGetFocusedPaneInfoResponse { + fn from(response: GetFocusedPaneInfoResponse) -> Self { + match response { + GetFocusedPaneInfoResponse::Ok { tab_index, pane_id } => { + let protobuf_pane_id = ProtobufPaneId { + pane_type: match pane_id { + PaneId::Terminal(_) => ProtobufPaneType::Terminal as i32, + PaneId::Plugin(_) => ProtobufPaneType::Plugin as i32, + }, + id: match pane_id { + PaneId::Terminal(id) | PaneId::Plugin(id) => id, + }, + }; + ProtobufGetFocusedPaneInfoResponse { + result: Some(get_focused_pane_info_response::Result::FocusedPaneInfo( + FocusedPaneInfo { + focused_tab_index: tab_index as u32, + focused_pane_id: Some(protobuf_pane_id), + }, + )), + } + }, + GetFocusedPaneInfoResponse::Err(err) => ProtobufGetFocusedPaneInfoResponse { + result: Some(get_focused_pane_info_response::Result::Error(err)), + }, + } + } +} + +impl TryFrom<ProtobufSaveLayoutResponse> for SaveLayoutResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufSaveLayoutResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(save_layout_response::Result::Success(_)) => Ok(SaveLayoutResponse::Ok(())), + Some(save_layout_response::Result::Error(error)) => Ok(SaveLayoutResponse::Err(error)), + None => Err("Empty SaveLayoutResponse"), + } + } +} + +impl From<SaveLayoutResponse> for ProtobufSaveLayoutResponse { + fn from(response: SaveLayoutResponse) -> Self { + match response { + SaveLayoutResponse::Ok(_) => ProtobufSaveLayoutResponse { + result: Some(save_layout_response::Result::Success(true)), + }, + SaveLayoutResponse::Err(error) => ProtobufSaveLayoutResponse { + result: Some(save_layout_response::Result::Error(error)), + }, + } + } +} + +impl TryFrom<ProtobufDeleteLayoutResponse> for DeleteLayoutResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufDeleteLayoutResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(delete_layout_response::Result::Success(_)) => Ok(DeleteLayoutResponse::Ok(())), + Some(delete_layout_response::Result::Error(error)) => { + Ok(DeleteLayoutResponse::Err(error)) + }, + None => Err("Empty DeleteLayoutResponse"), + } + } +} + +impl From<DeleteLayoutResponse> for ProtobufDeleteLayoutResponse { + fn from(response: DeleteLayoutResponse) -> Self { + match response { + DeleteLayoutResponse::Ok(_) => ProtobufDeleteLayoutResponse { + result: Some(delete_layout_response::Result::Success(true)), + }, + DeleteLayoutResponse::Err(error) => ProtobufDeleteLayoutResponse { + result: Some(delete_layout_response::Result::Error(error)), + }, + } + } +} + +impl TryFrom<ProtobufRenameLayoutResponse> for RenameLayoutResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufRenameLayoutResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(rename_layout_response::Result::Success(_)) => Ok(RenameLayoutResponse::Ok(())), + Some(rename_layout_response::Result::Error(error)) => { + Ok(RenameLayoutResponse::Err(error)) + }, + None => Err("Empty RenameLayoutResponse"), + } + } +} + +impl From<RenameLayoutResponse> for ProtobufRenameLayoutResponse { + fn from(response: RenameLayoutResponse) -> Self { + match response { + RenameLayoutResponse::Ok(_) => ProtobufRenameLayoutResponse { + result: Some(rename_layout_response::Result::Success(true)), + }, + RenameLayoutResponse::Err(error) => ProtobufRenameLayoutResponse { + result: Some(rename_layout_response::Result::Error(error)), + }, + } + } +} + +impl TryFrom<ProtobufEditLayoutResponse> for EditLayoutResponse { + type Error = &'static str; + fn try_from(protobuf_response: ProtobufEditLayoutResponse) -> Result<Self, &'static str> { + match protobuf_response.result { + Some(edit_layout_response::Result::Success(_)) => Ok(EditLayoutResponse::Ok(())), + Some(edit_layout_response::Result::Error(error)) => Ok(EditLayoutResponse::Err(error)), + None => Err("Empty EditLayoutResponse"), + } + } +} + +impl From<EditLayoutResponse> for ProtobufEditLayoutResponse { + fn from(response: EditLayoutResponse) -> Self { + match response { + EditLayoutResponse::Ok(_) => ProtobufEditLayoutResponse { + result: Some(edit_layout_response::Result::Success(true)), + }, + EditLayoutResponse::Err(error) => ProtobufEditLayoutResponse { + result: Some(edit_layout_response::Result::Error(error)), + }, + } + } +} + +impl TryFrom<(InputMode, KeyWithModifier, Vec<Action>)> for KeyToRebind { + type Error = &'static str; + fn try_from( + key_to_rebind: (InputMode, KeyWithModifier, Vec<Action>), + ) -> Result<Self, &'static str> { + Ok(KeyToRebind { + input_mode: key_to_rebind.0 as i32, + key: Some(key_to_rebind.1.try_into()?), + actions: key_to_rebind + .2 + .into_iter() + .filter_map(|a| a.try_into().ok()) + .collect(), + }) + } +} + +impl TryFrom<(InputMode, KeyWithModifier)> for KeyToUnbind { + type Error = &'static str; + fn try_from(key_to_unbind: (InputMode, KeyWithModifier)) -> Result<Self, &'static str> { + Ok(KeyToUnbind { + input_mode: key_to_unbind.0 as i32, + key: Some(key_to_unbind.1.try_into()?), + }) + } +} + +fn key_to_rebind_to_plugin_command_assets( + key_to_rebind: KeyToRebind, +) -> Option<(InputMode, KeyWithModifier, Vec<Action>)> { + Some(( + ProtobufInputMode::from_i32(key_to_rebind.input_mode)? + .try_into() + .ok()?, + key_to_rebind.key?.try_into().ok()?, + key_to_rebind + .actions + .into_iter() + .filter_map(|a| a.try_into().ok()) + .collect(), + )) +} + +fn key_to_unbind_to_plugin_command_assets( + key_to_unbind: KeyToUnbind, +) -> Option<(InputMode, KeyWithModifier)> { + Some(( + ProtobufInputMode::from_i32(key_to_unbind.input_mode)? + .try_into() + .ok()?, + key_to_unbind.key?.try_into().ok()?, + )) +} + +impl TryFrom<ProtobufPluginCommand> for PluginCommand { + type Error = &'static str; + fn try_from(protobuf_plugin_command: ProtobufPluginCommand) -> Result<Self, &'static str> { + match CommandName::from_i32(protobuf_plugin_command.name) { + Some(CommandName::Subscribe) => match protobuf_plugin_command.payload { + Some(Payload::SubscribePayload(subscribe_payload)) => { + let protobuf_event_list = subscribe_payload.subscriptions; + match protobuf_event_list { + Some(protobuf_event_list) => { + Ok(PluginCommand::Subscribe(protobuf_event_list.try_into()?)) + }, + None => Err("malformed subscription event"), + } + }, + _ => Err("Mismatched payload for Subscribe"), + }, + Some(CommandName::Unsubscribe) => match protobuf_plugin_command.payload { + Some(Payload::UnsubscribePayload(unsubscribe_payload)) => { + let protobuf_event_list = unsubscribe_payload.subscriptions; + match protobuf_event_list { + Some(protobuf_event_list) => { + Ok(PluginCommand::Unsubscribe(protobuf_event_list.try_into()?)) + }, + None => Err("malformed unsubscription event"), + } + }, + _ => Err("Mismatched payload for Unsubscribe"), + }, + Some(CommandName::SetSelectable) => match protobuf_plugin_command.payload { + Some(Payload::SetSelectablePayload(should_be_selectable)) => { + Ok(PluginCommand::SetSelectable(should_be_selectable)) + }, + _ => Err("Mismatched payload for SetSelectable"), + }, + Some(CommandName::ShowCursor) => match protobuf_plugin_command.payload { + Some(Payload::ShowCursorPayload(payload)) => { + let cursor_position = + payload.position.map(|pos| (pos.x as usize, pos.y as usize)); + Ok(PluginCommand::ShowCursor(cursor_position)) + }, + _ => Err("Mismatched payload for ShowCursor"), + }, + Some(CommandName::GetPluginIds) => { + if protobuf_plugin_command.payload.is_some() { + Err("GetPluginIds should not have a payload") + } else { + Ok(PluginCommand::GetPluginIds) + } + }, + Some(CommandName::GetZellijVersion) => { + if protobuf_plugin_command.payload.is_some() { + Err("GetZellijVersion should not have a payload") + } else { + Ok(PluginCommand::GetZellijVersion) + } + }, + Some(CommandName::OpenFile) => match protobuf_plugin_command.payload { + Some(Payload::OpenFilePayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenFile(file_to_open.try_into()?, context)) + }, + None => Err("Malformed open file payload"), + } + }, + _ => Err("Mismatched payload for OpenFile"), + }, + Some(CommandName::OpenFileFloating) => match protobuf_plugin_command.payload { + Some(Payload::OpenFileFloatingPayload(file_to_open_payload)) => { + let floating_pane_coordinates = file_to_open_payload + .floating_pane_coordinates + .map(|f| f.into()); + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + match file_to_open_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenFileFloating( + file_to_open.try_into()?, + floating_pane_coordinates, + context, + )), + None => Err("Malformed open file payload"), + } + }, + _ => Err("Mismatched payload for OpenFileFloating"), + }, + Some(CommandName::OpenTerminal) => match protobuf_plugin_command.payload { + Some(Payload::OpenTerminalPayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + Ok(PluginCommand::OpenTerminal(file_to_open.try_into()?)) + }, + None => Err("Malformed open terminal payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminal"), + }, + Some(CommandName::OpenTerminalFloating) => match protobuf_plugin_command.payload { + Some(Payload::OpenTerminalFloatingPayload(file_to_open_payload)) => { + let floating_pane_coordinates = file_to_open_payload + .floating_pane_coordinates + .map(|f| f.into()); + match file_to_open_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenTerminalFloating( + file_to_open.try_into()?, + floating_pane_coordinates, + )), + None => Err("Malformed open terminal floating payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminalFloating"), + }, + Some(CommandName::OpenCommandPane) => match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPanePayload(command_to_run_payload)) => { + match command_to_run_payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = 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"), + } + }, + _ => Err("Mismatched payload for OpenCommandPane"), + }, + Some(CommandName::OpenCommandPaneFloating) => match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneFloatingPayload(command_to_run_payload)) => { + let floating_pane_coordinates = command_to_run_payload + .floating_pane_coordinates + .map(|f| f.into()); + match command_to_run_payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = 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"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneFloating"), + }, + Some(CommandName::SwitchTabTo) => match protobuf_plugin_command.payload { + Some(Payload::SwitchTabToPayload(switch_to_tab_payload)) => Ok( + PluginCommand::SwitchTabTo(switch_to_tab_payload.tab_index as u32), + ), + _ => Err("Mismatched payload for SwitchToTab"), + }, + Some(CommandName::SetTimeout) => match protobuf_plugin_command.payload { + Some(Payload::SetTimeoutPayload(set_timeout_payload)) => { + Ok(PluginCommand::SetTimeout(set_timeout_payload.seconds)) + }, + _ => Err("Mismatched payload for SetTimeout"), + }, + Some(CommandName::ExecCmd) => match protobuf_plugin_command.payload { + Some(Payload::ExecCmdPayload(exec_cmd_payload)) => { + Ok(PluginCommand::ExecCmd(exec_cmd_payload.command_line)) + }, + _ => Err("Mismatched payload for ExecCmd"), + }, + Some(CommandName::PostMessageTo) => match protobuf_plugin_command.payload { + Some(Payload::PostMessageToPayload(post_message_to_payload)) => { + match post_message_to_payload.message { + Some(message) => Ok(PluginCommand::PostMessageTo(message.try_into()?)), + None => Err("Malformed post message to payload"), + } + }, + _ => Err("Mismatched payload for PostMessageTo"), + }, + Some(CommandName::PostMessageToPlugin) => match protobuf_plugin_command.payload { + Some(Payload::PostMessageToPluginPayload(post_message_to_payload)) => { + match post_message_to_payload.message { + Some(message) => { + Ok(PluginCommand::PostMessageToPlugin(message.try_into()?)) + }, + None => Err("Malformed post message to plugin payload"), + } + }, + _ => Err("Mismatched payload for PostMessageToPlugin"), + }, + Some(CommandName::HideSelf) => { + if protobuf_plugin_command.payload.is_some() { + return Err("HideSelf should not have a payload"); + } + Ok(PluginCommand::HideSelf) + }, + Some(CommandName::ShowSelf) => match protobuf_plugin_command.payload { + Some(Payload::ShowSelfPayload(should_float_if_hidden)) => { + Ok(PluginCommand::ShowSelf(should_float_if_hidden)) + }, + _ => Err("Mismatched payload for ShowSelf"), + }, + Some(CommandName::SwitchToMode) => match protobuf_plugin_command.payload { + Some(Payload::SwitchToModePayload(switch_to_mode_payload)) => { + match ProtobufInputMode::from_i32(switch_to_mode_payload.input_mode) { + Some(protobuf_input_mode) => { + Ok(PluginCommand::SwitchToMode(protobuf_input_mode.try_into()?)) + }, + None => Err("Malformed switch to mode payload"), + } + }, + _ => Err("Mismatched payload for SwitchToMode"), + }, + Some(CommandName::NewTabsWithLayout) => match protobuf_plugin_command.payload { + Some(Payload::NewTabsWithLayoutPayload(raw_layout)) => { + Ok(PluginCommand::NewTabsWithLayout(raw_layout)) + }, + _ => Err("Mismatched payload for NewTabsWithLayout"), + }, + Some(CommandName::NewTab) => match protobuf_plugin_command.payload { + Some(Payload::NewTabPayload(protobuf_new_tab_payload)) => { + Ok(PluginCommand::NewTab { + name: protobuf_new_tab_payload.name, + cwd: protobuf_new_tab_payload.cwd, + }) + }, + None => Ok(PluginCommand::NewTab { + name: None, + cwd: None, + }), + _ => Err("Mismatched payload for NewTab"), + }, + Some(CommandName::NewTabUnfocused) => match protobuf_plugin_command.payload { + Some(Payload::NewTabUnfocusedPayload(payload)) => { + Ok(PluginCommand::NewTabUnfocused { + name: payload.name, + cwd: payload.cwd, + }) + }, + None => Ok(PluginCommand::NewTabUnfocused { + name: None, + cwd: None, + }), + _ => Err("Mismatched payload for NewTabUnfocused"), + }, + Some(CommandName::NewTiledPaneInTab) => match protobuf_plugin_command.payload { + Some(Payload::NewTiledPaneInTabPayload(payload)) => { + Ok(PluginCommand::NewTiledPaneInTab { + tab_position: payload.tab_position as usize, + }) + }, + _ => Err("Mismatched payload for NewTiledPaneInTab"), + }, + Some(CommandName::ToggleFloatingPanes) => match protobuf_plugin_command.payload { + Some(Payload::ToggleFloatingPanesPayload(payload)) => { + Ok(PluginCommand::ToggleFloatingPanes { + tab_id: payload.tab_id, + }) + }, + _ => Ok(PluginCommand::ToggleFloatingPanes { tab_id: None }), + }, + Some(CommandName::NewPane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("NewPane should not have a payload"); + } + Ok(PluginCommand::NewPane) + }, + Some(CommandName::GoToNextTab) => { + if protobuf_plugin_command.payload.is_some() { + return Err("GoToNextTab should not have a payload"); + } + Ok(PluginCommand::GoToNextTab) + }, + Some(CommandName::GoToPreviousTab) => { + if protobuf_plugin_command.payload.is_some() { + return Err("GoToPreviousTab should not have a payload"); + } + Ok(PluginCommand::GoToPreviousTab) + }, + Some(CommandName::Resize) => match protobuf_plugin_command.payload { + Some(Payload::ResizePayload(resize_payload)) => match resize_payload.resize { + Some(resize) => Ok(PluginCommand::Resize(resize.try_into()?)), + None => Err("Malformed switch resize payload"), + }, + _ => Err("Mismatched payload for Resize"), + }, + Some(CommandName::ResizeWithDirection) => match protobuf_plugin_command.payload { + Some(Payload::ResizeWithDirectionPayload(resize_with_direction_payload)) => { + match resize_with_direction_payload.resize { + Some(resize) => Ok(PluginCommand::ResizeWithDirection(resize.try_into()?)), + None => Err("Malformed switch resize payload"), + } + }, + _ => Err("Mismatched payload for Resize"), + }, + Some(CommandName::FocusNextPane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("FocusNextPane should not have a payload"); + } + Ok(PluginCommand::FocusNextPane) + }, + Some(CommandName::FocusPreviousPane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("FocusPreviousPane should not have a payload"); + } + Ok(PluginCommand::FocusPreviousPane) + }, + Some(CommandName::FocusLastPane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("FocusLastPane should not have a payload"); + } + Ok(PluginCommand::FocusLastPane) + }, + Some(CommandName::MoveFocus) => match protobuf_plugin_command.payload { + Some(Payload::MoveFocusPayload(move_payload)) => match move_payload.direction { + Some(direction) => Ok(PluginCommand::MoveFocus(direction.try_into()?)), + None => Err("Malformed move focus payload"), + }, + _ => Err("Mismatched payload for MoveFocus"), + }, + Some(CommandName::MoveFocusOrTab) => match protobuf_plugin_command.payload { + Some(Payload::MoveFocusOrTabPayload(move_payload)) => { + match move_payload.direction { + Some(direction) => Ok(PluginCommand::MoveFocusOrTab(direction.try_into()?)), + None => Err("Malformed move focus or tab payload"), + } + }, + _ => Err("Mismatched payload for MoveFocusOrTab"), + }, + Some(CommandName::Detach) => { + if protobuf_plugin_command.payload.is_some() { + return Err("Detach should not have a payload"); + } + Ok(PluginCommand::Detach) + }, + Some(CommandName::EditScrollback) => { + if protobuf_plugin_command.payload.is_some() { + return Err("EditScrollback should not have a payload"); + } + Ok(PluginCommand::EditScrollback) + }, + Some(CommandName::Write) => match protobuf_plugin_command.payload { + Some(Payload::WritePayload(bytes)) => Ok(PluginCommand::Write(bytes)), + _ => Err("Mismatched payload for Write"), + }, + Some(CommandName::WriteChars) => match protobuf_plugin_command.payload { + Some(Payload::WriteCharsPayload(chars)) => Ok(PluginCommand::WriteChars(chars)), + _ => Err("Mismatched payload for WriteChars"), + }, + Some(CommandName::ToggleTab) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ToggleTab should not have a payload"); + } + Ok(PluginCommand::ToggleTab) + }, + Some(CommandName::MovePane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("MovePane should not have a payload"); + } + Ok(PluginCommand::MovePane) + }, + Some(CommandName::MovePaneWithDirection) => match protobuf_plugin_command.payload { + Some(Payload::MovePaneWithDirectionPayload(move_payload)) => { + match move_payload.direction { + Some(direction) => { + Ok(PluginCommand::MovePaneWithDirection(direction.try_into()?)) + }, + None => Err("Malformed MovePaneWithDirection payload"), + } + }, + _ => Err("Mismatched payload for MovePaneWithDirection"), + }, + Some(CommandName::ClearScreen) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ClearScreen should not have a payload"); + } + Ok(PluginCommand::ClearScreen) + }, + Some(CommandName::ScrollUp) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ScrollUp should not have a payload"); + } + Ok(PluginCommand::ScrollUp) + }, + Some(CommandName::ScrollDown) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ScrollDown should not have a payload"); + } + Ok(PluginCommand::ScrollDown) + }, + Some(CommandName::ScrollToTop) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ScrollToTop should not have a payload"); + } + Ok(PluginCommand::ScrollToTop) + }, + Some(CommandName::ScrollToBottom) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ScrollToBottom should not have a payload"); + } + Ok(PluginCommand::ScrollToBottom) + }, + Some(CommandName::PageScrollUp) => { + if protobuf_plugin_command.payload.is_some() { + return Err("PageScrollUp should not have a payload"); + } + Ok(PluginCommand::PageScrollUp) + }, + Some(CommandName::PageScrollDown) => { + if protobuf_plugin_command.payload.is_some() { + return Err("PageScrollDown should not have a payload"); + } + Ok(PluginCommand::PageScrollDown) + }, + Some(CommandName::ToggleFocusFullscreen) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ToggleFocusFullscreen should not have a payload"); + } + Ok(PluginCommand::ToggleFocusFullscreen) + }, + Some(CommandName::ToggleFocusNoUiFullscreen) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ToggleFocusNoUiFullscreen should not have a payload"); + } + Ok(PluginCommand::ToggleFocusNoUiFullscreen) + }, + Some(CommandName::FocusHostSession) => { + if protobuf_plugin_command.payload.is_some() { + return Err("FocusHostSession should not have a payload"); + } + Ok(PluginCommand::FocusHostSession) + }, + Some(CommandName::TogglePaneFrames) => { + if protobuf_plugin_command.payload.is_some() { + return Err("TogglePaneFrames should not have a payload"); + } + Ok(PluginCommand::TogglePaneFrames) + }, + Some(CommandName::SetPaneFrameStyle) => match protobuf_plugin_command.payload { + Some(Payload::SetPaneFrameStylePayload(payload)) => { + match ProtobufPaneFrameStyle::from_i32(payload.pane_frame_style) { + Some(protobuf_pane_frame_style) => Ok(PluginCommand::SetPaneFrameStyle( + protobuf_pane_frame_style.try_into()?, + )), + None => Err("Malformed SetPaneFrameStyle payload"), + } + }, + _ => Err("Mismatched payload for SetPaneFrameStyle"), + }, + Some(CommandName::TogglePaneEmbedOrEject) => { + if protobuf_plugin_command.payload.is_some() { + return Err("TogglePaneEmbedOrEject should not have a payload"); + } + Ok(PluginCommand::TogglePaneEmbedOrEject) + }, + Some(CommandName::UndoRenamePane) => { + if protobuf_plugin_command.payload.is_some() { + return Err("UndoRenamePane should not have a payload"); + } + Ok(PluginCommand::UndoRenamePane) + }, + Some(CommandName::CloseFocus) => { + if protobuf_plugin_command.payload.is_some() { + return Err("CloseFocus should not have a payload"); + } + Ok(PluginCommand::CloseFocus) + }, + Some(CommandName::ToggleActiveTabSync) => { + if protobuf_plugin_command.payload.is_some() { + return Err("ToggleActiveTabSync should not have a payload"); + } + Ok(PluginCommand::ToggleActiveTabSync) + }, + Some(CommandName::CloseFocusedTab) => { + if protobuf_plugin_command.payload.is_some() { + return Err("CloseFocusedTab should not have a payload"); + } + Ok(PluginCommand::CloseFocusedTab) + }, + Some(CommandName::UndoRenameTab) => { + if protobuf_plugin_command.payload.is_some() { + return Err("UndoRenameTab should not have a payload"); + } + Ok(PluginCommand::UndoRenameTab) + }, + Some(CommandName::QuitZellij) => { + if protobuf_plugin_command.payload.is_some() { + return Err("QuitZellij should not have a payload"); + } + Ok(PluginCommand::QuitZellij) + }, + Some(CommandName::PreviousSwapLayout) => { + if protobuf_plugin_command.payload.is_some() { + return Err("PreviousSwapLayout should not have a payload"); + } + Ok(PluginCommand::PreviousSwapLayout) + }, + Some(CommandName::NextSwapLayout) => { + if protobuf_plugin_command.payload.is_some() { + return Err("NextSwapLayout should not have a payload"); + } + Ok(PluginCommand::NextSwapLayout) + }, + Some(CommandName::GoToTabName) => match protobuf_plugin_command.payload { + Some(Payload::GoToTabNamePayload(tab_name)) => { + Ok(PluginCommand::GoToTabName(tab_name)) + }, + _ => Err("Mismatched payload for GoToTabName"), + }, + Some(CommandName::FocusOrCreateTab) => match protobuf_plugin_command.payload { + Some(Payload::FocusOrCreateTabPayload(tab_name)) => { + Ok(PluginCommand::FocusOrCreateTab(tab_name)) + }, + _ => Err("Mismatched payload for FocusOrCreateTab"), + }, + Some(CommandName::GoToTab) => match protobuf_plugin_command.payload { + Some(Payload::GoToTabPayload(tab_index)) => { + Ok(PluginCommand::GoToTab(tab_index as u32)) + }, + _ => Err("Mismatched payload for GoToTab"), + }, + Some(CommandName::StartOrReloadPlugin) => match protobuf_plugin_command.payload { + Some(Payload::StartOrReloadPluginPayload(url)) => { + Ok(PluginCommand::StartOrReloadPlugin(url)) + }, + _ => Err("Mismatched payload for StartOrReloadPlugin"), + }, + Some(CommandName::CloseTerminalPane) => match protobuf_plugin_command.payload { + Some(Payload::CloseTerminalPanePayload(pane_id)) => { + Ok(PluginCommand::CloseTerminalPane(pane_id as u32)) + }, + _ => Err("Mismatched payload for CloseTerminalPane"), + }, + Some(CommandName::ClosePluginPane) => match protobuf_plugin_command.payload { + Some(Payload::ClosePluginPanePayload(pane_id)) => { + Ok(PluginCommand::ClosePluginPane(pane_id as u32)) + }, + _ => Err("Mismatched payload for ClosePluginPane"), + }, + Some(CommandName::FocusTerminalPane) => match protobuf_plugin_command.payload { + Some(Payload::FocusTerminalPanePayload(payload)) => { + let pane_id = payload.pane_id as u32; + let should_float = payload.should_float; + let should_be_in_place = payload.should_be_in_place; + Ok(PluginCommand::FocusTerminalPane( + pane_id, + should_float, + should_be_in_place, + )) + }, + _ => Err("Mismatched payload for ClosePluginPane"), + }, + Some(CommandName::FocusPluginPane) => match protobuf_plugin_command.payload { + Some(Payload::FocusPluginPanePayload(payload)) => { + let pane_id = payload.pane_id as u32; + let should_float = payload.should_float; + let should_be_in_place = payload.should_be_in_place; + Ok(PluginCommand::FocusPluginPane( + pane_id, + should_float, + should_be_in_place, + )) + }, + _ => Err("Mismatched payload for ClosePluginPane"), + }, + Some(CommandName::RenameTerminalPane) => match protobuf_plugin_command.payload { + Some(Payload::RenameTerminalPanePayload(payload)) => { + let pane_id = payload.id as u32; + let new_name = payload.new_name; + Ok(PluginCommand::RenameTerminalPane(pane_id, new_name)) + }, + _ => Err("Mismatched payload for RenameTerminalPane"), + }, + Some(CommandName::RenamePluginPane) => match protobuf_plugin_command.payload { + Some(Payload::RenamePluginPanePayload(payload)) => { + let pane_id = payload.id as u32; + let new_name = payload.new_name; + Ok(PluginCommand::RenamePluginPane(pane_id, new_name)) + }, + _ => Err("Mismatched payload for RenamePluginPane"), + }, + Some(CommandName::RenameTab) => match protobuf_plugin_command.payload { + Some(Payload::RenameTabPayload(payload)) => { + let tab_index = payload.id as u32; + let name = payload.new_name; + Ok(PluginCommand::RenameTab(tab_index, name)) + }, + _ => Err("Mismatched payload for RenameTab"), + }, + Some(CommandName::ReportCrash) => match protobuf_plugin_command.payload { + Some(Payload::ReportCrashPayload(payload)) => { + Ok(PluginCommand::ReportPanic(payload)) + }, + _ => Err("Mismatched payload for ReportCrash"), + }, + Some(CommandName::RequestPluginPermissions) => match protobuf_plugin_command.payload { + Some(Payload::RequestPluginPermissionPayload(payload)) => { + Ok(PluginCommand::RequestPluginPermissions( + payload + .permissions + .iter() + .filter_map(|p| ProtobufPermissionType::from_i32(*p)) + .filter_map(|p| PermissionType::try_from(p).ok()) + .collect(), + )) + }, + _ => Err("Mismatched payload for RequestPluginPermission"), + }, + Some(CommandName::SwitchSession) => match protobuf_plugin_command.payload { + Some(Payload::SwitchSessionPayload(payload)) => { + let pane_id = match (payload.pane_id, payload.pane_id_is_plugin) { + (Some(pane_id), Some(is_plugin)) => Some((pane_id, is_plugin)), + (None, None) => None, + _ => { + return Err("Malformed payload for SwitchSession, 'pane_id' and 'is_plugin' must be included together or not at all") + } + }; + Ok(PluginCommand::SwitchSession(ConnectToSession { + name: payload.name, + tab_position: payload.tab_position.map(|p| p as usize), + pane_id, + layout: payload.layout.and_then(|l| l.try_into().ok()), + cwd: payload.cwd.map(|c| PathBuf::from(c)), + })) + }, + _ => Err("Mismatched payload for SwitchSession"), + }, + Some(CommandName::OpenTerminalInPlace) => match protobuf_plugin_command.payload { + Some(Payload::OpenTerminalInPlacePayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + Ok(PluginCommand::OpenTerminalInPlace(file_to_open.try_into()?)) + }, + None => Err("Malformed open terminal in-place payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminalInPlace"), + }, + Some(CommandName::OpenFileInPlace) => match protobuf_plugin_command.payload { + Some(Payload::OpenFileInPlacePayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenFileInPlace( + file_to_open.try_into()?, + context, + )) + }, + None => Err("Malformed open file in place payload"), + } + }, + _ => Err("Mismatched payload for OpenFileInPlace"), + }, + 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) => { + let context: BTreeMap<String, String> = 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"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneInPlace"), + }, + Some(CommandName::RunCommand) => match protobuf_plugin_command.payload { + Some(Payload::RunCommandPayload(run_command_payload)) => { + let env_variables: BTreeMap<String, String> = run_command_payload + .env_variables + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + let context: BTreeMap<String, String> = run_command_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::RunCommand( + run_command_payload.command_line, + env_variables, + PathBuf::from(run_command_payload.cwd), + context, + )) + }, + _ => Err("Mismatched payload for RunCommand"), + }, + Some(CommandName::WebRequest) => match protobuf_plugin_command.payload { + Some(Payload::WebRequestPayload(web_request_payload)) => { + let context: BTreeMap<String, String> = web_request_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + let headers: BTreeMap<String, String> = web_request_payload + .headers + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + let verb = match ProtobufHttpVerb::from_i32(web_request_payload.verb) { + Some(verb) => verb.into(), + None => { + return Err("Unrecognized http verb"); + }, + }; + Ok(PluginCommand::WebRequest( + web_request_payload.url, + verb, + headers, + web_request_payload.body, + context, + )) + }, + _ => Err("Mismatched payload for WebRequest"), + }, + Some(CommandName::DeleteDeadSession) => match protobuf_plugin_command.payload { + Some(Payload::DeleteDeadSessionPayload(dead_session_name)) => { + Ok(PluginCommand::DeleteDeadSession(dead_session_name)) + }, + _ => Err("Mismatched payload for DeleteDeadSession"), + }, + Some(CommandName::DeleteAllDeadSessions) => Ok(PluginCommand::DeleteAllDeadSessions), + Some(CommandName::RenameSession) => match protobuf_plugin_command.payload { + Some(Payload::RenameSessionPayload(new_session_name)) => { + Ok(PluginCommand::RenameSession(new_session_name)) + }, + _ => Err("Mismatched payload for RenameSession"), + }, + Some(CommandName::UnblockCliPipeInput) => match protobuf_plugin_command.payload { + Some(Payload::UnblockCliPipeInputPayload(pipe_name)) => { + Ok(PluginCommand::UnblockCliPipeInput(pipe_name)) + }, + _ => Err("Mismatched payload for UnblockPipeInput"), + }, + Some(CommandName::BlockCliPipeInput) => match protobuf_plugin_command.payload { + Some(Payload::BlockCliPipeInputPayload(pipe_name)) => { + Ok(PluginCommand::BlockCliPipeInput(pipe_name)) + }, + _ => Err("Mismatched payload for BlockPipeInput"), + }, + Some(CommandName::CliPipeOutput) => match protobuf_plugin_command.payload { + Some(Payload::CliPipeOutputPayload(CliPipeOutputPayload { pipe_name, output })) => { + Ok(PluginCommand::CliPipeOutput(pipe_name, output)) + }, + _ => Err("Mismatched payload for PipeOutput"), + }, + Some(CommandName::MessageToPlugin) => match protobuf_plugin_command.payload { + Some(Payload::MessageToPluginPayload(MessageToPluginPayload { + plugin_url, + plugin_config, + message_name, + message_payload, + message_args, + new_plugin_args, + destination_plugin_id, + floating_pane_coordinates, + })) => { + let plugin_config: BTreeMap<String, String> = plugin_config + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + let message_args: BTreeMap<String, String> = message_args + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::MessageToPlugin(MessageToPlugin { + plugin_url, + plugin_config, + message_name, + message_payload, + message_args, + new_plugin_args: new_plugin_args.and_then(|protobuf_new_plugin_args| { + Some(NewPluginArgs { + should_float: protobuf_new_plugin_args.should_float, + pane_id_to_replace: protobuf_new_plugin_args + .pane_id_to_replace + .and_then(|p_id| PaneId::try_from(p_id).ok()), + pane_title: protobuf_new_plugin_args.pane_title, + cwd: protobuf_new_plugin_args.cwd.map(|cwd| PathBuf::from(cwd)), + skip_cache: protobuf_new_plugin_args.skip_cache, + should_focus: protobuf_new_plugin_args.should_focus, + }) + }), + destination_plugin_id, + floating_pane_coordinates: floating_pane_coordinates + .and_then(|f| f.try_into().ok()), + })) + }, + _ => Err("Mismatched payload for MessageToPlugin"), + }, + Some(CommandName::DisconnectOtherClients) => match protobuf_plugin_command.payload { + None => Ok(PluginCommand::DisconnectOtherClients), + _ => Err("Mismatched payload for DisconnectOtherClients"), + }, + Some(CommandName::KillSessions) => match protobuf_plugin_command.payload { + Some(Payload::KillSessionsPayload(KillSessionsPayload { session_names })) => { + Ok(PluginCommand::KillSessions(session_names)) + }, + _ => Err("Mismatched payload for KillSessions"), + }, + Some(CommandName::ScanHostFolder) => match protobuf_plugin_command.payload { + Some(Payload::ScanHostFolderPayload(folder_to_scan)) => { + Ok(PluginCommand::ScanHostFolder(PathBuf::from(folder_to_scan))) + }, + _ => Err("Mismatched payload for ScanHostFolder"), + }, + Some(CommandName::WatchFilesystem) => match protobuf_plugin_command.payload { + Some(_) => Err("WatchFilesystem should have no payload, found a payload"), + None => Ok(PluginCommand::WatchFilesystem), + }, + Some(CommandName::ListWindowsVolumes) => match protobuf_plugin_command.payload { + Some(_) => Err("ListWindowsVolumes should have no payload"), + None => Ok(PluginCommand::ListWindowsVolumes), + }, + Some(CommandName::GetSessionList) => match protobuf_plugin_command.payload { + Some(Payload::GetSessionListPayload(_)) => Ok(PluginCommand::GetSessionList), + None => Ok(PluginCommand::GetSessionList), + _ => Err("Mismatched payload for GetSessionList"), + }, + Some(CommandName::KillSessionsAndReply) => match protobuf_plugin_command.payload { + Some(Payload::KillSessionsAndReplyPayload(KillSessionsPayload { + session_names, + })) => Ok(PluginCommand::KillSessionsAndReply(session_names)), + _ => Err("Mismatched payload for KillSessionsAndReply"), + }, + Some(CommandName::DeleteDeadSessionAndReply) => match protobuf_plugin_command.payload { + Some(Payload::DeleteDeadSessionAndReplyPayload(dead_session_name)) => { + Ok(PluginCommand::DeleteDeadSessionAndReply(dead_session_name)) + }, + _ => Err("Mismatched payload for DeleteDeadSessionAndReply"), + }, + Some(CommandName::DeleteAllDeadSessionsAndReply) => { + Ok(PluginCommand::DeleteAllDeadSessionsAndReply) + }, + Some(CommandName::SetSoftKeyboard) => match protobuf_plugin_command.payload { + Some(Payload::SetSoftKeyboardPayload(payload)) => { + Ok(PluginCommand::SetSoftKeyboard(payload.on)) + }, + _ => Err("Mismatched payload for SetSoftKeyboard"), + }, + Some(CommandName::SetTabFit) => match protobuf_plugin_command.payload { + Some(Payload::SetTabFitPayload(payload)) => { + let fit = match (payload.pane_id, payload.size) { + (Some(pane_id), Some(size)) => { + Some((pane_id.try_into()?, size_from_protobuf(size))) + }, + (None, None) => None, + _ => return Err("Malformed set_tab_fit_payload payload"), + }; + Ok(PluginCommand::SetTabFit { + tab_id: payload.tab_id as usize, + fit, + }) + }, + _ => Err("Mismatched payload for SetTabFit"), + }, + Some(CommandName::ExitMobileMode) => match protobuf_plugin_command.payload { + Some(_) => Err("ExitMobileMode should have no payload, found a payload"), + None => Ok(PluginCommand::ExitMobileMode), + }, + Some(CommandName::SetShadowFocus) => match protobuf_plugin_command.payload { + Some(Payload::SetShadowFocusPayload(pane_id)) => { + Ok(PluginCommand::SetShadowFocus(pane_id.try_into()?)) + }, + _ => Err("Mismatched payload for SetShadowFocus"), + }, + Some(CommandName::DumpSessionLayout) => match protobuf_plugin_command.payload { + Some(Payload::DumpSessionLayoutPayload(payload)) => { + Ok(PluginCommand::DumpSessionLayout { + tab_index: payload.tab_index.map(|i| i as usize), + }) + }, + None => Ok(PluginCommand::DumpSessionLayout { tab_index: None }), + _ => Err("Mismatched payload for DumpSessionLayout"), + }, + Some(CommandName::CloseSelf) => match protobuf_plugin_command.payload { + Some(_) => Err("CloseSelf should have no payload, found a payload"), + None => Ok(PluginCommand::CloseSelf), + }, + Some(CommandName::NewTabsWithLayoutInfo) => match protobuf_plugin_command.payload { + Some(Payload::NewTabsWithLayoutInfoPayload(new_tabs_with_layout_info_payload)) => { + new_tabs_with_layout_info_payload + .layout_info + .and_then(|layout_info| { + Some(PluginCommand::NewTabsWithLayoutInfo( + layout_info.try_into().ok()?, + )) + }) + .ok_or("Failed to parse NewTabsWithLayoutInfo command") + }, + _ => Err("Mismatched payload for NewTabsWithLayoutInfo"), + }, + Some(CommandName::Reconfigure) => match protobuf_plugin_command.payload { + Some(Payload::ReconfigurePayload(reconfigure_payload)) => { + Ok(PluginCommand::Reconfigure( + reconfigure_payload.config, + reconfigure_payload.write_to_disk, + )) + }, + _ => 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; + let should_focus_pane = show_pane_with_id_payload.should_focus_pane; + Ok(PluginCommand::ShowPaneWithId( + pane_id, + should_float_if_hidden, + should_focus_pane, + )) + }, + _ => Err("Mismatched payload for ShowPaneWithId"), + }, + Some(CommandName::OpenCommandPaneBackground) => match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneBackgroundPayload(command_to_run_payload)) => { + match command_to_run_payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = command_to_run_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneBackground( + command_to_run.try_into()?, + context, + )) + }, + None => Err("Malformed open command pane background payload"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneBackground"), + }, + Some(CommandName::RerunCommandPane) => match protobuf_plugin_command.payload { + Some(Payload::RerunCommandPanePayload(rerun_command_pane_payload)) => Ok( + PluginCommand::RerunCommandPane(rerun_command_pane_payload.terminal_pane_id), + ), + _ => Err("Mismatched payload for RerunCommandPane"), + }, + Some(CommandName::ResizePaneIdWithDirection) => match protobuf_plugin_command.payload { + Some(Payload::ResizePaneIdWithDirectionPayload(resize_with_direction_payload)) => { + match ( + resize_with_direction_payload.resize, + resize_with_direction_payload.pane_id, + ) { + (Some(resize), Some(pane_id)) => { + Ok(PluginCommand::ResizePaneIdWithDirection( + resize.try_into()?, + pane_id.try_into()?, + )) + }, + _ => Err("Malformed resize_pane_with_id payload"), + } + }, + _ => Err("Mismatched payload for Resize"), + }, + Some(CommandName::EditScrollbackForPaneWithId) => match protobuf_plugin_command.payload + { + Some(Payload::EditScrollbackForPaneWithIdPayload( + edit_scrollback_for_pane_with_id_payload, + )) => match edit_scrollback_for_pane_with_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::EditScrollbackForPaneWithId( + pane_id.try_into()?, + )), + _ => Err("Malformed edit_scrollback_for_pane_with_id payload"), + }, + _ => Err("Mismatched payload for EditScrollback"), + }, + Some(CommandName::GetPaneScrollback) => match protobuf_plugin_command.payload { + Some(Payload::GetPaneScrollbackPayload(get_pane_scrollback_payload)) => { + match get_pane_scrollback_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::GetPaneScrollback { + pane_id: pane_id.try_into()?, + get_full_scrollback: get_pane_scrollback_payload.get_full_scrollback, + }), + _ => Err("Malformed get_pane_scrollback_payload"), + } + }, + _ => Err("Mismatched payload for GetPaneScrollback"), + }, + Some(CommandName::WriteToPaneId) => match protobuf_plugin_command.payload { + Some(Payload::WriteToPaneIdPayload(write_to_pane_id_payload)) => { + match write_to_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::WriteToPaneId( + write_to_pane_id_payload.bytes_to_write, + pane_id.try_into()?, + )), + _ => Err("Malformed write_to_pane_id payload"), + } + }, + _ => Err("Mismatched payload for WriteToPaneId"), + }, + Some(CommandName::WriteCharsToPaneId) => match protobuf_plugin_command.payload { + Some(Payload::WriteCharsToPaneIdPayload(write_chars_to_pane_id_payload)) => { + match write_chars_to_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::WriteCharsToPaneId( + write_chars_to_pane_id_payload.chars_to_write, + pane_id.try_into()?, + )), + _ => Err("Malformed write_chars_to_pane_id payload"), + } + }, + _ => Err("Mismatched payload for WriteCharsCharsToPaneId"), + }, + Some(CommandName::SendSigintToPaneId) => match protobuf_plugin_command.payload { + Some(Payload::SendSigintToPaneIdPayload(pane_id)) => { + Ok(PluginCommand::SendSigintToPaneId(pane_id.try_into()?)) + }, + _ => Err("Mismatched payload for SendSigintToPaneId"), + }, + Some(CommandName::SendSigkillToPaneId) => match protobuf_plugin_command.payload { + Some(Payload::SendSigkillToPaneIdPayload(pane_id)) => { + Ok(PluginCommand::SendSigkillToPaneId(pane_id.try_into()?)) + }, + _ => Err("Mismatched payload for SendSigkillToPaneId"), + }, + Some(CommandName::GetPanePid) => match protobuf_plugin_command.payload { + Some(Payload::GetPanePidPayload(get_pane_pid_payload)) => { + match get_pane_pid_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::GetPanePid { + pane_id: pane_id.try_into()?, + }), + _ => Err("Malformed get_pane_pid payload"), + } + }, + _ => Err("Mismatched payload for GetPanePid"), + }, + Some(CommandName::GetPaneRunningCommand) => match protobuf_plugin_command.payload { + Some(Payload::GetPaneRunningCommandPayload(payload)) => { + Ok(PluginCommand::GetPaneRunningCommand { + pane_id: payload + .pane_id + .ok_or("Malformed GetPaneRunningCommand: missing pane_id")? + .try_into()?, + }) + }, + _ => Err("Malformed GetPaneRunningCommand payload"), + }, + Some(CommandName::GetPaneCwd) => match protobuf_plugin_command.payload { + Some(Payload::GetPaneCwdPayload(payload)) => Ok(PluginCommand::GetPaneCwd { + pane_id: payload + .pane_id + .ok_or("Malformed GetPaneCwd: missing pane_id")? + .try_into()?, + }), + _ => Err("Malformed GetPaneCwd payload"), + }, + Some(CommandName::OverrideLayout) => match protobuf_plugin_command.payload { + Some(Payload::OverrideLayoutPayload(override_layout_payload)) => { + let layout_info = override_layout_payload + .layout_info + .ok_or("OverrideLayout missing layout_info")? + .try_into() + .map_err(|_| "Failed to parse LayoutInfo")?; + let context = override_layout_payload + .context + .into_iter() + .map(|c| (c.name, c.value)) + .collect(); + Ok(PluginCommand::OverrideLayout( + layout_info, + override_layout_payload.retain_existing_terminal_panes, + override_layout_payload.retain_existing_plugin_panes, + override_layout_payload.apply_only_to_active_tab, + context, + )) + }, + _ => Err("Mismatched payload for OverrideLayout"), + }, + Some(CommandName::SaveLayout) => match protobuf_plugin_command.payload { + Some(Payload::SaveLayoutPayload(save_layout_payload)) => { + Ok(PluginCommand::SaveLayout { + layout_name: save_layout_payload.layout_name, + layout_kdl: save_layout_payload.layout_kdl, + overwrite: save_layout_payload.overwrite, + }) + }, + _ => Err("Mismatched payload for SaveLayout"), + }, + Some(CommandName::DeleteLayout) => match protobuf_plugin_command.payload { + Some(Payload::DeleteLayoutPayload(delete_layout_payload)) => { + Ok(PluginCommand::DeleteLayout { + layout_name: delete_layout_payload.layout_name, + }) + }, + _ => Err("Mismatched payload for DeleteLayout"), + }, + Some(CommandName::RenameLayout) => match protobuf_plugin_command.payload { + Some(Payload::RenameLayoutPayload(rename_layout_payload)) => { + Ok(PluginCommand::RenameLayout { + old_layout_name: rename_layout_payload.old_layout_name, + new_layout_name: rename_layout_payload.new_layout_name, + }) + }, + _ => Err("Mismatched payload for RenameLayout"), + }, + Some(CommandName::EditLayout) => match protobuf_plugin_command.payload { + Some(Payload::EditLayoutPayload(edit_layout_payload)) => { + let layout_name = edit_layout_payload.layout_name; + let context: BTreeMap<String, String> = edit_layout_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::EditLayout { + layout_name, + context, + }) + }, + _ => Err("Mismatched payload for EditLayout"), + }, + Some(CommandName::MovePaneWithPaneId) => match protobuf_plugin_command.payload { + Some(Payload::MovePaneWithPaneIdPayload(move_pane_with_pane_id_payload)) => { + match move_pane_with_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::MovePaneWithPaneId(pane_id.try_into()?)), + _ => Err("Malformed move_pane_with_pane_id payload"), + } + }, + _ => Err("Mismatched payload for MovePaneWithPaneId"), + }, + Some(CommandName::MovePaneWithPaneIdInDirection) => { + match protobuf_plugin_command.payload { + Some(Payload::MovePaneWithPaneIdInDirectionPayload(move_payload)) => { + match (move_payload.direction, move_payload.pane_id) { + (Some(direction), Some(pane_id)) => { + Ok(PluginCommand::MovePaneWithPaneIdInDirection( + pane_id.try_into()?, + direction.try_into()?, + )) + }, + _ => Err("Malformed MovePaneWithPaneIdInDirection payload"), + } + }, + _ => Err("Mismatched payload for MovePaneWithDirection"), + } + }, + Some(CommandName::ClearScreenForPaneId) => match protobuf_plugin_command.payload { + Some(Payload::ClearScreenForPaneIdPayload(clear_screen_for_pane_id_payload)) => { + match clear_screen_for_pane_id_payload.pane_id { + Some(pane_id) => { + Ok(PluginCommand::ClearScreenForPaneId(pane_id.try_into()?)) + }, + _ => Err("Malformed clear_screen_for_pane_id_payload payload"), + } + }, + _ => Err("Mismatched payload for ClearScreenForPaneId"), + }, + Some(CommandName::ScrollUpInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::ScrollUpInPaneIdPayload(scroll_up_in_pane_id_payload)) => { + match scroll_up_in_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::ScrollUpInPaneId(pane_id.try_into()?)), + _ => Err("Malformed scroll_up_in_pane_id_payload payload"), + } + }, + _ => Err("Mismatched payload for ScrollUpInPaneId"), + }, + Some(CommandName::ScrollDownInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::ScrollDownInPaneIdPayload(scroll_down_in_pane_id_payload)) => { + match scroll_down_in_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::ScrollDownInPaneId(pane_id.try_into()?)), + _ => Err("Malformed scroll_down_in_pane_id_payload payload"), + } + }, + _ => Err("Mismatched payload for ScrollDownInPaneId"), + }, + Some(CommandName::ScrollToTopInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::ScrollToTopInPaneIdPayload(scroll_to_top_in_pane_id_payload)) => { + match scroll_to_top_in_pane_id_payload.pane_id { + Some(pane_id) => { + Ok(PluginCommand::ScrollToTopInPaneId(pane_id.try_into()?)) + }, + _ => Err("Malformed scroll_to_top_in_pane_id_payload payload"), + } + }, + _ => Err("Mismatched payload for ScrollToTopInPaneId"), + }, + Some(CommandName::ScrollToBottomInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::ScrollToBottomInPaneIdPayload( + scroll_to_bottom_in_pane_id_payload, + )) => match scroll_to_bottom_in_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::ScrollToBottomInPaneId(pane_id.try_into()?)), + _ => Err("Malformed scroll_to_bottom_in_pane_id_payload payload"), + }, + _ => Err("Mismatched payload for ScrollToBottomInPaneId"), + }, + Some(CommandName::PageScrollUpInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::PageScrollUpInPaneIdPayload(page_scroll_up_in_pane_id_payload)) => { + match page_scroll_up_in_pane_id_payload.pane_id { + Some(pane_id) => { + Ok(PluginCommand::PageScrollUpInPaneId(pane_id.try_into()?)) + }, + _ => Err("Malformed page_scroll_up_in_pane_id_payload payload"), + } + }, + _ => Err("Mismatched payload for PageScrollUpInPaneId"), + }, + Some(CommandName::PageScrollDownInPaneId) => match protobuf_plugin_command.payload { + Some(Payload::PageScrollDownInPaneIdPayload( + page_scroll_down_in_pane_id_payload, + )) => match page_scroll_down_in_pane_id_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::PageScrollDownInPaneId(pane_id.try_into()?)), + _ => Err("Malformed page_scroll_down_in_pane_id_payload payload"), + }, + _ => Err("Mismatched payload for PageScrollDownInPaneId"), + }, + Some(CommandName::TogglePaneIdFullscreen) => match protobuf_plugin_command.payload { + Some(Payload::TogglePaneIdFullscreenPayload(toggle_pane_id_fullscreen_payload)) => { + match toggle_pane_id_fullscreen_payload.pane_id { + Some(pane_id) => { + Ok(PluginCommand::TogglePaneIdFullscreen(pane_id.try_into()?)) + }, + _ => Err("Malformed toggle_pane_id_fullscreen_payload payload"), + } + }, + _ => Err("Mismatched payload for TogglePaneIdFullscreen"), + }, + Some(CommandName::TogglePaneEmbedOrEjectForPaneId) => { + match protobuf_plugin_command.payload { + Some(Payload::TogglePaneEmbedOrEjectForPaneIdPayload( + toggle_pane_embed_or_eject_payload, + )) => match toggle_pane_embed_or_eject_payload.pane_id { + Some(pane_id) => Ok(PluginCommand::TogglePaneEmbedOrEjectForPaneId( + pane_id.try_into()?, + )), + _ => Err("Malformed toggle_pane_embed_or_eject_payload payload"), + }, + _ => Err("Mismatched payload for TogglePaneEmbedOrEjectForPaneId"), + } + }, + Some(CommandName::CloseTabWithIndex) => match protobuf_plugin_command.payload { + Some(Payload::CloseTabWithIndexPayload(close_tab_index_payload)) => Ok( + PluginCommand::CloseTabWithIndex(close_tab_index_payload.tab_index as usize), + ), + _ => Err("Mismatched payload for CloseTabWithIndex"), + }, + Some(CommandName::BreakPanesToNewTab) => match protobuf_plugin_command.payload { + Some(Payload::BreakPanesToNewTabPayload(break_panes_to_new_tab_payload)) => { + Ok(PluginCommand::BreakPanesToNewTab( + break_panes_to_new_tab_payload + .pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + break_panes_to_new_tab_payload.new_tab_name, + break_panes_to_new_tab_payload.should_change_focus_to_new_tab, + )) + }, + _ => Err("Mismatched payload for BreakPanesToNewTab"), + }, + Some(CommandName::BreakPanesToTabWithIndex) => match protobuf_plugin_command.payload { + Some(Payload::BreakPanesToTabWithIndexPayload( + break_panes_to_tab_with_index_payload, + )) => Ok(PluginCommand::BreakPanesToTabWithIndex( + break_panes_to_tab_with_index_payload + .pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + break_panes_to_tab_with_index_payload.tab_index as usize, + break_panes_to_tab_with_index_payload.should_change_focus_to_target_tab, + )), + _ => Err("Mismatched payload for BreakPanesToTabWithIndex"), + }, + Some(CommandName::SwitchTabToId) => match protobuf_plugin_command.payload { + Some(Payload::SwitchTabToIdPayload(payload)) => { + Ok(PluginCommand::SwitchTabToId(payload.tab_id)) + }, + _ => Err("Mismatched payload for SwitchTabToId"), + }, + Some(CommandName::GoToTabWithId) => match protobuf_plugin_command.payload { + Some(Payload::GoToTabWithIdPayload(payload)) => { + Ok(PluginCommand::GoToTabWithId(payload.tab_id)) + }, + _ => Err("Mismatched payload for GoToTabWithId"), + }, + Some(CommandName::CloseTabWithId) => match protobuf_plugin_command.payload { + Some(Payload::CloseTabWithIdPayload(payload)) => { + Ok(PluginCommand::CloseTabWithId(payload.tab_id)) + }, + _ => Err("Mismatched payload for CloseTabWithId"), + }, + Some(CommandName::RenameTabWithId) => match protobuf_plugin_command.payload { + Some(Payload::RenameTabWithIdPayload(payload)) => Ok( + PluginCommand::RenameTabWithId(payload.tab_id, payload.new_name), + ), + _ => Err("Mismatched payload for RenameTabWithId"), + }, + Some(CommandName::BreakPanesToTabWithId) => match protobuf_plugin_command.payload { + Some(Payload::BreakPanesToTabWithIdPayload(payload)) => { + Ok(PluginCommand::BreakPanesToTabWithId( + payload + .pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + payload.tab_id, + payload.should_change_focus_to_target_tab, + )) + }, + _ => Err("Mismatched payload for BreakPanesToTabWithId"), + }, + Some(CommandName::ReloadPlugin) => match protobuf_plugin_command.payload { + Some(Payload::ReloadPluginPayload(reload_plugin_payload)) => { + Ok(PluginCommand::ReloadPlugin(reload_plugin_payload.plugin_id)) + }, + _ => Err("Mismatched payload for ReloadPlugin"), + }, + Some(CommandName::LoadNewPlugin) => match protobuf_plugin_command.payload { + Some(Payload::LoadNewPluginPayload(load_new_plugin_payload)) => { + Ok(PluginCommand::LoadNewPlugin { + url: load_new_plugin_payload.plugin_url, + config: load_new_plugin_payload + .plugin_config + .into_iter() + .map(|e| (e.name, e.value)) + .collect(), + load_in_background: load_new_plugin_payload + .should_load_plugin_in_background, + skip_plugin_cache: load_new_plugin_payload.should_skip_plugin_cache, + }) + }, + _ => Err("Mismatched payload for LoadNewPlugin"), + }, + Some(CommandName::RebindKeys) => match protobuf_plugin_command.payload { + Some(Payload::RebindKeysPayload(rebind_keys_payload)) => { + Ok(PluginCommand::RebindKeys { + keys_to_rebind: rebind_keys_payload + .keys_to_rebind + .into_iter() + .filter_map(|k| key_to_rebind_to_plugin_command_assets(k)) + .collect(), + keys_to_unbind: rebind_keys_payload + .keys_to_unbind + .into_iter() + .filter_map(|k| key_to_unbind_to_plugin_command_assets(k)) + .collect(), + write_config_to_disk: rebind_keys_payload.write_config_to_disk, + }) + }, + _ => Err("Mismatched payload for RebindKeys"), + }, + Some(CommandName::ListClients) => match protobuf_plugin_command.payload { + Some(_) => Err("ListClients should have no payload, found a payload"), + None => Ok(PluginCommand::ListClients), + }, + Some(CommandName::ChangeHostFolder) => match protobuf_plugin_command.payload { + Some(Payload::ChangeHostFolderPayload(change_host_folder_payload)) => { + Ok(PluginCommand::ChangeHostFolder(PathBuf::from( + change_host_folder_payload.new_host_folder, + ))) + }, + _ => Err("Mismatched payload for ChangeHostFolder"), + }, + Some(CommandName::SetFloatingPanePinned) => match protobuf_plugin_command.payload { + Some(Payload::SetFloatingPanePinnedPayload(set_floating_pane_pinned_payload)) => { + match set_floating_pane_pinned_payload + .pane_id + .and_then(|p| p.try_into().ok()) + { + Some(pane_id) => Ok(PluginCommand::SetFloatingPanePinned( + pane_id, + set_floating_pane_pinned_payload.should_be_pinned, + )), + None => Err("PaneId not found!"), + } + }, + _ => Err("Mismatched payload for SetFloatingPanePinned"), + }, + Some(CommandName::StackPanes) => match protobuf_plugin_command.payload { + Some(Payload::StackPanesPayload(stack_panes_payload)) => { + Ok(PluginCommand::StackPanes( + stack_panes_payload + .pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + )) + }, + _ => Err("Mismatched payload for StackPanes"), + }, + Some(CommandName::ChangeFloatingPanesCoordinates) => { + match protobuf_plugin_command.payload { + Some(Payload::ChangeFloatingPanesCoordinatesPayload( + change_floating_panes_coordinates_payload, + )) => Ok(PluginCommand::ChangeFloatingPanesCoordinates( + change_floating_panes_coordinates_payload + .pane_ids_and_floating_panes_coordinates + .into_iter() + .filter_map(|p_id_a_fp| { + let pane_id: PaneId = p_id_a_fp.pane_id?.try_into().ok()?; + let floating_pane_coordinates: FloatingPaneCoordinates = + p_id_a_fp.floating_pane_coordinates?.try_into().ok()?; + Some((pane_id, floating_pane_coordinates)) + }) + .collect(), + )), + _ => Err("Mismatched payload for ChangeFloatingPanesCoordinates"), + } + }, + Some(CommandName::TogglePaneBorderless) => match protobuf_plugin_command.payload { + Some(Payload::TogglePaneBorderlessPayload(toggle_payload)) => { + match toggle_payload.pane_id { + Some(pane_id) => { + Ok(PluginCommand::TogglePaneBorderless(pane_id.try_into()?)) + }, + None => Err("Malformed TogglePaneBorderless payload"), + } + }, + _ => Err("Mismatched payload for TogglePaneBorderless"), + }, + Some(CommandName::SetPaneBorderless) => match protobuf_plugin_command.payload { + Some(Payload::SetPaneBorderlessPayload(payload)) => { + match (payload.pane_id, payload.borderless) { + (Some(pane_id), borderless) => Ok(PluginCommand::SetPaneBorderless( + pane_id.try_into()?, + borderless, + )), + _ => Err("Malformed SetPaneBorderless payload"), + } + }, + _ => Err("Mismatched payload for SetPaneBorderless"), + }, + Some(CommandName::OpenCommandPaneNearPlugin) => match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneNearPluginPayload(command_to_run_payload)) => { + match command_to_run_payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = command_to_run_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneNearPlugin( + command_to_run.try_into()?, + context, + )) + }, + None => Err("Malformed open command pane near plugin payload"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneNearPlugin"), + }, + Some(CommandName::OpenTerminalNearPlugin) => match protobuf_plugin_command.payload { + Some(Payload::OpenTerminalNearPluginPayload(open_terminal_near_plugin_payload)) => { + match open_terminal_near_plugin_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenTerminalNearPlugin( + file_to_open.try_into()?, + )), + None => Err("Malformed open terminal near plugin payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminalNearPluginPayload"), + }, + Some(CommandName::OpenTerminalFloatingNearPlugin) => match protobuf_plugin_command + .payload + { + Some(Payload::OpenTerminalFloatingNearPluginPayload( + open_terminal_floating_near_plugin_payload, + )) => { + let floating_pane_coordinates = open_terminal_floating_near_plugin_payload + .floating_pane_coordinates + .map(|f| f.into()); + match open_terminal_floating_near_plugin_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenTerminalFloatingNearPlugin( + file_to_open.try_into()?, + floating_pane_coordinates, + )), + None => Err("Malformed open terminal floating near plugin payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminalFloatingNearPlugin"), + }, + Some(CommandName::OpenTerminalInPlaceOfPlugin) => match protobuf_plugin_command.payload + { + Some(Payload::OpenTerminalInPlaceOfPluginPayload( + open_terminal_in_place_of_plugin_payload, + )) => match open_terminal_in_place_of_plugin_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenTerminalInPlaceOfPlugin( + file_to_open.try_into()?, + open_terminal_in_place_of_plugin_payload.close_plugin_after_replace, + )), + None => Err("Malformed open terminal in place of plugin payload"), + }, + _ => Err("Mismatched payload for OpenTerminalInPlaceOfPlugin"), + }, + Some(CommandName::OpenCommandPaneFloatingNearPlugin) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneFloatingNearPluginPayload( + open_command_pane_floating_near_plugin, + )) => match open_command_pane_floating_near_plugin.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = + open_command_pane_floating_near_plugin + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + let floating_pane_coordinates = open_command_pane_floating_near_plugin + .floating_pane_coordinates + .map(|f| f.into()); + Ok(PluginCommand::OpenCommandPaneFloatingNearPlugin( + command_to_run.try_into()?, + floating_pane_coordinates, + context, + )) + }, + None => Err("Malformed open command pane floating near plugin payload"), + }, + _ => Err("Mismatched payload for OpenCommandPaneFloatingNearPlugin"), + } + }, + Some(CommandName::OpenCommandPaneInPlaceOfPlugin) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneInPlaceOfPluginPayload( + open_command_pane_in_place_of_plugin_payload, + )) => match open_command_pane_in_place_of_plugin_payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = + open_command_pane_in_place_of_plugin_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneInPlaceOfPlugin( + command_to_run.try_into()?, + open_command_pane_in_place_of_plugin_payload + .close_plugin_after_replace, + context, + )) + }, + None => Err("Malformed open command pane in place of plugin payload"), + }, + _ => Err("Mismatched payload for OpenCommandPaneInPlaceOfPlugin"), + } + }, + Some(CommandName::OpenFileNearPlugin) => match protobuf_plugin_command.payload { + Some(Payload::OpenFileNearPluginPayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenFileNearPlugin( + file_to_open.try_into()?, + context, + )) + }, + None => Err("Malformed open file payload"), + } + }, + _ => Err("Mismatched payload for OpenFileNearPlugin"), + }, + Some(CommandName::OpenFileFloatingNearPlugin) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenFileFloatingNearPluginPayload(file_to_open_payload)) => { + let floating_pane_coordinates = file_to_open_payload + .floating_pane_coordinates + .map(|f| f.into()); + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + match file_to_open_payload.file_to_open { + Some(file_to_open) => Ok(PluginCommand::OpenFileFloatingNearPlugin( + file_to_open.try_into()?, + floating_pane_coordinates, + context, + )), + None => Err("Malformed open file payload"), + } + }, + _ => Err("Mismatched payload for OpenFileFloatingNearPlugin"), + } + }, + Some(CommandName::OpenFileInPlaceOfPlugin) => match protobuf_plugin_command.payload { + Some(Payload::OpenFileInPlaceOfPluginPayload(file_to_open_payload)) => { + match file_to_open_payload.file_to_open { + Some(file_to_open) => { + let context: BTreeMap<String, String> = file_to_open_payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenFileInPlaceOfPlugin( + file_to_open.try_into()?, + file_to_open_payload.close_plugin_after_replace, + context, + )) + }, + None => Err("Malformed open file in place payload"), + } + }, + _ => Err("Mismatched payload for OpenFileInPlaceOfPlugin"), + }, + Some(CommandName::StartWebServer) => { + if protobuf_plugin_command.payload.is_some() { + Err("StartWebServer should not have a payload") + } else { + Ok(PluginCommand::StartWebServer) + } + }, + Some(CommandName::StopWebServer) => { + if protobuf_plugin_command.payload.is_some() { + Err("StopWebServer should not have a payload") + } else { + Ok(PluginCommand::StopWebServer) + } + }, + Some(CommandName::QueryWebServerStatus) => { + if protobuf_plugin_command.payload.is_some() { + Err("QueryWebServerStatus should not have a payload") + } else { + Ok(PluginCommand::QueryWebServerStatus) + } + }, + Some(CommandName::GroupAndUngroupPanes) => match protobuf_plugin_command.payload { + Some(Payload::GroupAndUngroupPanesPayload(group_and_ungroup_panes_payload)) => { + Ok(PluginCommand::GroupAndUngroupPanes( + group_and_ungroup_panes_payload + .pane_ids_to_group + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + group_and_ungroup_panes_payload + .pane_ids_to_ungroup + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + group_and_ungroup_panes_payload.for_all_clients, + )) + }, + _ => Err("Mismatched payload for GroupAndUngroupPanes"), + }, + Some(CommandName::HighlightAndUnhighlightPanes) => { + match protobuf_plugin_command.payload { + Some(Payload::HighlightAndUnhighlightPanesPayload( + highlight_and_unhighlight_panes_payload, + )) => Ok(PluginCommand::HighlightAndUnhighlightPanes( + highlight_and_unhighlight_panes_payload + .pane_ids_to_highlight + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + highlight_and_unhighlight_panes_payload + .pane_ids_to_unhighlight + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + )), + _ => Err("Mismatched payload for HighlightAndUnhighlightPanes"), + } + }, + Some(CommandName::CloseMultiplePanes) => match protobuf_plugin_command.payload { + Some(Payload::CloseMultiplePanesPayload(close_multiple_panes_payload)) => { + Ok(PluginCommand::CloseMultiplePanes( + close_multiple_panes_payload + .pane_ids + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + )) + }, + _ => Err("Mismatched payload for CloseMultiplePanes"), + }, + Some(CommandName::FloatMultiplePanes) => match protobuf_plugin_command.payload { + Some(Payload::FloatMultiplePanesPayload(float_multiple_panes_payload)) => { + Ok(PluginCommand::FloatMultiplePanes( + float_multiple_panes_payload + .pane_ids + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + )) + }, + _ => Err("Mismatched payload for FloatMultiplePanes"), + }, + Some(CommandName::EmbedMultiplePanes) => match protobuf_plugin_command.payload { + Some(Payload::EmbedMultiplePanesPayload(embed_multiple_panes_payload)) => { + Ok(PluginCommand::EmbedMultiplePanes( + embed_multiple_panes_payload + .pane_ids + .into_iter() + .filter_map(|p| p.try_into().ok()) + .collect(), + )) + }, + _ => Err("Mismatched payload for EmbedMultiplePanes"), + }, + Some(CommandName::ShareCurrentSession) => { + if protobuf_plugin_command.payload.is_some() { + Err("ShareCurrentSession should not have a payload") + } else { + Ok(PluginCommand::ShareCurrentSession) + } + }, + Some(CommandName::StopSharingCurrentSession) => { + if protobuf_plugin_command.payload.is_some() { + Err("StopSharingCurrentSession should not have a payload") + } else { + Ok(PluginCommand::StopSharingCurrentSession) + } + }, + Some(CommandName::SetSelfMouseSelectionSupport) => { + match protobuf_plugin_command.payload { + Some(Payload::SetSelfMouseSelectionSupportPayload( + set_self_mouse_selection_support_payload, + )) => Ok(PluginCommand::SetSelfMouseSelectionSupport( + set_self_mouse_selection_support_payload.support_mouse_selection, + )), + _ => Err("SetSelfMouseSelectionSupport requires a payload"), + } + }, + Some(CommandName::GenerateWebLoginToken) => match protobuf_plugin_command.payload { + Some(Payload::GenerateWebLoginTokenPayload(generate_web_login_token_payload)) => { + Ok(PluginCommand::GenerateWebLoginToken( + generate_web_login_token_payload.token_label, + generate_web_login_token_payload.read_only.unwrap_or(false), + )) + }, + _ => Err("GenerateWebLoginToken requires a payload"), + }, + Some(CommandName::RevokeWebLoginToken) => match protobuf_plugin_command.payload { + Some(Payload::RevokeWebLoginTokenPayload(revoke_web_login_token_payload)) => Ok( + PluginCommand::RevokeWebLoginToken(revoke_web_login_token_payload.token_label), + ), + _ => Err("RevokeWebLoginToken requires a payload"), + }, + Some(CommandName::ListWebLoginTokens) => { + if protobuf_plugin_command.payload.is_some() { + Err("ListWebLoginTokens should not have a payload") + } else { + Ok(PluginCommand::ListWebLoginTokens) + } + }, + Some(CommandName::RevokeAllWebLoginTokens) => { + if protobuf_plugin_command.payload.is_some() { + Err("RevokeAllWebLoginTokens should not have a payload") + } else { + Ok(PluginCommand::RevokeAllWebLoginTokens) + } + }, + Some(CommandName::RenameWebLoginToken) => match protobuf_plugin_command.payload { + Some(Payload::RenameWebLoginTokenPayload(rename_web_login_token_payload)) => { + Ok(PluginCommand::RenameWebLoginToken( + rename_web_login_token_payload.old_name, + rename_web_login_token_payload.new_name, + )) + }, + _ => Err("RenameWebLoginToken requires a payload"), + }, + Some(CommandName::InterceptKeyPresses) => match protobuf_plugin_command.payload { + Some(_) => Err("InterceptKeyPresses should have no payload, found a payload"), + None => Ok(PluginCommand::InterceptKeyPresses), + }, + Some(CommandName::ClearKeyPressesIntercepts) => match protobuf_plugin_command.payload { + Some(_) => Err("ClearKeyPressesIntercepts should have no payload, found a payload"), + None => Ok(PluginCommand::ClearKeyPressesIntercepts), + }, + Some(CommandName::ReplacePaneWithExistingPane) => match protobuf_plugin_command.payload + { + Some(Payload::ReplacePaneWithExistingPanePayload( + replace_pane_with_other_pane_payload, + )) => Ok(PluginCommand::ReplacePaneWithExistingPane( + replace_pane_with_other_pane_payload + .pane_id_to_replace + .and_then(|p_id| PaneId::try_from(p_id).ok()) + .ok_or("Failed to parse ReplacePaneWithExistingPanePayload")?, + replace_pane_with_other_pane_payload + .existing_pane_id + .and_then(|p_id| PaneId::try_from(p_id).ok()) + .ok_or("Failed to parse ReplacePaneWithExistingPanePayload")?, + replace_pane_with_other_pane_payload.suppress_replaced_pane, + )), + _ => Err("Mismatched payload for ReplacePaneWithExistingPane"), + }, + Some(CommandName::RunAction) => match protobuf_plugin_command.payload { + Some(Payload::RunActionPayload(protobuf_payload)) => { + let action = Action::try_from( + protobuf_payload + .action + .ok_or("Missing action in RunAction payload")?, + ) + .map_err(|_| "Failed to convert protobuf action")?; + + let context: BTreeMap<String, String> = protobuf_payload + .context + .into_iter() + .map(|item| (item.name, item.value)) + .collect(); + + Ok(PluginCommand::RunAction(action, context)) + }, + _ => Err("Mismatched payload for RunAction"), + }, + Some(CommandName::CopyToClipboard) => match protobuf_plugin_command.payload { + Some(Payload::CopyToClipboardPayload(payload)) => { + Ok(PluginCommand::CopyToClipboard(payload.text)) + }, + _ => Err("Mismatched payload for CopyToClipboard"), + }, + Some(CommandName::GenerateRandomName) => Ok(PluginCommand::GenerateRandomName), + Some(CommandName::DumpLayout) => match protobuf_plugin_command.payload { + Some(Payload::DumpLayoutPayload(payload)) => { + Ok(PluginCommand::DumpLayout(payload.layout_name)) + }, + _ => Err("Mismatched payload for DumpLayout"), + }, + Some(CommandName::ParseLayout) => match protobuf_plugin_command.payload { + Some(Payload::ParseLayoutPayload(payload)) => { + Ok(PluginCommand::ParseLayout(payload.layout_string)) + }, + _ => Err("Mismatched payload for ParseLayout"), + }, + Some(CommandName::GetLayoutDir) => Ok(PluginCommand::GetLayoutDir), + Some(CommandName::GetFocusedPaneInfo) => Ok(PluginCommand::GetFocusedPaneInfo), + Some(CommandName::SaveSession) => Ok(PluginCommand::SaveSession), + Some(CommandName::CurrentSessionLastSavedTime) => { + Ok(PluginCommand::CurrentSessionLastSavedTime) + }, + Some(CommandName::GetPaneInfo) => match protobuf_plugin_command.payload { + Some(Payload::GetPaneInfoPayload(get_pane_info_payload)) => { + let pane_id = get_pane_info_payload + .pane_id + .ok_or("Malformed pane_id for GetPaneInfo") + .and_then(|p| p.try_into())?; + Ok(PluginCommand::GetPaneInfo(pane_id)) + }, + _ => Err("Malformed payload for GetPaneInfo"), + }, + Some(CommandName::GetTabInfo) => match protobuf_plugin_command.payload { + Some(Payload::GetTabInfoPayload(get_tab_info_payload)) => { + let tab_id = get_tab_info_payload.tab_id as usize; + Ok(PluginCommand::GetTabInfo(tab_id)) + }, + _ => Err("Malformed payload for GetTabInfo"), + }, + Some(CommandName::GetSessionEnvironmentVariables) => { + match protobuf_plugin_command.payload { + Some(Payload::GetSessionEnvironmentVariablesPayload(_)) => { + Ok(PluginCommand::GetSessionEnvironmentVariables) + }, + _ => Err("Mismatched payload for GetSessionEnvironmentVariables"), + } + }, + Some(CommandName::OpenCommandPaneInNewTab) => match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneInNewTabPayload(payload)) => { + match payload.command_to_run { + Some(command_to_run) => { + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneInNewTab( + command_to_run.try_into()?, + context, + )) + }, + None => Err("Malformed open_command_pane_in_new_tab payload"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneInNewTab"), + }, + Some(CommandName::OpenPluginPaneInNewTab) => match protobuf_plugin_command.payload { + Some(Payload::OpenPluginPaneInNewTabPayload(payload)) => { + let configuration: BTreeMap<String, String> = + payload.configuration.into_iter().collect(); + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenPluginPaneInNewTab { + plugin_url: payload.plugin_url, + configuration, + context, + }) + }, + _ => Err("Mismatched payload for OpenPluginPaneInNewTab"), + }, + Some(CommandName::OpenEditorPaneInNewTab) => match protobuf_plugin_command.payload { + Some(Payload::OpenEditorPaneInNewTabPayload(payload)) => { + match payload.file_to_open { + Some(file) => { + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenEditorPaneInNewTab( + file.try_into()?, + context, + )) + }, + None => Err("Malformed open_editor_pane_in_new_tab payload"), + } + }, + _ => Err("Mismatched payload for OpenEditorPaneInNewTab"), + }, + Some(CommandName::OpenCommandPaneInPlaceOfPaneId) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenCommandPaneInPlaceOfPaneIdPayload(payload)) => { + match (payload.pane_id_to_replace, payload.command_to_run) { + (Some(pane_id), Some(command_to_run)) => { + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenCommandPaneInPlaceOfPaneId( + pane_id.try_into()?, + command_to_run.try_into()?, + payload.close_replaced_pane, + context, + )) + }, + _ => Err("Malformed open_command_pane_in_place_of_pane_id payload"), + } + }, + _ => Err("Mismatched payload for OpenCommandPaneInPlaceOfPaneId"), + } + }, + Some(CommandName::OpenTerminalPaneInPlaceOfPaneId) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenTerminalPaneInPlaceOfPaneIdPayload(payload)) => { + match payload.pane_id_to_replace { + Some(pane_id) => { + let cwd = payload.cwd.map(|f| f.try_into()).transpose()?; + let cwd = cwd.unwrap_or_else(|| crate::data::FileToOpen { + path: std::path::PathBuf::from("."), + ..Default::default() + }); + Ok(PluginCommand::OpenTerminalPaneInPlaceOfPaneId( + pane_id.try_into()?, + cwd, + payload.close_replaced_pane, + )) + }, + None => Err("Malformed open_terminal_pane_in_place_of_pane_id payload"), + } + }, + _ => Err("Mismatched payload for OpenTerminalPaneInPlaceOfPaneId"), + } + }, + Some(CommandName::OpenEditPaneInPlaceOfPaneId) => { + match protobuf_plugin_command.payload { + Some(Payload::OpenEditPaneInPlaceOfPaneIdPayload(payload)) => { + match (payload.pane_id_to_replace, payload.file_to_open) { + (Some(pane_id), Some(file_to_open)) => { + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenEditPaneInPlaceOfPaneId( + pane_id.try_into()?, + file_to_open.try_into()?, + payload.close_replaced_pane, + context, + )) + }, + _ => Err("Malformed open_edit_pane_in_place_of_pane_id payload"), + } + }, + _ => Err("Mismatched payload for OpenEditPaneInPlaceOfPaneId"), + } + }, + Some(CommandName::HideFloatingPanes) => match protobuf_plugin_command.payload { + Some(Payload::HideFloatingPanesPayload(payload)) => { + Ok(PluginCommand::HideFloatingPanes { + tab_id: payload.tab_id.map(|id| id as usize), + }) + }, + None => Ok(PluginCommand::HideFloatingPanes { tab_id: None }), + _ => Err("Mismatched payload for HideFloatingPanes"), + }, + Some(CommandName::ShowFloatingPanes) => match protobuf_plugin_command.payload { + Some(Payload::ShowFloatingPanesPayload(payload)) => { + Ok(PluginCommand::ShowFloatingPanes { + tab_id: payload.tab_id.map(|id| id as usize), + }) + }, + None => Ok(PluginCommand::ShowFloatingPanes { tab_id: None }), + _ => Err("Mismatched payload for ShowFloatingPanes"), + }, + Some(CommandName::SetPaneColor) => match protobuf_plugin_command.payload { + Some(Payload::SetPaneColorPayload(payload)) => match payload.pane_id { + Some(pane_id) => Ok(PluginCommand::SetPaneColor( + pane_id.try_into()?, + payload.fg, + payload.bg, + )), + None => Err("Malformed SetPaneColor payload"), + }, + _ => Err("Mismatched payload for SetPaneColor"), + }, + Some(CommandName::SetPaneRegexHighlights) => { + match protobuf_plugin_command.payload { + Some(Payload::SetPaneRegexHighlightsPayload(p)) => { + let pane_id: PaneId = p + .pane_id + .ok_or("Missing pane_id in SetPaneRegexHighlights")? + .try_into()?; + let highlights = p + .highlights + .into_iter() + .map(|h| { + let style = match h.style.and_then(|s| s.style) { + Some(ProtobufHighlightStyleVariant::Emphasis0(_)) => { + HighlightStyle::Emphasis0 + }, + Some(ProtobufHighlightStyleVariant::Emphasis1(_)) => { + HighlightStyle::Emphasis1 + }, + Some(ProtobufHighlightStyleVariant::Emphasis2(_)) => { + HighlightStyle::Emphasis2 + }, + Some(ProtobufHighlightStyleVariant::Emphasis3(_)) => { + HighlightStyle::Emphasis3 + }, + Some(ProtobufHighlightStyleVariant::CustomRgb(c)) => { + HighlightStyle::CustomRgb { + fg: match (c.fg_r, c.fg_g, c.fg_b) { + (Some(r), Some(g), Some(b)) => { + Some((r as u8, g as u8, b as u8)) + }, + _ => None, + }, + bg: match (c.bg_r, c.bg_g, c.bg_b) { + (Some(r), Some(g), Some(b)) => { + Some((r as u8, g as u8, b as u8)) + }, + _ => None, + }, + } + }, + Some(ProtobufHighlightStyleVariant::CustomIndex(c)) => { + HighlightStyle::CustomIndex { + fg: c.fg.map(|v| v as u8), + bg: c.bg.map(|v| v as u8), + } + }, + Some(ProtobufHighlightStyleVariant::BackgroundEmphasis0(_)) => { + HighlightStyle::BackgroundEmphasis0 + }, + Some(ProtobufHighlightStyleVariant::BackgroundEmphasis1(_)) => { + HighlightStyle::BackgroundEmphasis1 + }, + Some(ProtobufHighlightStyleVariant::BackgroundEmphasis2(_)) => { + HighlightStyle::BackgroundEmphasis2 + }, + Some(ProtobufHighlightStyleVariant::BackgroundEmphasis3(_)) => { + HighlightStyle::BackgroundEmphasis3 + }, + Some(ProtobufHighlightStyleVariant::None(_)) => { + HighlightStyle::None + }, + None => HighlightStyle::Emphasis0, // fallback + }; + let context = h + .context + .into_iter() + .map(|item| (item.name, item.value)) + .collect(); + RegexHighlight { + pattern: h.pattern, + style, + layer: match h.layer { + x if x == ProtobufHighlightLayer::Tool as i32 => { + HighlightLayer::Tool + }, + x if x == ProtobufHighlightLayer::ActionFeedback as i32 => { + HighlightLayer::ActionFeedback + }, + _ => HighlightLayer::Hint, // 0 or unknown => Hint + }, + context, + on_hover: h.on_hover, + bold: h.bold, + italic: h.italic, + underline: h.underline, + tooltip_text: h.tooltip_text, + } + }) + .collect(); + Ok(PluginCommand::SetPaneRegexHighlights(pane_id, highlights)) + }, + _ => Err("Mismatched payload for SetPaneRegexHighlights"), + } + }, + Some(CommandName::ClearPaneHighlights) => match protobuf_plugin_command.payload { + Some(Payload::ClearPaneHighlightsPayload(p)) => { + let pane_id: PaneId = p + .pane_id + .ok_or("Missing pane_id in ClearPaneHighlights")? + .try_into()?; + Ok(PluginCommand::ClearPaneHighlights(pane_id)) + }, + _ => Err("Mismatched payload for ClearPaneHighlights"), + }, + Some(CommandName::OpenPluginPaneFloating) => match protobuf_plugin_command.payload { + Some(Payload::OpenPluginPaneFloatingPayload(payload)) => { + let configuration: BTreeMap<String, String> = + payload.configuration.into_iter().collect(); + let floating_pane_coordinates = + payload.floating_pane_coordinates.map(|f| f.into()); + let context: BTreeMap<String, String> = payload + .context + .into_iter() + .map(|e| (e.name, e.value)) + .collect(); + Ok(PluginCommand::OpenPluginPaneFloating { + plugin_url: payload.plugin_url, + configuration, + floating_pane_coordinates, + context, + }) + }, + _ => Err("Mismatched payload for OpenPluginPaneFloating"), + }, + None => Err("Unrecognized plugin command"), + } + } +} + +impl TryFrom<PluginCommand> for ProtobufPluginCommand { + type Error = &'static str; + fn try_from(plugin_command: PluginCommand) -> Result<Self, &'static str> { + match plugin_command { + PluginCommand::Subscribe(subscriptions) => { + let subscriptions: ProtobufEventNameList = subscriptions.try_into()?; + Ok(ProtobufPluginCommand { + name: CommandName::Subscribe as i32, + payload: Some(Payload::SubscribePayload(SubscribePayload { + subscriptions: Some(subscriptions), + })), + }) + }, + PluginCommand::Unsubscribe(subscriptions) => { + let subscriptions: ProtobufEventNameList = subscriptions.try_into()?; + Ok(ProtobufPluginCommand { + name: CommandName::Unsubscribe as i32, + payload: Some(Payload::UnsubscribePayload(UnsubscribePayload { + subscriptions: Some(subscriptions), + })), + }) + }, + PluginCommand::SetSelectable(should_be_selectable) => Ok(ProtobufPluginCommand { + name: CommandName::SetSelectable as i32, + payload: Some(Payload::SetSelectablePayload(should_be_selectable)), + }), + PluginCommand::ShowCursor(cursor_position) => { + let position = cursor_position.map(|(x, y)| CursorPosition { + x: x as u32, + y: y as u32, + }); + Ok(ProtobufPluginCommand { + name: CommandName::ShowCursor as i32, + payload: Some(Payload::ShowCursorPayload(ShowCursorPayload { position })), + }) + }, + PluginCommand::GetPluginIds => Ok(ProtobufPluginCommand { + name: CommandName::GetPluginIds as i32, + payload: None, + }), + PluginCommand::GetZellijVersion => Ok(ProtobufPluginCommand { + name: CommandName::GetZellijVersion as i32, + payload: None, + }), + PluginCommand::OpenFile(file_to_open, context) => Ok(ProtobufPluginCommand { + name: CommandName::OpenFile as i32, + payload: Some(Payload::OpenFilePayload(OpenFilePayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: None, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + })), + }), + PluginCommand::OpenFileFloating(file_to_open, floating_pane_coordinates, context) => { + Ok(ProtobufPluginCommand { + name: CommandName::OpenFileFloating as i32, + payload: Some(Payload::OpenFileFloatingPayload(OpenFilePayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + })), + }) + }, + PluginCommand::OpenTerminal(cwd) => Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminal as i32, + payload: Some(Payload::OpenTerminalPayload(OpenFilePayload { + file_to_open: Some(cwd.try_into()?), + floating_pane_coordinates: None, + context: vec![], // will be added in the future + })), + }), + PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => { + Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalFloating as i32, + payload: Some(Payload::OpenTerminalFloatingPayload(OpenFilePayload { + file_to_open: Some(cwd.try_into()?), + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context: vec![], // will be added in the future + })), + }) + }, + 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, + }, + )), + }) + }, + PluginCommand::SwitchTabTo(tab_index) => Ok(ProtobufPluginCommand { + name: CommandName::SwitchTabTo as i32, + payload: Some(Payload::SwitchTabToPayload(SwitchTabToPayload { + tab_index: tab_index, + })), + }), + PluginCommand::SetTimeout(seconds) => Ok(ProtobufPluginCommand { + name: CommandName::SetTimeout as i32, + payload: Some(Payload::SetTimeoutPayload(SetTimeoutPayload { seconds })), + }), + PluginCommand::ExecCmd(command_line) => Ok(ProtobufPluginCommand { + name: CommandName::ExecCmd as i32, + payload: Some(Payload::ExecCmdPayload(ExecCmdPayload { command_line })), + }), + PluginCommand::PostMessageTo(plugin_message) => Ok(ProtobufPluginCommand { + name: CommandName::PostMessageTo as i32, + payload: Some(Payload::PostMessageToPayload(PluginMessagePayload { + message: Some(plugin_message.try_into()?), + })), + }), + PluginCommand::PostMessageToPlugin(plugin_message) => Ok(ProtobufPluginCommand { + name: CommandName::PostMessageToPlugin as i32, + payload: Some(Payload::PostMessageToPluginPayload(PluginMessagePayload { + message: Some(plugin_message.try_into()?), + })), + }), + PluginCommand::HideSelf => Ok(ProtobufPluginCommand { + name: CommandName::HideSelf as i32, + payload: None, + }), + PluginCommand::ShowSelf(should_float_if_hidden) => Ok(ProtobufPluginCommand { + name: CommandName::ShowSelf as i32, + payload: Some(Payload::ShowSelfPayload(should_float_if_hidden)), + }), + PluginCommand::SwitchToMode(input_mode) => Ok(ProtobufPluginCommand { + name: CommandName::SwitchToMode as i32, + payload: Some(Payload::SwitchToModePayload(SwitchToModePayload { + input_mode: ProtobufInputMode::try_from(input_mode)? as i32, + })), + }), + PluginCommand::NewTabsWithLayout(raw_layout) => Ok(ProtobufPluginCommand { + name: CommandName::NewTabsWithLayout as i32, + payload: Some(Payload::NewTabsWithLayoutPayload(raw_layout)), + }), + PluginCommand::NewTab { name, cwd } => Ok(ProtobufPluginCommand { + name: CommandName::NewTab as i32, + payload: Some(Payload::NewTabPayload(NewTabPayload { name, cwd })), + }), + PluginCommand::NewTabUnfocused { name, cwd } => Ok(ProtobufPluginCommand { + name: CommandName::NewTabUnfocused as i32, + payload: Some(Payload::NewTabUnfocusedPayload(NewTabUnfocusedPayload { + name, + cwd, + })), + }), + PluginCommand::NewTiledPaneInTab { tab_position } => Ok(ProtobufPluginCommand { + name: CommandName::NewTiledPaneInTab as i32, + payload: Some(Payload::NewTiledPaneInTabPayload( + NewTiledPaneInTabPayload { + tab_position: tab_position as u32, + }, + )), + }), + PluginCommand::ToggleFloatingPanes { tab_id } => Ok(ProtobufPluginCommand { + name: CommandName::ToggleFloatingPanes as i32, + payload: Some(Payload::ToggleFloatingPanesPayload( + ToggleFloatingPanesPayload { tab_id }, + )), + }), + PluginCommand::NewPane => Ok(ProtobufPluginCommand { + name: CommandName::NewPane as i32, + payload: None, + }), + PluginCommand::GoToNextTab => Ok(ProtobufPluginCommand { + name: CommandName::GoToNextTab as i32, + payload: None, + }), + PluginCommand::GoToPreviousTab => Ok(ProtobufPluginCommand { + name: CommandName::GoToPreviousTab as i32, + payload: None, + }), + PluginCommand::Resize(resize) => Ok(ProtobufPluginCommand { + name: CommandName::Resize as i32, + payload: Some(Payload::ResizePayload(ResizePayload { + resize: Some(resize.try_into()?), + })), + }), + PluginCommand::ResizeWithDirection(resize) => Ok(ProtobufPluginCommand { + name: CommandName::ResizeWithDirection as i32, + payload: Some(Payload::ResizeWithDirectionPayload(ResizePayload { + resize: Some(resize.try_into()?), + })), + }), + PluginCommand::FocusNextPane => Ok(ProtobufPluginCommand { + name: CommandName::FocusNextPane as i32, + payload: None, + }), + PluginCommand::FocusPreviousPane => Ok(ProtobufPluginCommand { + name: CommandName::FocusPreviousPane as i32, + payload: None, + }), + PluginCommand::FocusLastPane => Ok(ProtobufPluginCommand { + name: CommandName::FocusLastPane as i32, + payload: None, + }), + PluginCommand::MoveFocus(direction) => Ok(ProtobufPluginCommand { + name: CommandName::MoveFocus as i32, + payload: Some(Payload::MoveFocusPayload(MovePayload { + direction: Some(direction.try_into()?), + })), + }), + PluginCommand::MoveFocusOrTab(direction) => Ok(ProtobufPluginCommand { + name: CommandName::MoveFocusOrTab as i32, + payload: Some(Payload::MoveFocusOrTabPayload(MovePayload { + direction: Some(direction.try_into()?), + })), + }), + PluginCommand::Detach => Ok(ProtobufPluginCommand { + name: CommandName::Detach as i32, + payload: None, + }), + PluginCommand::EditScrollback => Ok(ProtobufPluginCommand { + name: CommandName::EditScrollback as i32, + payload: None, + }), + PluginCommand::Write(bytes) => Ok(ProtobufPluginCommand { + name: CommandName::Write as i32, + payload: Some(Payload::WritePayload(bytes)), + }), + PluginCommand::WriteChars(chars) => Ok(ProtobufPluginCommand { + name: CommandName::WriteChars as i32, + payload: Some(Payload::WriteCharsPayload(chars)), + }), + PluginCommand::ToggleTab => Ok(ProtobufPluginCommand { + name: CommandName::ToggleTab as i32, + payload: None, + }), + PluginCommand::MovePane => Ok(ProtobufPluginCommand { + name: CommandName::MovePane as i32, + payload: None, + }), + PluginCommand::MovePaneWithDirection(direction) => Ok(ProtobufPluginCommand { + name: CommandName::MovePaneWithDirection as i32, + payload: Some(Payload::MovePaneWithDirectionPayload(MovePayload { + direction: Some(direction.try_into()?), + })), + }), + PluginCommand::ClearScreen => Ok(ProtobufPluginCommand { + name: CommandName::ClearScreen as i32, + payload: None, + }), + PluginCommand::ScrollUp => Ok(ProtobufPluginCommand { + name: CommandName::ScrollUp as i32, + payload: None, + }), + PluginCommand::ScrollDown => Ok(ProtobufPluginCommand { + name: CommandName::ScrollDown as i32, + payload: None, + }), + PluginCommand::ScrollToTop => Ok(ProtobufPluginCommand { + name: CommandName::ScrollToTop as i32, + payload: None, + }), + PluginCommand::ScrollToBottom => Ok(ProtobufPluginCommand { + name: CommandName::ScrollToBottom as i32, + payload: None, + }), + PluginCommand::PageScrollUp => Ok(ProtobufPluginCommand { + name: CommandName::PageScrollUp as i32, + payload: None, + }), + PluginCommand::PageScrollDown => Ok(ProtobufPluginCommand { + name: CommandName::PageScrollDown as i32, + payload: None, + }), + PluginCommand::ToggleFocusFullscreen => Ok(ProtobufPluginCommand { + name: CommandName::ToggleFocusFullscreen as i32, + payload: None, + }), + PluginCommand::ToggleFocusNoUiFullscreen => Ok(ProtobufPluginCommand { + name: CommandName::ToggleFocusNoUiFullscreen as i32, + payload: None, + }), + PluginCommand::FocusHostSession => Ok(ProtobufPluginCommand { + name: CommandName::FocusHostSession as i32, + payload: None, + }), + PluginCommand::TogglePaneFrames => Ok(ProtobufPluginCommand { + name: CommandName::TogglePaneFrames as i32, + payload: None, + }), + PluginCommand::SetPaneFrameStyle(pane_frame_style) => Ok(ProtobufPluginCommand { + name: CommandName::SetPaneFrameStyle as i32, + payload: Some(Payload::SetPaneFrameStylePayload( + ProtobufSetPaneFrameStylePayload { + pane_frame_style: ProtobufPaneFrameStyle::try_from(pane_frame_style)? + as i32, + }, + )), + }), + PluginCommand::TogglePaneEmbedOrEject => Ok(ProtobufPluginCommand { + name: CommandName::TogglePaneEmbedOrEject as i32, + payload: None, + }), + PluginCommand::UndoRenamePane => Ok(ProtobufPluginCommand { + name: CommandName::UndoRenamePane as i32, + payload: None, + }), + PluginCommand::CloseFocus => Ok(ProtobufPluginCommand { + name: CommandName::CloseFocus as i32, + payload: None, + }), + PluginCommand::ToggleActiveTabSync => Ok(ProtobufPluginCommand { + name: CommandName::ToggleActiveTabSync as i32, + payload: None, + }), + PluginCommand::CloseFocusedTab => Ok(ProtobufPluginCommand { + name: CommandName::CloseFocusedTab as i32, + payload: None, + }), + PluginCommand::UndoRenameTab => Ok(ProtobufPluginCommand { + name: CommandName::UndoRenameTab as i32, + payload: None, + }), + PluginCommand::QuitZellij => Ok(ProtobufPluginCommand { + name: CommandName::QuitZellij as i32, + payload: None, + }), + PluginCommand::PreviousSwapLayout => Ok(ProtobufPluginCommand { + name: CommandName::PreviousSwapLayout as i32, + payload: None, + }), + PluginCommand::NextSwapLayout => Ok(ProtobufPluginCommand { + name: CommandName::NextSwapLayout as i32, + payload: None, + }), + PluginCommand::GoToTabName(tab_name) => Ok(ProtobufPluginCommand { + name: CommandName::GoToTabName as i32, + payload: Some(Payload::GoToTabNamePayload(tab_name)), + }), + PluginCommand::FocusOrCreateTab(tab_name) => Ok(ProtobufPluginCommand { + name: CommandName::FocusOrCreateTab as i32, + payload: Some(Payload::FocusOrCreateTabPayload(tab_name)), + }), + PluginCommand::GoToTab(tab_index) => Ok(ProtobufPluginCommand { + name: CommandName::GoToTab as i32, + payload: Some(Payload::GoToTabPayload(tab_index)), + }), + PluginCommand::StartOrReloadPlugin(url) => Ok(ProtobufPluginCommand { + name: CommandName::StartOrReloadPlugin as i32, + payload: Some(Payload::StartOrReloadPluginPayload(url)), + }), + PluginCommand::CloseTerminalPane(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::CloseTerminalPane as i32, + payload: Some(Payload::CloseTerminalPanePayload(pane_id)), + }), + PluginCommand::ClosePluginPane(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ClosePluginPane as i32, + payload: Some(Payload::ClosePluginPanePayload(pane_id)), + }), + PluginCommand::FocusTerminalPane( + pane_id, + should_float_if_hidden, + should_be_in_place_if_hidden, + ) => Ok(ProtobufPluginCommand { + name: CommandName::FocusTerminalPane as i32, + payload: Some(Payload::FocusTerminalPanePayload(PaneIdAndShouldFloat { + pane_id: pane_id, + should_float: should_float_if_hidden, + should_be_in_place: should_be_in_place_if_hidden, + })), + }), + PluginCommand::FocusPluginPane( + pane_id, + should_float_if_hidden, + should_be_in_place_if_hidden, + ) => Ok(ProtobufPluginCommand { + name: CommandName::FocusPluginPane as i32, + payload: Some(Payload::FocusPluginPanePayload(PaneIdAndShouldFloat { + pane_id: pane_id, + should_float: should_float_if_hidden, + should_be_in_place: should_be_in_place_if_hidden, + })), + }), + PluginCommand::RenameTerminalPane(pane_id, new_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenameTerminalPane as i32, + payload: Some(Payload::RenameTerminalPanePayload(IdAndNewName { + id: pane_id, + new_name, + })), + }), + PluginCommand::RenamePluginPane(pane_id, new_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenamePluginPane as i32, + payload: Some(Payload::RenamePluginPanePayload(IdAndNewName { + id: pane_id, + new_name, + })), + }), + PluginCommand::RenameTab(tab_index, new_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenameTab as i32, + payload: Some(Payload::RenameTabPayload(IdAndNewName { + id: tab_index, + new_name, + })), + }), + PluginCommand::ReportPanic(payload) => Ok(ProtobufPluginCommand { + name: CommandName::ReportCrash as i32, + payload: Some(Payload::ReportCrashPayload(payload)), + }), + PluginCommand::RequestPluginPermissions(permissions) => Ok(ProtobufPluginCommand { + name: CommandName::RequestPluginPermissions as i32, + payload: Some(Payload::RequestPluginPermissionPayload( + RequestPluginPermissionPayload { + permissions: permissions + .iter() + .filter_map(|p| ProtobufPermissionType::try_from(*p).ok()) + .map(|p| p as i32) + .collect(), + }, + )), + }), + PluginCommand::SwitchSession(switch_to_session) => Ok(ProtobufPluginCommand { + name: CommandName::SwitchSession as i32, + payload: Some(Payload::SwitchSessionPayload(SwitchSessionPayload { + name: switch_to_session.name, + tab_position: switch_to_session.tab_position.map(|t| t as u32), + pane_id: switch_to_session.pane_id.map(|p| p.0), + pane_id_is_plugin: switch_to_session.pane_id.map(|p| p.1), + layout: switch_to_session.layout.and_then(|l| l.try_into().ok()), + cwd: switch_to_session.cwd.map(|c| c.display().to_string()), + })), + }), + PluginCommand::OpenTerminalInPlace(cwd) => Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalInPlace as i32, + payload: Some(Payload::OpenTerminalInPlacePayload(OpenFilePayload { + file_to_open: Some(cwd.try_into()?), + floating_pane_coordinates: None, + context: vec![], // will be added in the future + })), + }), + PluginCommand::OpenFileInPlace(file_to_open, context) => Ok(ProtobufPluginCommand { + name: CommandName::OpenFileInPlace as i32, + payload: Some(Payload::OpenFileInPlacePayload(OpenFilePayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: None, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + })), + }), + 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() + .map(|(name, value)| EnvVariable { name, value }) + .collect(); + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + let cwd = cwd.display().to_string(); + Ok(ProtobufPluginCommand { + name: CommandName::RunCommand as i32, + payload: Some(Payload::RunCommandPayload(RunCommandPayload { + command_line, + env_variables, + cwd, + context, + })), + }) + }, + PluginCommand::WebRequest(url, verb, headers, body, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + let headers: Vec<_> = headers + .into_iter() + .map(|(name, value)| Header { name, value }) + .collect(); + let verb: ProtobufHttpVerb = verb.into(); + Ok(ProtobufPluginCommand { + name: CommandName::WebRequest as i32, + payload: Some(Payload::WebRequestPayload(WebRequestPayload { + url, + verb: verb as i32, + body, + headers, + context, + })), + }) + }, + PluginCommand::DeleteDeadSession(dead_session_name) => Ok(ProtobufPluginCommand { + name: CommandName::DeleteDeadSession as i32, + payload: Some(Payload::DeleteDeadSessionPayload(dead_session_name)), + }), + PluginCommand::DeleteAllDeadSessions => Ok(ProtobufPluginCommand { + name: CommandName::DeleteAllDeadSessions as i32, + payload: None, + }), + PluginCommand::RenameSession(new_session_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenameSession as i32, + payload: Some(Payload::RenameSessionPayload(new_session_name)), + }), + PluginCommand::UnblockCliPipeInput(pipe_name) => Ok(ProtobufPluginCommand { + name: CommandName::UnblockCliPipeInput as i32, + payload: Some(Payload::UnblockCliPipeInputPayload(pipe_name)), + }), + PluginCommand::BlockCliPipeInput(pipe_name) => Ok(ProtobufPluginCommand { + name: CommandName::BlockCliPipeInput as i32, + payload: Some(Payload::BlockCliPipeInputPayload(pipe_name)), + }), + PluginCommand::CliPipeOutput(pipe_name, output) => Ok(ProtobufPluginCommand { + name: CommandName::CliPipeOutput as i32, + payload: Some(Payload::CliPipeOutputPayload(CliPipeOutputPayload { + pipe_name, + output, + })), + }), + PluginCommand::MessageToPlugin(message_to_plugin) => { + let plugin_config: Vec<_> = message_to_plugin + .plugin_config + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + let message_args: Vec<_> = message_to_plugin + .message_args + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::MessageToPlugin as i32, + payload: Some(Payload::MessageToPluginPayload(MessageToPluginPayload { + plugin_url: message_to_plugin.plugin_url, + plugin_config, + message_name: message_to_plugin.message_name, + message_payload: message_to_plugin.message_payload, + message_args, + new_plugin_args: message_to_plugin.new_plugin_args.map(|m_t_p| { + ProtobufNewPluginArgs { + should_float: m_t_p.should_float, + pane_id_to_replace: m_t_p + .pane_id_to_replace + .and_then(|p_id| ProtobufPaneId::try_from(p_id).ok()), + pane_title: m_t_p.pane_title, + cwd: m_t_p.cwd.map(|cwd| cwd.display().to_string()), + skip_cache: m_t_p.skip_cache, + should_focus: m_t_p.should_focus, + } + }), + destination_plugin_id: message_to_plugin.destination_plugin_id, + floating_pane_coordinates: message_to_plugin + .floating_pane_coordinates + .and_then(|f| f.try_into().ok()), + })), + }) + }, + PluginCommand::DisconnectOtherClients => Ok(ProtobufPluginCommand { + name: CommandName::DisconnectOtherClients as i32, + payload: None, + }), + PluginCommand::KillSessions(session_names) => Ok(ProtobufPluginCommand { + name: CommandName::KillSessions as i32, + payload: Some(Payload::KillSessionsPayload(KillSessionsPayload { + session_names, + })), + }), + PluginCommand::ScanHostFolder(folder_to_scan) => Ok(ProtobufPluginCommand { + name: CommandName::ScanHostFolder as i32, + payload: Some(Payload::ScanHostFolderPayload( + folder_to_scan.display().to_string(), + )), + }), + PluginCommand::WatchFilesystem => Ok(ProtobufPluginCommand { + name: CommandName::WatchFilesystem as i32, + payload: None, + }), + PluginCommand::ListWindowsVolumes => Ok(ProtobufPluginCommand { + name: CommandName::ListWindowsVolumes as i32, + payload: None, + }), + PluginCommand::GetSessionList => Ok(ProtobufPluginCommand { + name: CommandName::GetSessionList as i32, + payload: Some(Payload::GetSessionListPayload( + ProtobufGetSessionListPayload {}, + )), + }), + PluginCommand::KillSessionsAndReply(session_names) => Ok(ProtobufPluginCommand { + name: CommandName::KillSessionsAndReply as i32, + payload: Some(Payload::KillSessionsAndReplyPayload(KillSessionsPayload { + session_names, + })), + }), + PluginCommand::DeleteDeadSessionAndReply(dead_session_name) => { + Ok(ProtobufPluginCommand { + name: CommandName::DeleteDeadSessionAndReply as i32, + payload: Some(Payload::DeleteDeadSessionAndReplyPayload(dead_session_name)), + }) + }, + PluginCommand::DeleteAllDeadSessionsAndReply => Ok(ProtobufPluginCommand { + name: CommandName::DeleteAllDeadSessionsAndReply as i32, + payload: None, + }), + PluginCommand::SetSoftKeyboard(on) => Ok(ProtobufPluginCommand { + name: CommandName::SetSoftKeyboard as i32, + payload: Some(Payload::SetSoftKeyboardPayload( + ProtobufSetSoftKeyboardPayload { on }, + )), + }), + PluginCommand::SetTabFit { tab_id, fit } => { + let (pane_id, size) = match fit { + Some((pane_id, size)) => { + (Some(pane_id.try_into()?), Some(size_to_protobuf(size))) + }, + None => (None, None), + }; + Ok(ProtobufPluginCommand { + name: CommandName::SetTabFit as i32, + payload: Some(Payload::SetTabFitPayload(ProtobufSetTabFitPayload { + tab_id: tab_id as u32, + pane_id, + size, + })), + }) + }, + PluginCommand::ExitMobileMode => Ok(ProtobufPluginCommand { + name: CommandName::ExitMobileMode as i32, + payload: None, + }), + PluginCommand::DumpSessionLayout { tab_index } => Ok(ProtobufPluginCommand { + name: CommandName::DumpSessionLayout as i32, + payload: tab_index.map(|idx| { + Payload::DumpSessionLayoutPayload(DumpSessionLayoutPayload { + tab_index: Some(idx as u32), + }) + }), + }), + PluginCommand::CloseSelf => Ok(ProtobufPluginCommand { + name: CommandName::CloseSelf as i32, + payload: None, + }), + PluginCommand::NewTabsWithLayoutInfo(new_tabs_with_layout_info_payload) => { + Ok(ProtobufPluginCommand { + name: CommandName::NewTabsWithLayoutInfo as i32, + payload: Some(Payload::NewTabsWithLayoutInfoPayload( + NewTabsWithLayoutInfoPayload { + layout_info: new_tabs_with_layout_info_payload.try_into().ok(), + }, + )), + }) + }, + PluginCommand::Reconfigure(config, write_to_disk) => Ok(ProtobufPluginCommand { + name: CommandName::Reconfigure as i32, + payload: Some(Payload::ReconfigurePayload(ReconfigurePayload { + config, + write_to_disk, + })), + }), + 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, + should_focus_pane, + ) => 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, + should_focus_pane, + })), + }), + PluginCommand::OpenCommandPaneBackground(command_to_run, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneBackground as i32, + payload: Some(Payload::OpenCommandPaneBackgroundPayload( + OpenCommandPanePayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: None, + context, + }, + )), + }) + }, + PluginCommand::RerunCommandPane(terminal_pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::RerunCommandPane as i32, + payload: Some(Payload::RerunCommandPanePayload(RerunCommandPanePayload { + terminal_pane_id, + })), + }), + PluginCommand::ResizePaneIdWithDirection(resize, pane_id) => { + Ok(ProtobufPluginCommand { + name: CommandName::ResizePaneIdWithDirection as i32, + payload: Some(Payload::ResizePaneIdWithDirectionPayload( + ResizePaneIdWithDirectionPayload { + resize: Some(resize.try_into()?), + pane_id: Some(pane_id.try_into()?), + }, + )), + }) + }, + PluginCommand::EditScrollbackForPaneWithId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::EditScrollbackForPaneWithId as i32, + payload: Some(Payload::EditScrollbackForPaneWithIdPayload( + EditScrollbackForPaneWithIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::GetPaneScrollback { + pane_id, + get_full_scrollback, + } => Ok(ProtobufPluginCommand { + name: CommandName::GetPaneScrollback as i32, + payload: Some(Payload::GetPaneScrollbackPayload( + GetPaneScrollbackPayload { + pane_id: Some(pane_id.try_into()?), + get_full_scrollback, + }, + )), + }), + PluginCommand::WriteToPaneId(bytes_to_write, pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::WriteToPaneId as i32, + payload: Some(Payload::WriteToPaneIdPayload(WriteToPaneIdPayload { + bytes_to_write, + pane_id: Some(pane_id.try_into()?), + })), + }), + PluginCommand::WriteCharsToPaneId(chars_to_write, pane_id) => { + Ok(ProtobufPluginCommand { + name: CommandName::WriteCharsToPaneId as i32, + payload: Some(Payload::WriteCharsToPaneIdPayload( + WriteCharsToPaneIdPayload { + chars_to_write, + pane_id: Some(pane_id.try_into()?), + }, + )), + }) + }, + PluginCommand::SendSigintToPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::SendSigintToPaneId as i32, + payload: Some(Payload::SendSigintToPaneIdPayload(pane_id.try_into()?)), + }), + PluginCommand::SetShadowFocus(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::SetShadowFocus as i32, + payload: Some(Payload::SetShadowFocusPayload(pane_id.try_into()?)), + }), + PluginCommand::SendSigkillToPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::SendSigkillToPaneId as i32, + payload: Some(Payload::SendSigkillToPaneIdPayload(pane_id.try_into()?)), + }), + PluginCommand::GetPanePid { pane_id } => Ok(ProtobufPluginCommand { + name: CommandName::GetPanePid as i32, + payload: Some(Payload::GetPanePidPayload(GetPanePidPayload { + pane_id: Some(pane_id.try_into()?), + })), + }), + PluginCommand::GetPaneRunningCommand { pane_id } => Ok(ProtobufPluginCommand { + name: CommandName::GetPaneRunningCommand as i32, + payload: Some(Payload::GetPaneRunningCommandPayload( + ProtobufGetPaneRunningCommandPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::GetPaneCwd { pane_id } => Ok(ProtobufPluginCommand { + name: CommandName::GetPaneCwd as i32, + payload: Some(Payload::GetPaneCwdPayload(ProtobufGetPaneCwdPayload { + pane_id: Some(pane_id.try_into()?), + })), + }), + PluginCommand::OverrideLayout( + layout_info, + retain_existing_terminal_panes, + retain_existing_plugin_panes, + apply_only_to_active_tab, + context, + ) => Ok(ProtobufPluginCommand { + name: CommandName::OverrideLayout as i32, + payload: Some(Payload::OverrideLayoutPayload(OverrideLayoutPayload { + layout_info: layout_info.try_into().ok(), + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + retain_existing_terminal_panes, + retain_existing_plugin_panes, + apply_only_to_active_tab, + })), + }), + PluginCommand::SaveLayout { + layout_name, + layout_kdl, + overwrite, + } => Ok(ProtobufPluginCommand { + name: CommandName::SaveLayout as i32, + payload: Some(Payload::SaveLayoutPayload(SaveLayoutPayload { + layout_name, + layout_kdl, + overwrite, + })), + }), + PluginCommand::DeleteLayout { layout_name } => Ok(ProtobufPluginCommand { + name: CommandName::DeleteLayout as i32, + payload: Some(Payload::DeleteLayoutPayload(DeleteLayoutPayload { + layout_name, + })), + }), + PluginCommand::RenameLayout { + old_layout_name, + new_layout_name, + } => Ok(ProtobufPluginCommand { + name: CommandName::RenameLayout as i32, + payload: Some(Payload::RenameLayoutPayload(RenameLayoutPayload { + old_layout_name, + new_layout_name, + })), + }), + PluginCommand::EditLayout { + layout_name, + context, + } => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::EditLayout as i32, + payload: Some(Payload::EditLayoutPayload(EditLayoutPayload { + layout_name, + context, + })), + }) + }, + PluginCommand::MovePaneWithPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::MovePaneWithPaneId as i32, + payload: Some(Payload::MovePaneWithPaneIdPayload( + MovePaneWithPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::MovePaneWithPaneIdInDirection(pane_id, direction) => { + Ok(ProtobufPluginCommand { + name: CommandName::MovePaneWithPaneIdInDirection as i32, + payload: Some(Payload::MovePaneWithPaneIdInDirectionPayload( + MovePaneWithPaneIdInDirectionPayload { + pane_id: Some(pane_id.try_into()?), + direction: Some(direction.try_into()?), + }, + )), + }) + }, + PluginCommand::ClearScreenForPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ClearScreenForPaneId as i32, + payload: Some(Payload::ClearScreenForPaneIdPayload( + ClearScreenForPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::ScrollUpInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ScrollUpInPaneId as i32, + payload: Some(Payload::ScrollUpInPaneIdPayload(ScrollUpInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + })), + }), + PluginCommand::ScrollDownInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ScrollDownInPaneId as i32, + payload: Some(Payload::ScrollDownInPaneIdPayload( + ScrollDownInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::ScrollToTopInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ScrollToTopInPaneId as i32, + payload: Some(Payload::ScrollToTopInPaneIdPayload( + ScrollToTopInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::ScrollToBottomInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ScrollToBottomInPaneId as i32, + payload: Some(Payload::ScrollToBottomInPaneIdPayload( + ScrollToBottomInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::PageScrollUpInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::PageScrollUpInPaneId as i32, + payload: Some(Payload::PageScrollUpInPaneIdPayload( + PageScrollUpInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::PageScrollDownInPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::PageScrollDownInPaneId as i32, + payload: Some(Payload::PageScrollDownInPaneIdPayload( + PageScrollDownInPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::TogglePaneIdFullscreen(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::TogglePaneIdFullscreen as i32, + payload: Some(Payload::TogglePaneIdFullscreenPayload( + TogglePaneIdFullscreenPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::TogglePaneEmbedOrEjectForPaneId(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::TogglePaneEmbedOrEjectForPaneId as i32, + payload: Some(Payload::TogglePaneEmbedOrEjectForPaneIdPayload( + TogglePaneEmbedOrEjectForPaneIdPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::CloseTabWithIndex(tab_index) => Ok(ProtobufPluginCommand { + name: CommandName::CloseTabWithIndex as i32, + payload: Some(Payload::CloseTabWithIndexPayload( + CloseTabWithIndexPayload { + tab_index: tab_index as u32, + }, + )), + }), + PluginCommand::BreakPanesToNewTab( + pane_ids, + new_tab_name, + should_change_focus_to_new_tab, + ) => Ok(ProtobufPluginCommand { + name: CommandName::BreakPanesToNewTab as i32, + payload: Some(Payload::BreakPanesToNewTabPayload( + BreakPanesToNewTabPayload { + pane_ids: pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + should_change_focus_to_new_tab, + new_tab_name, + }, + )), + }), + PluginCommand::BreakPanesToTabWithIndex( + pane_ids, + tab_index, + should_change_focus_to_target_tab, + ) => Ok(ProtobufPluginCommand { + name: CommandName::BreakPanesToTabWithIndex as i32, + payload: Some(Payload::BreakPanesToTabWithIndexPayload( + BreakPanesToTabWithIndexPayload { + pane_ids: pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + tab_index: tab_index as u32, + should_change_focus_to_target_tab, + }, + )), + }), + PluginCommand::SwitchTabToId(tab_id) => Ok(ProtobufPluginCommand { + name: CommandName::SwitchTabToId as i32, + payload: Some(Payload::SwitchTabToIdPayload(SwitchTabToIdPayload { + tab_id, + })), + }), + PluginCommand::GoToTabWithId(tab_id) => Ok(ProtobufPluginCommand { + name: CommandName::GoToTabWithId as i32, + payload: Some(Payload::GoToTabWithIdPayload(GoToTabWithIdPayload { + tab_id, + })), + }), + PluginCommand::CloseTabWithId(tab_id) => Ok(ProtobufPluginCommand { + name: CommandName::CloseTabWithId as i32, + payload: Some(Payload::CloseTabWithIdPayload(CloseTabWithIdPayload { + tab_id, + })), + }), + PluginCommand::RenameTabWithId(tab_id, new_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenameTabWithId as i32, + payload: Some(Payload::RenameTabWithIdPayload(RenameTabWithIdPayload { + tab_id, + new_name, + })), + }), + PluginCommand::BreakPanesToTabWithId( + pane_ids, + tab_id, + should_change_focus_to_target_tab, + ) => Ok(ProtobufPluginCommand { + name: CommandName::BreakPanesToTabWithId as i32, + payload: Some(Payload::BreakPanesToTabWithIdPayload( + BreakPanesToTabWithIdPayload { + pane_ids: pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + tab_id, + should_change_focus_to_target_tab, + }, + )), + }), + PluginCommand::ReloadPlugin(plugin_id) => Ok(ProtobufPluginCommand { + name: CommandName::ReloadPlugin as i32, + payload: Some(Payload::ReloadPluginPayload(ReloadPluginPayload { + plugin_id, + })), + }), + PluginCommand::LoadNewPlugin { + url, + config, + load_in_background, + skip_plugin_cache, + } => Ok(ProtobufPluginCommand { + name: CommandName::LoadNewPlugin as i32, + payload: Some(Payload::LoadNewPluginPayload(LoadNewPluginPayload { + plugin_url: url, + plugin_config: config + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + should_skip_plugin_cache: skip_plugin_cache, + should_load_plugin_in_background: load_in_background, + })), + }), + PluginCommand::RebindKeys { + keys_to_rebind, + keys_to_unbind, + write_config_to_disk, + } => Ok(ProtobufPluginCommand { + name: CommandName::RebindKeys as i32, + payload: Some(Payload::RebindKeysPayload(RebindKeysPayload { + keys_to_rebind: keys_to_rebind + .into_iter() + .filter_map(|k| k.try_into().ok()) + .collect(), + keys_to_unbind: keys_to_unbind + .into_iter() + .filter_map(|k| k.try_into().ok()) + .collect(), + write_config_to_disk, + })), + }), + PluginCommand::ListClients => Ok(ProtobufPluginCommand { + name: CommandName::ListClients as i32, + payload: None, + }), + PluginCommand::ChangeHostFolder(new_host_folder) => Ok(ProtobufPluginCommand { + name: CommandName::ChangeHostFolder as i32, + payload: Some(Payload::ChangeHostFolderPayload(ChangeHostFolderPayload { + new_host_folder: new_host_folder.display().to_string(), // TODO: not accurate? + })), + }), + PluginCommand::SetFloatingPanePinned(pane_id, should_be_pinned) => { + Ok(ProtobufPluginCommand { + name: CommandName::SetFloatingPanePinned as i32, + payload: Some(Payload::SetFloatingPanePinnedPayload( + SetFloatingPanePinnedPayload { + pane_id: pane_id.try_into().ok(), + should_be_pinned, + }, + )), + }) + }, + PluginCommand::StackPanes(pane_ids) => Ok(ProtobufPluginCommand { + name: CommandName::StackPanes as i32, + payload: Some(Payload::StackPanesPayload(StackPanesPayload { + pane_ids: pane_ids + .into_iter() + .filter_map(|p_id| p_id.try_into().ok()) + .collect(), + })), + }), + PluginCommand::ChangeFloatingPanesCoordinates( + pane_ids_and_floating_panes_coordinates, + ) => Ok(ProtobufPluginCommand { + name: CommandName::ChangeFloatingPanesCoordinates as i32, + payload: Some(Payload::ChangeFloatingPanesCoordinatesPayload( + ChangeFloatingPanesCoordinatesPayload { + pane_ids_and_floating_panes_coordinates: + pane_ids_and_floating_panes_coordinates + .into_iter() + .filter_map(|(p_id, floating_pane_coordinates)| { + Some(PaneIdAndFloatingPaneCoordinates { + pane_id: Some(p_id.try_into().ok()?), + floating_pane_coordinates: Some( + floating_pane_coordinates.try_into().ok()?, + ), + }) + }) + .collect(), + }, + )), + }), + PluginCommand::TogglePaneBorderless(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::TogglePaneBorderless as i32, + payload: Some(Payload::TogglePaneBorderlessPayload( + TogglePaneBorderlessPayload { + pane_id: Some(pane_id.try_into()?), + }, + )), + }), + PluginCommand::SetPaneBorderless(pane_id, borderless) => Ok(ProtobufPluginCommand { + name: CommandName::SetPaneBorderless as i32, + payload: Some(Payload::SetPaneBorderlessPayload( + SetPaneBorderlessPayload { + pane_id: Some(pane_id.try_into()?), + borderless, + }, + )), + }), + PluginCommand::OpenCommandPaneNearPlugin(command_to_run, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneNearPlugin as i32, + payload: Some(Payload::OpenCommandPaneNearPluginPayload( + OpenCommandPaneNearPluginPayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: None, + context, + }, + )), + }) + }, + PluginCommand::OpenCommandPaneFloatingNearPlugin( + command_to_run, + floating_pane_coordinates, + context, + ) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneFloatingNearPlugin as i32, + payload: Some(Payload::OpenCommandPaneFloatingNearPluginPayload( + OpenCommandPaneFloatingNearPluginPayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context, + }, + )), + }) + }, + PluginCommand::OpenTerminalNearPlugin(cwd) => Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalNearPlugin as i32, + payload: Some(Payload::OpenTerminalNearPluginPayload( + OpenTerminalNearPluginPayload { + file_to_open: Some(cwd.try_into()?), + context: vec![], // will be added in the future + }, + )), + }), + PluginCommand::OpenTerminalFloatingNearPlugin(cwd, floating_pane_coordinates) => { + Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalFloatingNearPlugin as i32, + payload: Some(Payload::OpenTerminalFloatingNearPluginPayload( + OpenTerminalFloatingNearPluginPayload { + file_to_open: Some(cwd.try_into()?), + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context: vec![], // will be added in the future + }, + )), + }) + }, + PluginCommand::OpenTerminalInPlaceOfPlugin(cwd, close_plugin_after_replace) => { + Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalInPlaceOfPlugin as i32, + payload: Some(Payload::OpenTerminalInPlaceOfPluginPayload( + OpenTerminalInPlaceOfPluginPayload { + file_to_open: Some(cwd.try_into()?), + close_plugin_after_replace, + context: vec![], // will be added in the future + }, + )), + }) + }, + PluginCommand::OpenCommandPaneInPlaceOfPlugin( + command_to_run, + close_plugin_after_replace, + context, + ) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneInPlaceOfPlugin as i32, + payload: Some(Payload::OpenCommandPaneInPlaceOfPluginPayload( + OpenCommandPaneInPlaceOfPluginPayload { + command_to_run: Some(command_to_run.try_into()?), + close_plugin_after_replace, + context, + }, + )), + }) + }, + PluginCommand::OpenFileNearPlugin(file_to_open, context) => Ok(ProtobufPluginCommand { + name: CommandName::OpenFileNearPlugin as i32, + payload: Some(Payload::OpenFileNearPluginPayload( + OpenFileNearPluginPayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: None, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + }, + )), + }), + PluginCommand::OpenFileFloatingNearPlugin( + file_to_open, + floating_pane_coordinates, + context, + ) => Ok(ProtobufPluginCommand { + name: CommandName::OpenFileFloatingNearPlugin as i32, + payload: Some(Payload::OpenFileFloatingNearPluginPayload( + OpenFileFloatingNearPluginPayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + }, + )), + }), + PluginCommand::OpenFileInPlaceOfPlugin( + file_to_open, + close_plugin_after_replace, + context, + ) => Ok(ProtobufPluginCommand { + name: CommandName::OpenFileInPlaceOfPlugin as i32, + payload: Some(Payload::OpenFileInPlaceOfPluginPayload( + OpenFileInPlaceOfPluginPayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: None, + close_plugin_after_replace, + context: context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + }, + )), + }), + PluginCommand::GroupAndUngroupPanes( + panes_to_group, + panes_to_ungroup, + for_all_clients, + ) => Ok(ProtobufPluginCommand { + name: CommandName::GroupAndUngroupPanes as i32, + payload: Some(Payload::GroupAndUngroupPanesPayload( + GroupAndUngroupPanesPayload { + pane_ids_to_group: panes_to_group + .iter() + .filter_map(|&p| p.try_into().ok()) + .collect(), + pane_ids_to_ungroup: panes_to_ungroup + .iter() + .filter_map(|&p| p.try_into().ok()) + .collect(), + for_all_clients, + }, + )), + }), + PluginCommand::StartWebServer => Ok(ProtobufPluginCommand { + name: CommandName::StartWebServer as i32, + payload: None, + }), + PluginCommand::StopWebServer => Ok(ProtobufPluginCommand { + name: CommandName::StopWebServer as i32, + payload: None, + }), + PluginCommand::QueryWebServerStatus => Ok(ProtobufPluginCommand { + name: CommandName::QueryWebServerStatus as i32, + payload: None, + }), + PluginCommand::HighlightAndUnhighlightPanes( + panes_to_highlight, + panes_to_unhighlight, + ) => Ok(ProtobufPluginCommand { + name: CommandName::HighlightAndUnhighlightPanes as i32, + payload: Some(Payload::HighlightAndUnhighlightPanesPayload( + HighlightAndUnhighlightPanesPayload { + pane_ids_to_highlight: panes_to_highlight + .iter() + .filter_map(|&p| p.try_into().ok()) + .collect(), + pane_ids_to_unhighlight: panes_to_unhighlight + .iter() + .filter_map(|&p| p.try_into().ok()) + .collect(), + }, + )), + }), + PluginCommand::CloseMultiplePanes(pane_ids) => Ok(ProtobufPluginCommand { + name: CommandName::CloseMultiplePanes as i32, + payload: Some(Payload::CloseMultiplePanesPayload( + CloseMultiplePanesPayload { + pane_ids: pane_ids.iter().filter_map(|&p| p.try_into().ok()).collect(), + }, + )), + }), + PluginCommand::FloatMultiplePanes(pane_ids) => Ok(ProtobufPluginCommand { + name: CommandName::FloatMultiplePanes as i32, + payload: Some(Payload::FloatMultiplePanesPayload( + FloatMultiplePanesPayload { + pane_ids: pane_ids.iter().filter_map(|&p| p.try_into().ok()).collect(), + }, + )), + }), + PluginCommand::EmbedMultiplePanes(pane_ids) => Ok(ProtobufPluginCommand { + name: CommandName::EmbedMultiplePanes as i32, + payload: Some(Payload::EmbedMultiplePanesPayload( + EmbedMultiplePanesPayload { + pane_ids: pane_ids.iter().filter_map(|&p| p.try_into().ok()).collect(), + }, + )), + }), + PluginCommand::ShareCurrentSession => Ok(ProtobufPluginCommand { + name: CommandName::ShareCurrentSession as i32, + payload: None, + }), + PluginCommand::StopSharingCurrentSession => Ok(ProtobufPluginCommand { + name: CommandName::StopSharingCurrentSession as i32, + payload: None, + }), + PluginCommand::SetSelfMouseSelectionSupport(support_mouse_selection) => { + Ok(ProtobufPluginCommand { + name: CommandName::SetSelfMouseSelectionSupport as i32, + payload: Some(Payload::SetSelfMouseSelectionSupportPayload( + SetSelfMouseSelectionSupportPayload { + support_mouse_selection, + }, + )), + }) + }, + PluginCommand::GenerateWebLoginToken(token_label, read_only) => { + Ok(ProtobufPluginCommand { + name: CommandName::GenerateWebLoginToken as i32, + payload: Some(Payload::GenerateWebLoginTokenPayload( + GenerateWebLoginTokenPayload { + token_label, + read_only: Some(read_only), + }, + )), + }) + }, + PluginCommand::RevokeWebLoginToken(token_label) => Ok(ProtobufPluginCommand { + name: CommandName::RevokeWebLoginToken as i32, + payload: Some(Payload::RevokeWebLoginTokenPayload( + RevokeWebLoginTokenPayload { token_label }, + )), + }), + PluginCommand::ListWebLoginTokens => Ok(ProtobufPluginCommand { + name: CommandName::ListWebLoginTokens as i32, + payload: None, + }), + PluginCommand::RevokeAllWebLoginTokens => Ok(ProtobufPluginCommand { + name: CommandName::RevokeAllWebLoginTokens as i32, + payload: None, + }), + PluginCommand::RenameWebLoginToken(old_name, new_name) => Ok(ProtobufPluginCommand { + name: CommandName::RenameWebLoginToken as i32, + payload: Some(Payload::RenameWebLoginTokenPayload( + RenameWebLoginTokenPayload { old_name, new_name }, + )), + }), + PluginCommand::InterceptKeyPresses => Ok(ProtobufPluginCommand { + name: CommandName::InterceptKeyPresses as i32, + payload: None, + }), + PluginCommand::ClearKeyPressesIntercepts => Ok(ProtobufPluginCommand { + name: CommandName::ClearKeyPressesIntercepts as i32, + payload: None, + }), + PluginCommand::ReplacePaneWithExistingPane( + pane_id_to_replace, + existing_pane_id, + suppress_replaced_pane, + ) => Ok(ProtobufPluginCommand { + name: CommandName::ReplacePaneWithExistingPane as i32, + payload: Some(Payload::ReplacePaneWithExistingPanePayload( + ReplacePaneWithExistingPanePayload { + pane_id_to_replace: ProtobufPaneId::try_from(pane_id_to_replace).ok(), + existing_pane_id: ProtobufPaneId::try_from(existing_pane_id).ok(), + suppress_replaced_pane, + }, + )), + }), + PluginCommand::RunAction(action, context) => { + let protobuf_action = ProtobufAction::try_from(action) + .map_err(|_| "Failed to convert action to protobuf")?; + + let context_items: Vec<ContextItem> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + + Ok(ProtobufPluginCommand { + name: CommandName::RunAction as i32, + payload: Some(Payload::RunActionPayload(RunActionPayload { + action: Some(protobuf_action), + context: context_items, + })), + }) + }, + PluginCommand::CopyToClipboard(text) => Ok(ProtobufPluginCommand { + name: CommandName::CopyToClipboard as i32, + payload: Some(Payload::CopyToClipboardPayload(CopyToClipboardPayload { + text, + })), + }), + PluginCommand::GenerateRandomName => Ok(ProtobufPluginCommand { + name: CommandName::GenerateRandomName as i32, + payload: Some(Payload::GenerateRandomNamePayload( + GenerateRandomNamePayload {}, + )), + }), + PluginCommand::DumpLayout(layout_name) => Ok(ProtobufPluginCommand { + name: CommandName::DumpLayout as i32, + payload: Some(Payload::DumpLayoutPayload(DumpLayoutPayload { + layout_name, + })), + }), + PluginCommand::ParseLayout(layout_string) => Ok(ProtobufPluginCommand { + name: CommandName::ParseLayout as i32, + payload: Some(Payload::ParseLayoutPayload(ParseLayoutPayload { + layout_string, + })), + }), + PluginCommand::GetLayoutDir => Ok(ProtobufPluginCommand { + name: CommandName::GetLayoutDir as i32, + payload: Some(Payload::GetLayoutDirPayload(GetLayoutDirPayload {})), + }), + PluginCommand::GetFocusedPaneInfo => Ok(ProtobufPluginCommand { + name: CommandName::GetFocusedPaneInfo as i32, + payload: Some(Payload::GetFocusedPaneInfoPayload( + GetFocusedPaneInfoPayload {}, + )), + }), + PluginCommand::SaveSession => Ok(ProtobufPluginCommand { + name: CommandName::SaveSession as i32, + payload: Some(Payload::SaveSessionPayload(SaveSessionPayload {})), + }), + PluginCommand::CurrentSessionLastSavedTime => Ok(ProtobufPluginCommand { + name: CommandName::CurrentSessionLastSavedTime as i32, + payload: Some(Payload::CurrentSessionLastSavedTimePayload( + CurrentSessionLastSavedTimePayload {}, + )), + }), + PluginCommand::GetPaneInfo(pane_id) => { + let protobuf_pane_id: ProtobufPaneId = pane_id.try_into()?; + Ok(ProtobufPluginCommand { + name: CommandName::GetPaneInfo as i32, + payload: Some(Payload::GetPaneInfoPayload(GetPaneInfoPayload { + pane_id: Some(protobuf_pane_id), + })), + }) + }, + PluginCommand::GetTabInfo(tab_id) => Ok(ProtobufPluginCommand { + name: CommandName::GetTabInfo as i32, + payload: Some(Payload::GetTabInfoPayload(GetTabInfoPayload { + tab_id: tab_id as u64, + })), + }), + PluginCommand::GetSessionEnvironmentVariables => { + let payload = ProtobufGetSessionEnvironmentVariablesPayload {}; + Ok(ProtobufPluginCommand { + name: CommandName::GetSessionEnvironmentVariables as i32, + payload: Some(Payload::GetSessionEnvironmentVariablesPayload(payload)), + }) + }, + PluginCommand::OpenCommandPaneInNewTab(command_to_run, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneInNewTab as i32, + payload: Some(Payload::OpenCommandPaneInNewTabPayload( + OpenCommandPanePayload { + command_to_run: Some(command_to_run.try_into()?), + floating_pane_coordinates: None, + context, + }, + )), + }) + }, + PluginCommand::OpenPluginPaneInNewTab { + plugin_url, + configuration, + context, + } => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + let configuration: std::collections::HashMap<String, String> = + configuration.into_iter().collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenPluginPaneInNewTab as i32, + payload: Some(Payload::OpenPluginPaneInNewTabPayload( + ProtobufOpenPluginPaneInNewTabPayload { + plugin_url, + configuration, + context, + }, + )), + }) + }, + PluginCommand::OpenEditorPaneInNewTab(file_to_open, context) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenEditorPaneInNewTab as i32, + payload: Some(Payload::OpenEditorPaneInNewTabPayload(OpenFilePayload { + file_to_open: Some(file_to_open.try_into()?), + floating_pane_coordinates: None, + context, + })), + }) + }, + PluginCommand::OpenCommandPaneInPlaceOfPaneId( + pane_id, + command_to_run, + close_replaced_pane, + context, + ) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenCommandPaneInPlaceOfPaneId as i32, + payload: Some(Payload::OpenCommandPaneInPlaceOfPaneIdPayload( + OpenCommandPaneInPlaceOfPaneIdPayload { + pane_id_to_replace: Some(pane_id.try_into()?), + command_to_run: Some(command_to_run.try_into()?), + close_replaced_pane, + context, + }, + )), + }) + }, + PluginCommand::OpenTerminalPaneInPlaceOfPaneId(pane_id, cwd, close_replaced_pane) => { + Ok(ProtobufPluginCommand { + name: CommandName::OpenTerminalPaneInPlaceOfPaneId as i32, + payload: Some(Payload::OpenTerminalPaneInPlaceOfPaneIdPayload( + OpenTerminalPaneInPlaceOfPaneIdPayload { + pane_id_to_replace: Some(pane_id.try_into()?), + cwd: Some(cwd.try_into()?), + close_replaced_pane, + }, + )), + }) + }, + PluginCommand::OpenEditPaneInPlaceOfPaneId( + pane_id, + file_to_open, + close_replaced_pane, + context, + ) => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenEditPaneInPlaceOfPaneId as i32, + payload: Some(Payload::OpenEditPaneInPlaceOfPaneIdPayload( + OpenEditPaneInPlaceOfPaneIdPayload { + pane_id_to_replace: Some(pane_id.try_into()?), + file_to_open: Some(file_to_open.try_into()?), + close_replaced_pane, + context, + }, + )), + }) + }, + PluginCommand::HideFloatingPanes { tab_id } => Ok(ProtobufPluginCommand { + name: CommandName::HideFloatingPanes as i32, + payload: Some(Payload::HideFloatingPanesPayload( + ProtobufHideFloatingPanesPayload { + tab_id: tab_id.map(|id| id as u32), + }, + )), + }), + PluginCommand::ShowFloatingPanes { tab_id } => Ok(ProtobufPluginCommand { + name: CommandName::ShowFloatingPanes as i32, + payload: Some(Payload::ShowFloatingPanesPayload( + ProtobufShowFloatingPanesPayload { + tab_id: tab_id.map(|id| id as u32), + }, + )), + }), + PluginCommand::SetPaneColor(pane_id, fg, bg) => Ok(ProtobufPluginCommand { + name: CommandName::SetPaneColor as i32, + payload: Some(Payload::SetPaneColorPayload(SetPaneColorPayload { + pane_id: Some(pane_id.try_into()?), + fg, + bg, + })), + }), + PluginCommand::SetPaneRegexHighlights(pane_id, highlights) => { + Ok(ProtobufPluginCommand { + name: CommandName::SetPaneRegexHighlights as i32, + payload: Some(Payload::SetPaneRegexHighlightsPayload( + SetPaneRegexHighlightsPayload { + pane_id: pane_id.try_into().ok(), + highlights: highlights + .into_iter() + .map(|h| { + let style_variant = match h.style { + HighlightStyle::Emphasis0 => { + ProtobufHighlightStyleVariant::Emphasis0(true) + }, + HighlightStyle::Emphasis1 => { + ProtobufHighlightStyleVariant::Emphasis1(true) + }, + HighlightStyle::Emphasis2 => { + ProtobufHighlightStyleVariant::Emphasis2(true) + }, + HighlightStyle::Emphasis3 => { + ProtobufHighlightStyleVariant::Emphasis3(true) + }, + HighlightStyle::CustomRgb { fg, bg } => { + ProtobufHighlightStyleVariant::CustomRgb( + ProtobufCustomRgbHighlight { + fg_r: fg.map(|(r, _, _)| r as u32), + fg_g: fg.map(|(_, g, _)| g as u32), + fg_b: fg.map(|(_, _, b)| b as u32), + bg_r: bg.map(|(r, _, _)| r as u32), + bg_g: bg.map(|(_, g, _)| g as u32), + bg_b: bg.map(|(_, _, b)| b as u32), + }, + ) + }, + HighlightStyle::CustomIndex { fg, bg } => { + ProtobufHighlightStyleVariant::CustomIndex( + ProtobufCustomIndexHighlight { + fg: fg.map(|v| v as u32), + bg: bg.map(|v| v as u32), + }, + ) + }, + HighlightStyle::BackgroundEmphasis0 => { + ProtobufHighlightStyleVariant::BackgroundEmphasis0(true) + }, + HighlightStyle::BackgroundEmphasis1 => { + ProtobufHighlightStyleVariant::BackgroundEmphasis1(true) + }, + HighlightStyle::BackgroundEmphasis2 => { + ProtobufHighlightStyleVariant::BackgroundEmphasis2(true) + }, + HighlightStyle::BackgroundEmphasis3 => { + ProtobufHighlightStyleVariant::BackgroundEmphasis3(true) + }, + HighlightStyle::None => { + ProtobufHighlightStyleVariant::None(true) + }, + }; + ProtobufRegexHighlight { + pattern: h.pattern, + style: Some(ProtobufHighlightStyle { + style: Some(style_variant), + }), + context: h + .context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(), + on_hover: h.on_hover, + bold: h.bold, + italic: h.italic, + underline: h.underline, + tooltip_text: h.tooltip_text, + layer: match h.layer { + HighlightLayer::Hint => { + ProtobufHighlightLayer::Hint as i32 + }, + HighlightLayer::Tool => { + ProtobufHighlightLayer::Tool as i32 + }, + HighlightLayer::ActionFeedback => { + ProtobufHighlightLayer::ActionFeedback as i32 + }, + }, + } + }) + .collect(), + }, + )), + }) + }, + PluginCommand::ClearPaneHighlights(pane_id) => Ok(ProtobufPluginCommand { + name: CommandName::ClearPaneHighlights as i32, + payload: Some(Payload::ClearPaneHighlightsPayload( + ClearPaneHighlightsPayload { + pane_id: pane_id.try_into().ok(), + }, + )), + }), + PluginCommand::OpenPluginPaneFloating { + plugin_url, + configuration, + floating_pane_coordinates, + context, + } => { + let context: Vec<_> = context + .into_iter() + .map(|(name, value)| ContextItem { name, value }) + .collect(); + let configuration: std::collections::HashMap<String, String> = + configuration.into_iter().collect(); + Ok(ProtobufPluginCommand { + name: CommandName::OpenPluginPaneFloating as i32, + payload: Some(Payload::OpenPluginPaneFloatingPayload( + OpenPluginPaneFloatingPayload { + plugin_url, + configuration, + floating_pane_coordinates: floating_pane_coordinates.map(|f| f.into()), + context, + }, + )), + }) + }, + } + } +} + +// Conversion implementations for tab creation response types +use crate::data::{ + BreakPanesToNewTabResponse, BreakPanesToTabWithIdResponse, BreakPanesToTabWithIndexResponse, + FocusOrCreateTabResponse, NewTabResponse, NewTabUnfocusedResponse, NewTabsResponse, + NewTiledPaneInTabResponse, OpenCommandPaneBackgroundResponse, + OpenCommandPaneFloatingNearPluginResponse, OpenCommandPaneFloatingResponse, + OpenCommandPaneInPlaceOfPaneIdResponse, OpenCommandPaneInPlaceOfPluginResponse, + OpenCommandPaneInPlaceResponse, OpenCommandPaneNearPluginResponse, OpenCommandPaneResponse, + OpenEditPaneInPlaceOfPaneIdResponse, OpenFileFloatingNearPluginResponse, + OpenFileFloatingResponse, OpenFileInPlaceOfPluginResponse, OpenFileInPlaceResponse, + OpenFileNearPluginResponse, OpenFileResponse, OpenPaneInNewTabResponse, + OpenPluginPaneFloatingResponse, OpenTerminalFloatingNearPluginResponse, + OpenTerminalFloatingResponse, OpenTerminalInPlaceOfPluginResponse, OpenTerminalInPlaceResponse, + OpenTerminalNearPluginResponse, OpenTerminalPaneInPlaceOfPaneIdResponse, OpenTerminalResponse, +}; + +impl TryFrom<ProtobufNewTabResponse> for NewTabResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufNewTabResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(new_tab_response::Result::TabId(id)) => Ok(Some(id as usize)), + Some(new_tab_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<NewTabResponse> for ProtobufNewTabResponse { + fn from(response: NewTabResponse) -> Self { + match response { + Some(tab_id) => ProtobufNewTabResponse { + result: Some(new_tab_response::Result::TabId(tab_id as u64)), + }, + None => ProtobufNewTabResponse { + result: Some(new_tab_response::Result::None(true)), + }, + } + } +} + +impl TryFrom<ProtobufNewTabUnfocusedResponse> for NewTabUnfocusedResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufNewTabUnfocusedResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(new_tab_unfocused_response::Result::TabId(id)) => Ok(Some(id as usize)), + Some(new_tab_unfocused_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<NewTabUnfocusedResponse> for ProtobufNewTabUnfocusedResponse { + fn from(response: NewTabUnfocusedResponse) -> Self { + match response { + Some(tab_id) => ProtobufNewTabUnfocusedResponse { + result: Some(new_tab_unfocused_response::Result::TabId(tab_id as u64)), + }, + None => ProtobufNewTabUnfocusedResponse { + result: Some(new_tab_unfocused_response::Result::None(true)), + }, + } + } +} + +impl TryFrom<ProtobufNewTiledPaneInTabResponse> for NewTiledPaneInTabResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufNewTiledPaneInTabResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<NewTiledPaneInTabResponse> for ProtobufNewTiledPaneInTabResponse { + fn from(response: NewTiledPaneInTabResponse) -> Self { + ProtobufNewTiledPaneInTabResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufNewTabsResponse> for NewTabsResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufNewTabsResponse) -> Result<Self, Self::Error> { + Ok(protobuf.tab_ids.into_iter().map(|id| id as usize).collect()) + } +} + +impl From<NewTabsResponse> for ProtobufNewTabsResponse { + fn from(response: NewTabsResponse) -> Self { + ProtobufNewTabsResponse { + tab_ids: response.into_iter().map(|id| id as u64).collect(), + } + } +} + +impl TryFrom<ProtobufFocusOrCreateTabResponse> for FocusOrCreateTabResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufFocusOrCreateTabResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(focus_or_create_tab_response::Result::TabId(id)) => Ok(Some(id as usize)), + Some(focus_or_create_tab_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<FocusOrCreateTabResponse> for ProtobufFocusOrCreateTabResponse { + fn from(response: FocusOrCreateTabResponse) -> Self { + match response { + Some(tab_id) => ProtobufFocusOrCreateTabResponse { + result: Some(focus_or_create_tab_response::Result::TabId(tab_id as u64)), + }, + None => ProtobufFocusOrCreateTabResponse { + result: Some(focus_or_create_tab_response::Result::None(true)), + }, + } + } +} + +impl TryFrom<ProtobufBreakPanesToNewTabResponse> for BreakPanesToNewTabResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufBreakPanesToNewTabResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(break_panes_to_new_tab_response::Result::TabId(id)) => Ok(Some(id as usize)), + Some(break_panes_to_new_tab_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<BreakPanesToNewTabResponse> for ProtobufBreakPanesToNewTabResponse { + fn from(response: BreakPanesToNewTabResponse) -> Self { + match response { + Some(tab_id) => ProtobufBreakPanesToNewTabResponse { + result: Some(break_panes_to_new_tab_response::Result::TabId( + tab_id as u64, + )), + }, + None => ProtobufBreakPanesToNewTabResponse { + result: Some(break_panes_to_new_tab_response::Result::None(true)), + }, + } + } +} + +impl TryFrom<ProtobufBreakPanesToTabWithIndexResponse> for BreakPanesToTabWithIndexResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufBreakPanesToTabWithIndexResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(break_panes_to_tab_with_index_response::Result::TabId(id)) => { + Ok(Some(id as usize)) + }, + Some(break_panes_to_tab_with_index_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<BreakPanesToTabWithIndexResponse> for ProtobufBreakPanesToTabWithIndexResponse { + fn from(response: BreakPanesToTabWithIndexResponse) -> Self { + match response { + Some(tab_id) => ProtobufBreakPanesToTabWithIndexResponse { + result: Some(break_panes_to_tab_with_index_response::Result::TabId( + tab_id as u64, + )), + }, + None => ProtobufBreakPanesToTabWithIndexResponse { + result: Some(break_panes_to_tab_with_index_response::Result::None(true)), + }, + } + } +} + +impl TryFrom<ProtobufBreakPanesToTabWithIdResponse> for BreakPanesToTabWithIdResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufBreakPanesToTabWithIdResponse) -> Result<Self, Self::Error> { + match protobuf.result { + Some(break_panes_to_tab_with_id_response::Result::TabId(id)) => Ok(Some(id as usize)), + Some(break_panes_to_tab_with_id_response::Result::None(_)) | None => Ok(None), + } + } +} + +impl From<BreakPanesToTabWithIdResponse> for ProtobufBreakPanesToTabWithIdResponse { + fn from(response: BreakPanesToTabWithIdResponse) -> Self { + match response { + Some(tab_id) => ProtobufBreakPanesToTabWithIdResponse { + result: Some(break_panes_to_tab_with_id_response::Result::TabId( + tab_id as u64, + )), + }, + None => ProtobufBreakPanesToTabWithIdResponse { + result: Some(break_panes_to_tab_with_id_response::Result::None(true)), + }, + } + } +} + +// Pane-creating command response conversions + +impl TryFrom<ProtobufOpenFileResponse> for OpenFileResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileResponse> for ProtobufOpenFileResponse { + fn from(response: OpenFileResponse) -> Self { + ProtobufOpenFileResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenFileFloatingResponse> for OpenFileFloatingResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileFloatingResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileFloatingResponse> for ProtobufOpenFileFloatingResponse { + fn from(response: OpenFileFloatingResponse) -> Self { + ProtobufOpenFileFloatingResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenFileInPlaceResponse> for OpenFileInPlaceResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileInPlaceResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileInPlaceResponse> for ProtobufOpenFileInPlaceResponse { + fn from(response: OpenFileInPlaceResponse) -> Self { + ProtobufOpenFileInPlaceResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenFileNearPluginResponse> for OpenFileNearPluginResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileNearPluginResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileNearPluginResponse> for ProtobufOpenFileNearPluginResponse { + fn from(response: OpenFileNearPluginResponse) -> Self { + ProtobufOpenFileNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenFileFloatingNearPluginResponse> for OpenFileFloatingNearPluginResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileFloatingNearPluginResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileFloatingNearPluginResponse> for ProtobufOpenFileFloatingNearPluginResponse { + fn from(response: OpenFileFloatingNearPluginResponse) -> Self { + ProtobufOpenFileFloatingNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenFileInPlaceOfPluginResponse> for OpenFileInPlaceOfPluginResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenFileInPlaceOfPluginResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenFileInPlaceOfPluginResponse> for ProtobufOpenFileInPlaceOfPluginResponse { + fn from(response: OpenFileInPlaceOfPluginResponse) -> Self { + ProtobufOpenFileInPlaceOfPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalResponse> for OpenTerminalResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenTerminalResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalResponse> for ProtobufOpenTerminalResponse { + fn from(response: OpenTerminalResponse) -> Self { + ProtobufOpenTerminalResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalFloatingResponse> for OpenTerminalFloatingResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenTerminalFloatingResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalFloatingResponse> for ProtobufOpenTerminalFloatingResponse { + fn from(response: OpenTerminalFloatingResponse) -> Self { + ProtobufOpenTerminalFloatingResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalInPlaceResponse> for OpenTerminalInPlaceResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenTerminalInPlaceResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalInPlaceResponse> for ProtobufOpenTerminalInPlaceResponse { + fn from(response: OpenTerminalInPlaceResponse) -> Self { + ProtobufOpenTerminalInPlaceResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalNearPluginResponse> for OpenTerminalNearPluginResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenTerminalNearPluginResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalNearPluginResponse> for ProtobufOpenTerminalNearPluginResponse { + fn from(response: OpenTerminalNearPluginResponse) -> Self { + ProtobufOpenTerminalNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalFloatingNearPluginResponse> + for OpenTerminalFloatingNearPluginResponse +{ + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenTerminalFloatingNearPluginResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalFloatingNearPluginResponse> + for ProtobufOpenTerminalFloatingNearPluginResponse +{ + fn from(response: OpenTerminalFloatingNearPluginResponse) -> Self { + ProtobufOpenTerminalFloatingNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalInPlaceOfPluginResponse> for OpenTerminalInPlaceOfPluginResponse { + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenTerminalInPlaceOfPluginResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalInPlaceOfPluginResponse> for ProtobufOpenTerminalInPlaceOfPluginResponse { + fn from(response: OpenTerminalInPlaceOfPluginResponse) -> Self { + ProtobufOpenTerminalInPlaceOfPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneResponse> for OpenCommandPaneResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenCommandPaneResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneResponse> for ProtobufOpenCommandPaneResponse { + fn from(response: OpenCommandPaneResponse) -> Self { + ProtobufOpenCommandPaneResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneFloatingResponse> for OpenCommandPaneFloatingResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenCommandPaneFloatingResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneFloatingResponse> for ProtobufOpenCommandPaneFloatingResponse { + fn from(response: OpenCommandPaneFloatingResponse) -> Self { + ProtobufOpenCommandPaneFloatingResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneInPlaceResponse> for OpenCommandPaneInPlaceResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenCommandPaneInPlaceResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneInPlaceResponse> for ProtobufOpenCommandPaneInPlaceResponse { + fn from(response: OpenCommandPaneInPlaceResponse) -> Self { + ProtobufOpenCommandPaneInPlaceResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneNearPluginResponse> for OpenCommandPaneNearPluginResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenCommandPaneNearPluginResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneNearPluginResponse> for ProtobufOpenCommandPaneNearPluginResponse { + fn from(response: OpenCommandPaneNearPluginResponse) -> Self { + ProtobufOpenCommandPaneNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneFloatingNearPluginResponse> + for OpenCommandPaneFloatingNearPluginResponse +{ + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenCommandPaneFloatingNearPluginResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneFloatingNearPluginResponse> + for ProtobufOpenCommandPaneFloatingNearPluginResponse +{ + fn from(response: OpenCommandPaneFloatingNearPluginResponse) -> Self { + ProtobufOpenCommandPaneFloatingNearPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneInPlaceOfPluginResponse> + for OpenCommandPaneInPlaceOfPluginResponse +{ + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenCommandPaneInPlaceOfPluginResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneInPlaceOfPluginResponse> + for ProtobufOpenCommandPaneInPlaceOfPluginResponse +{ + fn from(response: OpenCommandPaneInPlaceOfPluginResponse) -> Self { + ProtobufOpenCommandPaneInPlaceOfPluginResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneBackgroundResponse> for OpenCommandPaneBackgroundResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenCommandPaneBackgroundResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneBackgroundResponse> for ProtobufOpenCommandPaneBackgroundResponse { + fn from(response: OpenCommandPaneBackgroundResponse) -> Self { + ProtobufOpenCommandPaneBackgroundResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenPaneInNewTabResponse> for OpenPaneInNewTabResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenPaneInNewTabResponse) -> Result<Self, Self::Error> { + let tab_id = protobuf.tab_id.map(|id| id as usize); + let pane_id = match protobuf.pane_id { + Some(pane_id) => Some(pane_id.try_into()?), + None => None, + }; + Ok(OpenPaneInNewTabResponse { tab_id, pane_id }) + } +} + +impl From<OpenPaneInNewTabResponse> for ProtobufOpenPaneInNewTabResponse { + fn from(response: OpenPaneInNewTabResponse) -> Self { + ProtobufOpenPaneInNewTabResponse { + tab_id: response.tab_id.map(|id| id as u64), + pane_id: response.pane_id.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenCommandPaneInPlaceOfPaneIdResponse> + for OpenCommandPaneInPlaceOfPaneIdResponse +{ + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenCommandPaneInPlaceOfPaneIdResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenCommandPaneInPlaceOfPaneIdResponse> + for ProtobufOpenCommandPaneInPlaceOfPaneIdResponse +{ + fn from(response: OpenCommandPaneInPlaceOfPaneIdResponse) -> Self { + ProtobufOpenCommandPaneInPlaceOfPaneIdResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenTerminalPaneInPlaceOfPaneIdResponse> + for OpenTerminalPaneInPlaceOfPaneIdResponse +{ + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenTerminalPaneInPlaceOfPaneIdResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenTerminalPaneInPlaceOfPaneIdResponse> + for ProtobufOpenTerminalPaneInPlaceOfPaneIdResponse +{ + fn from(response: OpenTerminalPaneInPlaceOfPaneIdResponse) -> Self { + ProtobufOpenTerminalPaneInPlaceOfPaneIdResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenEditPaneInPlaceOfPaneIdResponse> for OpenEditPaneInPlaceOfPaneIdResponse { + type Error = &'static str; + fn try_from( + protobuf: ProtobufOpenEditPaneInPlaceOfPaneIdResponse, + ) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenEditPaneInPlaceOfPaneIdResponse> for ProtobufOpenEditPaneInPlaceOfPaneIdResponse { + fn from(response: OpenEditPaneInPlaceOfPaneIdResponse) -> Self { + ProtobufOpenEditPaneInPlaceOfPaneIdResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +impl TryFrom<ProtobufOpenPluginPaneFloatingResponse> for OpenPluginPaneFloatingResponse { + type Error = &'static str; + fn try_from(protobuf: ProtobufOpenPluginPaneFloatingResponse) -> Result<Self, Self::Error> { + match protobuf.pane_id { + Some(pane_id) => Ok(Some(pane_id.try_into()?)), + None => Ok(None), + } + } +} + +impl From<OpenPluginPaneFloatingResponse> for ProtobufOpenPluginPaneFloatingResponse { + fn from(response: OpenPluginPaneFloatingResponse) -> Self { + ProtobufOpenPluginPaneFloatingResponse { + pane_id: response.map(|p| p.try_into().unwrap()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::data::{PaneId, PluginCommand}; + use crate::pane_size::Size; + + #[test] + fn set_tab_fit_set_protobuf_round_trip() { + let original = PluginCommand::SetTabFit { + tab_id: 7, + fit: Some((PaneId::Terminal(3), Size { rows: 24, cols: 80 })), + }; + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::SetTabFit { tab_id, fit } => { + assert_eq!(tab_id, 7); + assert_eq!( + fit, + Some((PaneId::Terminal(3), Size { rows: 24, cols: 80 })) + ); + }, + other => panic!("expected SetTabFit, got {:?}", other), + } + } + + #[test] + fn set_tab_fit_clear_protobuf_round_trip() { + let original = PluginCommand::SetTabFit { + tab_id: 7, + fit: None, + }; + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::SetTabFit { tab_id, fit } => { + assert_eq!(tab_id, 7); + assert_eq!(fit, None); + }, + other => panic!("expected SetTabFit, got {:?}", other), + } + } + + #[test] + fn set_pane_frame_style_protobuf_round_trip() { + use crate::input::options::PaneFrameStyle; + for style in [ + PaneFrameStyle::Full, + PaneFrameStyle::Titles, + PaneFrameStyle::None, + ] { + let original = PluginCommand::SetPaneFrameStyle(style); + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::SetPaneFrameStyle(decoded_style) => { + assert_eq!(decoded_style, style) + }, + other => panic!("expected SetPaneFrameStyle, got {:?}", other), + } + } + } + + #[test] + fn new_pane_protobuf_round_trip() { + let original = PluginCommand::NewPane; + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::NewPane => {}, + other => panic!("expected NewPane, got {:?}", other), + } + } + + #[test] + fn toggle_floating_panes_focused_tab_protobuf_round_trip() { + let original = PluginCommand::ToggleFloatingPanes { tab_id: None }; + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::ToggleFloatingPanes { tab_id } => assert_eq!(tab_id, None), + other => panic!("expected ToggleFloatingPanes, got {:?}", other), + } + } + + #[test] + fn toggle_floating_panes_with_tab_id_protobuf_round_trip() { + let original = PluginCommand::ToggleFloatingPanes { tab_id: Some(2) }; + let protobuf: ProtobufPluginCommand = original.try_into().expect("encode"); + let decoded: PluginCommand = protobuf.try_into().expect("decode"); + match decoded { + PluginCommand::ToggleFloatingPanes { tab_id } => assert_eq!(tab_id, Some(2)), + other => panic!("expected ToggleFloatingPanes, got {:?}", other), + } + } +} |
