diff options
| author | Aram Drevekenin <aram@poor.dev> | 2026-02-11 13:26:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-11 13:26:33 +0100 |
| commit | 13a82eea6d74d8168e538b8755131ed793a7f054 (patch) | |
| tree | bb8d2c1b6cd24bf46b84860360c48e6249e21ba1 /zellij-utils/src/plugin_api | |
| parent | Allow writing characters, bytes and keys to specific panes from the CLI (#4691) (diff) | |
| download | sl0ppij-13a82eea6d74d8168e538b8755131ed793a7f054.tar.gz sl0ppij-13a82eea6d74d8168e538b8755131ed793a7f054.tar.xz sl0ppij-13a82eea6d74d8168e538b8755131ed793a7f054.zip | |
CLI commands to query tab ids, names and info (#4695)
* add equivalent tab_id commands to tab_position commands (cli and plugins)
* add list-tabs and current-tab-info cli commands
* rustfmt
* add pr
Diffstat (limited to 'zellij-utils/src/plugin_api')
| -rw-r--r-- | zellij-utils/src/plugin_api/action.proto | 11 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/action.rs | 12 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.proto | 40 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.rs | 148 |
4 files changed, 184 insertions, 27 deletions
diff --git a/zellij-utils/src/plugin_api/action.proto b/zellij-utils/src/plugin_api/action.proto index 802d0a0e..83181097 100644 --- a/zellij-utils/src/plugin_api/action.proto +++ b/zellij-utils/src/plugin_api/action.proto @@ -232,6 +232,9 @@ message Action { NewInPlacePanePayload new_in_place_pane_payload = 52; OverrideLayoutPayload override_layout_payload = 53; SetPaneBorderlessPayload set_pane_borderless_payload = 54; + uint64 go_to_tab_by_id_payload = 55; + uint64 close_tab_by_id_payload = 56; + TabIdAndName rename_tab_by_id_payload = 57; } } @@ -247,6 +250,11 @@ message IdAndName { uint32 id = 2; } +message TabIdAndName { + uint64 tab_id = 1; + string name = 2; +} + message PaneIdAndShouldFloat { uint32 pane_id = 1; bool should_float = 2; @@ -451,6 +459,9 @@ enum ActionName { NewInPlacePane = 92; OverrideLayout = 93; SetPaneBorderless = 94; + GoToTabById = 95; + CloseTabById = 96; + RenameTabById = 97; } message Position { diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs index 92dc618c..047244d7 100644 --- a/zellij-utils/src/plugin_api/action.rs +++ b/zellij-utils/src/plugin_api/action.rs @@ -1030,8 +1030,12 @@ impl TryFrom<Action> for ProtobufAction { chars: chars_to_write, })), }), - Action::WriteToPaneId { .. } | Action::WriteCharsToPaneId { .. } => { - Err("WriteToPaneId and WriteCharsToPaneId are CLI-only actions, not available in keybindings") + Action::WriteToPaneId { .. } + | Action::WriteCharsToPaneId { .. } + | Action::GoToTabById { .. } + | Action::CloseTabById { .. } + | Action::RenameTabById { .. } => { + Err("WriteToPaneId, WriteCharsToPaneId, GoToTabById, CloseTabById, and RenameTabById are CLI-only actions, not available in keybindings") }, Action::SwitchToMode { input_mode } => { let input_mode: ProtobufInputMode = input_mode.try_into()?; @@ -1782,7 +1786,9 @@ impl TryFrom<Action> for ProtobufAction { | Action::SetPaneBorderless { .. } | Action::SkipConfirm { action: _ } | Action::SwitchSession { .. } - | Action::SaveSession => Err("Unsupported action"), + | Action::SaveSession + | Action::ListTabs { .. } + | Action::CurrentTabInfo { .. } => Err("Unsupported action"), } } } diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto index b450c13f..a2a25f99 100644 --- a/zellij-utils/src/plugin_api/plugin_command.proto +++ b/zellij-utils/src/plugin_api/plugin_command.proto @@ -184,6 +184,11 @@ enum CommandName { GetTabInfo = 189; GetPaneRunningCommand = 190; GetPaneCwd = 191; + SwitchTabToId = 192; + GoToTabWithId = 193; + CloseTabWithId = 194; + RenameTabWithId = 195; + BreakPanesToTabWithId = 196; } message PluginCommand { @@ -317,6 +322,11 @@ message PluginCommand { GetTabInfoPayload get_tab_info_payload = 140; GetPaneRunningCommandPayload get_pane_running_command_payload = 141; GetPaneCwdPayload get_pane_cwd_payload = 142; + SwitchTabToIdPayload switch_tab_to_id_payload = 143; + GoToTabWithIdPayload go_to_tab_with_id_payload = 144; + CloseTabWithIdPayload close_tab_with_id_payload = 145; + RenameTabWithIdPayload rename_tab_with_id_payload = 146; + BreakPanesToTabWithIdPayload break_panes_to_tab_with_id_payload = 147; } } @@ -749,6 +759,36 @@ enum FixedOrPercent { Percent = 1; } +message SwitchTabToIdPayload { + uint64 tab_id = 1; +} + +message GoToTabWithIdPayload { + uint64 tab_id = 1; +} + +message CloseTabWithIdPayload { + uint64 tab_id = 1; +} + +message RenameTabWithIdPayload { + uint64 tab_id = 1; + string new_name = 2; +} + +message BreakPanesToTabWithIdPayload { + repeated PaneId pane_ids = 1; + uint64 tab_id = 2; + bool should_change_focus_to_target_tab = 3; +} + +message BreakPanesToTabWithIdResponse { + oneof result { + uint64 tab_id = 1; + bool none = 2; + } +} + message CreateTokenResponse { optional string token = 1; optional string token_label = 2; diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs index 7871d15f..6ade3376 100644 --- a/zellij-utils/src/plugin_api/plugin_command.rs +++ b/zellij-utils/src/plugin_api/plugin_command.rs @@ -3,20 +3,23 @@ pub use super::generated_api::api::{ event::{EventNameList as ProtobufEventNameList, Header}, input_mode::InputMode as ProtobufInputMode, plugin_command::{ - break_panes_to_new_tab_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, - new_tab_response, parse_layout_response, plugin_command::Payload, rename_layout_response, - save_layout_response, save_session_response, BreakPanesToNewTabPayload, + 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, new_tab_response, parse_layout_response, + plugin_command::Payload, rename_layout_response, save_layout_response, + save_session_response, BreakPanesToNewTabPayload, BreakPanesToNewTabResponse as ProtobufBreakPanesToNewTabResponse, + BreakPanesToTabWithIdPayload, + BreakPanesToTabWithIdResponse as ProtobufBreakPanesToTabWithIdResponse, BreakPanesToTabWithIndexPayload, BreakPanesToTabWithIndexResponse as ProtobufBreakPanesToTabWithIndexResponse, ChangeFloatingPanesCoordinatesPayload, ChangeHostFolderPayload, ClearScreenForPaneIdPayload, CliPipeOutputPayload, CloseMultiplePanesPayload, - CloseTabWithIndexPayload, CommandName, ContextItem, CopyToClipboardPayload, - CreateTokenResponse as ProtobufCreateTokenResponse, CreateTokenResponse, - CurrentSessionLastSavedTimePayload, + CloseTabWithIdPayload, CloseTabWithIndexPayload, CommandName, ContextItem, + CopyToClipboardPayload, CreateTokenResponse as ProtobufCreateTokenResponse, + CreateTokenResponse, CurrentSessionLastSavedTimePayload, CurrentSessionLastSavedTimeResponse as ProtobufCurrentSessionLastSavedTimeResponse, CursorPosition, DeleteLayoutPayload, DeleteLayoutResponse as ProtobufDeleteLayoutResponse, DumpLayoutPayload, DumpLayoutResponse as ProtobufDumpLayoutResponse, @@ -39,13 +42,14 @@ pub use super::generated_api::api::{ GetPaneRunningCommandPayload as ProtobufGetPaneRunningCommandPayload, GetPaneRunningCommandResponse as ProtobufGetPaneRunningCommandResponse, GetPaneScrollbackPayload, GetTabInfoPayload, - GetTabInfoResponse as ProtobufGetTabInfoResponse, GroupAndUngroupPanesPayload, - HidePaneWithIdPayload, HighlightAndUnhighlightPanesPayload, HttpVerb as ProtobufHttpVerb, - IdAndNewName, KeyToRebind, KeyToUnbind, KillSessionsPayload, ListTokensResponse, - LoadNewPluginPayload, MessageToPluginPayload, MovePaneWithPaneIdInDirectionPayload, - MovePaneWithPaneIdPayload, MovePayload, NewPluginArgs as ProtobufNewPluginArgs, - NewTabPayload, NewTabResponse as ProtobufNewTabResponse, - NewTabsResponse as ProtobufNewTabsResponse, NewTabsWithLayoutInfoPayload, + GetTabInfoResponse as ProtobufGetTabInfoResponse, GoToTabWithIdPayload, + GroupAndUngroupPanesPayload, HidePaneWithIdPayload, HighlightAndUnhighlightPanesPayload, + HttpVerb as ProtobufHttpVerb, IdAndNewName, KeyToRebind, KeyToUnbind, KillSessionsPayload, + ListTokensResponse, LoadNewPluginPayload, MessageToPluginPayload, + MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload, MovePayload, + NewPluginArgs as ProtobufNewPluginArgs, NewTabPayload, + NewTabResponse as ProtobufNewTabResponse, NewTabsResponse as ProtobufNewTabsResponse, + NewTabsWithLayoutInfoPayload, OpenCommandPaneBackgroundResponse as ProtobufOpenCommandPaneBackgroundResponse, OpenCommandPaneFloatingNearPluginPayload, OpenCommandPaneFloatingNearPluginResponse as ProtobufOpenCommandPaneFloatingNearPluginResponse, @@ -77,9 +81,10 @@ pub use super::generated_api::api::{ ParseLayoutResponse as ProtobufParseLayoutResponse, PluginCommand as ProtobufPluginCommand, PluginMessagePayload, RebindKeysPayload, ReconfigurePayload, ReloadPluginPayload, RenameLayoutPayload, RenameLayoutResponse as ProtobufRenameLayoutResponse, - RenameWebLoginTokenPayload, RenameWebTokenResponse, ReplacePaneWithExistingPanePayload, - RequestPluginPermissionPayload, RerunCommandPanePayload, ResizePaneIdWithDirectionPayload, - ResizePayload, RevokeAllWebTokensResponse, RevokeTokenResponse, RevokeWebLoginTokenPayload, + 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, @@ -87,9 +92,9 @@ pub use super::generated_api::api::{ SetFloatingPanePinnedPayload, SetPaneBorderlessPayload, SetSelfMouseSelectionSupportPayload, SetTimeoutPayload, ShowCursorPayload, ShowPaneWithIdPayload, StackPanesPayload, SubscribePayload, SwitchSessionPayload, - SwitchTabToPayload, TogglePaneBorderlessPayload, TogglePaneEmbedOrEjectForPaneIdPayload, - TogglePaneIdFullscreenPayload, UnsubscribePayload, WebRequestPayload, - WriteCharsToPaneIdPayload, WriteToPaneIdPayload, + SwitchTabToIdPayload, SwitchTabToPayload, TogglePaneBorderlessPayload, + TogglePaneEmbedOrEjectForPaneIdPayload, TogglePaneIdFullscreenPayload, UnsubscribePayload, + WebRequestPayload, WriteCharsToPaneIdPayload, WriteToPaneIdPayload, }, plugin_permission::PermissionType as ProtobufPermissionType, resize::ResizeAction as ProtobufResizeAction, @@ -1679,6 +1684,44 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand { )), _ => 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)) @@ -3128,6 +3171,48 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand { }, )), }), + 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 { @@ -3601,8 +3686,8 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand { // Conversion implementations for tab creation response types use crate::data::{ - BreakPanesToNewTabResponse, BreakPanesToTabWithIndexResponse, FocusOrCreateTabResponse, - NewTabResponse, NewTabsResponse, OpenCommandPaneBackgroundResponse, + BreakPanesToNewTabResponse, BreakPanesToTabWithIdResponse, BreakPanesToTabWithIndexResponse, + FocusOrCreateTabResponse, NewTabResponse, NewTabsResponse, OpenCommandPaneBackgroundResponse, OpenCommandPaneFloatingNearPluginResponse, OpenCommandPaneFloatingResponse, OpenCommandPaneInPlaceOfPluginResponse, OpenCommandPaneInPlaceResponse, OpenCommandPaneNearPluginResponse, OpenCommandPaneResponse, OpenFileFloatingNearPluginResponse, @@ -3725,6 +3810,21 @@ impl From<BreakPanesToTabWithIndexResponse> for ProtobufBreakPanesToTabWithIndex } } +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 { |
