aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/plugin_api
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-02-11 13:26:33 +0100
committerGitHub <noreply@github.com>2026-02-11 13:26:33 +0100
commit13a82eea6d74d8168e538b8755131ed793a7f054 (patch)
treebb8d2c1b6cd24bf46b84860360c48e6249e21ba1 /zellij-utils/src/plugin_api
parentAllow writing characters, bytes and keys to specific panes from the CLI (#4691) (diff)
downloadsl0ppij-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.proto11
-rw-r--r--zellij-utils/src/plugin_api/action.rs12
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto40
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs148
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 {