aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/plugin_api
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-04-28 17:14:59 +0200
committerGitHub <noreply@github.com>2026-04-28 17:14:59 +0200
commit227142dd567ee72bcc137c116bc1ce2b818975e7 (patch)
tree8958a994dddb80bf20ce1e6bf2694687736b0b19 /zellij-utils/src/plugin_api
parentupgrade rustls-webpki (#5106) (diff)
downloadsl0ppij-227142dd567ee72bcc137c116bc1ce2b818975e7.tar.gz
sl0ppij-227142dd567ee72bcc137c116bc1ce2b818975e7.tar.xz
sl0ppij-227142dd567ee72bcc137c116bc1ce2b818975e7.zip
Support CSI2031 (dark/light theme switching) + remove STDIN cache to avoid stale color queries (#5105)
* initial phase 1 implementation * various fies * some fixes * fix fragmented stdin cases * some fixes * renaming * guard against old clients * implement csi 2031 * allow toggling theme with actions * rustfmt * fix: finalize trailing characters in ansi parser as well * add pr
Diffstat (limited to 'zellij-utils/src/plugin_api')
-rw-r--r--zellij-utils/src/plugin_api/action.proto3
-rw-r--r--zellij-utils/src/plugin_api/action.rs24
-rw-r--r--zellij-utils/src/plugin_api/event.proto11
-rw-r--r--zellij-utils/src/plugin_api/event.rs50
4 files changed, 83 insertions, 5 deletions
diff --git a/zellij-utils/src/plugin_api/action.proto b/zellij-utils/src/plugin_api/action.proto
index ea043d56..28a8337e 100644
--- a/zellij-utils/src/plugin_api/action.proto
+++ b/zellij-utils/src/plugin_api/action.proto
@@ -490,6 +490,9 @@ enum ActionName {
ShowFloatingPanes = 98;
HideFloatingPanes = 99;
AreFloatingPanesVisible = 100;
+ SetDarkTheme = 101;
+ SetLightTheme = 102;
+ ToggleTheme = 103;
}
message Position {
diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs
index cbd62e5b..cd3e1522 100644
--- a/zellij-utils/src/plugin_api/action.rs
+++ b/zellij-utils/src/plugin_api/action.rs
@@ -611,6 +611,18 @@ impl TryFrom<ProtobufAction> for Action {
Some(_) => Err("Detach should not have a payload"),
None => Ok(Action::Detach),
},
+ Some(ProtobufActionName::SetDarkTheme) => match protobuf_action.optional_payload {
+ Some(_) => Err("SetDarkTheme should not have a payload"),
+ None => Ok(Action::SetDarkTheme),
+ },
+ Some(ProtobufActionName::SetLightTheme) => match protobuf_action.optional_payload {
+ Some(_) => Err("SetLightTheme should not have a payload"),
+ None => Ok(Action::SetLightTheme),
+ },
+ Some(ProtobufActionName::ToggleTheme) => match protobuf_action.optional_payload {
+ Some(_) => Err("ToggleTheme should not have a payload"),
+ None => Ok(Action::ToggleTheme),
+ },
Some(ProtobufActionName::LeftClick) => match protobuf_action.optional_payload {
Some(OptionalPayload::LeftClickPayload(payload)) => {
let position = payload.try_into()?;
@@ -1567,6 +1579,18 @@ impl TryFrom<Action> for ProtobufAction {
name: ProtobufActionName::Detach as i32,
optional_payload: None,
}),
+ Action::SetDarkTheme => Ok(ProtobufAction {
+ name: ProtobufActionName::SetDarkTheme as i32,
+ optional_payload: None,
+ }),
+ Action::SetLightTheme => Ok(ProtobufAction {
+ name: ProtobufActionName::SetLightTheme as i32,
+ optional_payload: None,
+ }),
+ Action::ToggleTheme => Ok(ProtobufAction {
+ name: ProtobufActionName::ToggleTheme as i32,
+ optional_payload: None,
+ }),
Action::LaunchOrFocusPlugin {
plugin: run_plugin_or_alias,
should_float,
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index 3c3a8490..5334f434 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -68,6 +68,7 @@ enum EventType {
PaneRenderReportWithAnsi = 43;
InitialKeybinds = 44;
CommandChanged = 45;
+ HostTerminalThemeChanged = 46;
}
message EventNameList {
@@ -115,9 +116,19 @@ message Event {
PaneRenderReportPayload pane_render_report_with_ansi_payload = 37;
InitialKeybindsPayload initial_keybinds_payload = 38;
CommandChangedPayload command_changed_payload = 39;
+ HostTerminalThemeChangedPayload host_terminal_theme_changed_payload = 40;
}
}
+message HostTerminalThemeChangedPayload {
+ HostTerminalThemeIndication mode = 1;
+}
+
+enum HostTerminalThemeIndication {
+ Dark = 0;
+ Light = 1;
+}
+
message CwdChangedPayload {
PaneId pane_id = 1;
string new_cwd = 2;
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index 6f138742..af421fac 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -11,6 +11,8 @@ pub use super::generated_api::api::{
CopyDestination as ProtobufCopyDestination, CwdChangedPayload as ProtobufCwdChangedPayload,
Event as ProtobufEvent, EventNameList as ProtobufEventNameList,
EventType as ProtobufEventType, FileMetadata as ProtobufFileMetadata,
+ HostTerminalThemeChangedPayload as ProtobufHostTerminalThemeChangedPayload,
+ HostTerminalThemeIndication as ProtobufHostTerminalThemeIndication,
InputModeKeybinds as ProtobufInputModeKeybinds, KdlError as ProtobufKdlError,
KdlErrorVariant as ProtobufKdlErrorVariant, KeyBind as ProtobufKeyBind,
LayoutInfo as ProtobufLayoutInfo, LayoutMetadata as ProtobufLayoutMetadata,
@@ -35,11 +37,11 @@ pub use super::generated_api::api::{
};
#[allow(hidden_glob_reexports)]
use crate::data::{
- ClientId, ClientInfo, CopyDestination, Event, EventType, FileMetadata, InputMode,
- KeyWithModifier, LayoutInfo, LayoutMetadata, ModeInfo, Mouse, PaneContents, PaneId, PaneInfo,
- PaneManifest, PaneMetadata, PaneScrollbackResponse, PermissionStatus, PluginCapabilities,
- PluginInfo, SelectedText, SessionInfo, Style, TabInfo, TabMetadata, WebServerStatus,
- WebSharing,
+ ClientId, ClientInfo, CopyDestination, Event, EventType, FileMetadata, HostTerminalThemeMode,
+ InputMode, KeyWithModifier, LayoutInfo, LayoutMetadata, ModeInfo, Mouse, PaneContents, PaneId,
+ PaneInfo, PaneManifest, PaneMetadata, PaneScrollbackResponse, PermissionStatus,
+ PluginCapabilities, PluginInfo, SelectedText, SessionInfo, Style, TabInfo, TabMetadata,
+ WebServerStatus, WebSharing,
};
use crate::errors::prelude::*;
@@ -578,6 +580,14 @@ impl TryFrom<ProtobufEvent> for Event {
},
_ => Err("Malformed payload for InitialKeybinds Event"),
},
+ Some(ProtobufEventType::HostTerminalThemeChanged) => match protobuf_event.payload {
+ Some(ProtobufEventPayload::HostTerminalThemeChangedPayload(p)) => {
+ let mode = ProtobufHostTerminalThemeIndication::from_i32(p.mode)
+ .ok_or("Unknown HostTerminalThemeIndication")?;
+ Ok(Event::HostTerminalThemeChanged(mode.into()))
+ },
+ _ => Err("Malformed payload for HostTerminalThemeChanged Event"),
+ },
None => Err("Unknown Protobuf Event"),
}
}
@@ -1109,6 +1119,16 @@ impl TryFrom<Event> for ProtobufEvent {
},
)),
}),
+ Event::HostTerminalThemeChanged(mode) => {
+ let proto_mode: ProtobufHostTerminalThemeIndication = mode.into();
+ let payload = ProtobufHostTerminalThemeChangedPayload {
+ mode: proto_mode as i32,
+ };
+ Ok(ProtobufEvent {
+ name: ProtobufEventType::HostTerminalThemeChanged as i32,
+ payload: Some(event::Payload::HostTerminalThemeChangedPayload(payload)),
+ })
+ },
Event::InitialKeybinds(keybinds) => {
let mut protobuf_keybinds: Vec<ProtobufInputModeKeybinds> = vec![];
for (input_mode, input_mode_keybinds) in keybinds {
@@ -2057,6 +2077,7 @@ impl TryFrom<ProtobufEventType> for EventType {
ProtobufEventType::PluginConfigurationChanged => EventType::PluginConfigurationChanged,
ProtobufEventType::HighlightClicked => EventType::HighlightClicked,
ProtobufEventType::InitialKeybinds => EventType::InitialKeybinds,
+ ProtobufEventType::HostTerminalThemeChanged => EventType::HostTerminalThemeChanged,
})
}
}
@@ -2110,10 +2131,29 @@ impl TryFrom<EventType> for ProtobufEventType {
EventType::PluginConfigurationChanged => ProtobufEventType::PluginConfigurationChanged,
EventType::HighlightClicked => ProtobufEventType::HighlightClicked,
EventType::InitialKeybinds => ProtobufEventType::InitialKeybinds,
+ EventType::HostTerminalThemeChanged => ProtobufEventType::HostTerminalThemeChanged,
})
}
}
+impl From<HostTerminalThemeMode> for ProtobufHostTerminalThemeIndication {
+ fn from(mode: HostTerminalThemeMode) -> Self {
+ match mode {
+ HostTerminalThemeMode::Dark => ProtobufHostTerminalThemeIndication::Dark,
+ HostTerminalThemeMode::Light => ProtobufHostTerminalThemeIndication::Light,
+ }
+ }
+}
+
+impl From<ProtobufHostTerminalThemeIndication> for HostTerminalThemeMode {
+ fn from(mode: ProtobufHostTerminalThemeIndication) -> Self {
+ match mode {
+ ProtobufHostTerminalThemeIndication::Dark => HostTerminalThemeMode::Dark,
+ ProtobufHostTerminalThemeIndication::Light => HostTerminalThemeMode::Light,
+ }
+ }
+}
+
impl From<ProtobufResurrectableSession> for (String, Duration) {
fn from(protobuf_resurrectable_session: ProtobufResurrectableSession) -> (String, Duration) {
(