aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2025-10-27 12:31:02 +0100
committerGitHub <noreply@github.com>2025-10-27 12:31:02 +0100
commit8762f866380360457c84c1e7ce7973f104468f87 (patch)
treeb437ef473578e2120b67e6d96068e05b7cb88511 /zellij-utils/src
parentMigrate from wasmtime to wasmi (#4449) (diff)
downloadsl0ppij-8762f866380360457c84c1e7ce7973f104468f87.tar.gz
sl0ppij-8762f866380360457c84c1e7ce7973f104468f87.tar.xz
sl0ppij-8762f866380360457c84c1e7ce7973f104468f87.zip
Feature: watcher clients (#4487)
* initial implementation * make Screen aware of watchers - slightly buggy * fix: only render focused tab to watcher * track watcher sizes on Screen * pad watcher output as needed * truncate watcher sizes as needed * render on watcher resize * fix watcher first resize * allow watchers to quit with esc, ctrl-c or ctrl-q * fix: send watcher size on initial connection message * refactor: move padding logic to output * fix watcher rendering after all clients disconnected * fix watcher rendering caching issues * crop watcher cursor when out of bounds * remove watchers cleanly on session close * standardize watcher messages ignoring * add e2e test for watcher functionality * update snapshots * add output tests * rustfmt * cleanups * docs(changelog): add PR
Diffstat (limited to 'zellij-utils/src')
-rw-r--r--zellij-utils/src/cli.rs8
-rw-r--r--zellij-utils/src/client_server_contract/client_to_server.proto5
-rw-r--r--zellij-utils/src/data.rs5
-rw-r--r--zellij-utils/src/errors.rs4
-rw-r--r--zellij-utils/src/ipc.rs3
-rw-r--r--zellij-utils/src/ipc/protobuf_conversion.rs26
6 files changed, 45 insertions, 6 deletions
diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs
index 495066d0..da1f777a 100644
--- a/zellij-utils/src/cli.rs
+++ b/zellij-utils/src/cli.rs
@@ -271,6 +271,14 @@ pub enum Sessions {
forget: bool,
},
+ /// Watch a session (read-only)
+ #[clap(visible_alias = "w")]
+ Watch {
+ /// Name of the session to watch
+ #[clap(value_parser)]
+ session_name: Option<String>,
+ },
+
/// Kill a specific session
#[clap(visible_alias = "k")]
KillSession {
diff --git a/zellij-utils/src/client_server_contract/client_to_server.proto b/zellij-utils/src/client_server_contract/client_to_server.proto
index f9b01994..9ec0a49f 100644
--- a/zellij-utils/src/client_server_contract/client_to_server.proto
+++ b/zellij-utils/src/client_server_contract/client_to_server.proto
@@ -20,6 +20,7 @@ message ClientToServerMsg {
ConnStatusMsg conn_status = 13;
WebServerStartedMsg web_server_started = 14;
FailedToStartWebServerMsg failed_to_start_web_server = 15;
+ AttachWatcherClientMsg attach_watcher_client = 16;
}
}
@@ -59,6 +60,10 @@ message AttachClientMsg {
bool is_web_client = 4;
}
+message AttachWatcherClientMsg {
+ Size terminal_size = 1;
+}
+
message ActionMsg {
Action action = 1;
optional uint32 terminal_id = 2;
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index 8632c7a0..53425e0b 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -1624,6 +1624,11 @@ impl ModeInfo {
pub fn update_hide_session_name(&mut self, hide_session_name: bool) {
self.style.hide_session_name = hide_session_name;
}
+ pub fn change_to_default_mode(&mut self) {
+ if let Some(base_mode) = self.base_mode {
+ self.mode = base_mode;
+ }
+ }
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index 624ef414..bcd05987 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -389,6 +389,10 @@ pub enum ScreenContext {
InterceptKeyPresses,
ClearKeyPressesIntercepts,
ReplacePaneWithExistingPane,
+ AddWatcherClient,
+ RemoveWatcherClient,
+ SetFollowedClient,
+ WatcherTerminalResize, // NEW
}
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs
index fdffaa07..1f37b2e7 100644
--- a/zellij-utils/src/ipc.rs
+++ b/zellij-utils/src/ipc.rs
@@ -114,6 +114,9 @@ pub enum ClientToServerMsg {
pane_to_focus: Option<PaneReference>,
is_web_client: bool,
},
+ AttachWatcherClient {
+ terminal_size: Size,
+ },
Action {
action: Action,
terminal_id: Option<u32>,
diff --git a/zellij-utils/src/ipc/protobuf_conversion.rs b/zellij-utils/src/ipc/protobuf_conversion.rs
index 23c9f201..658c10f3 100644
--- a/zellij-utils/src/ipc/protobuf_conversion.rs
+++ b/zellij-utils/src/ipc/protobuf_conversion.rs
@@ -1,11 +1,12 @@
use crate::{
client_server_contract::client_server_contract::{
- client_to_server_msg, server_to_client_msg, ActionMsg, AttachClientMsg, BackgroundColorMsg,
- CliPipeOutputMsg, ClientExitedMsg, ClientToServerMsg as ProtoClientToServerMsg,
- ColorRegistersMsg, ConfigFileUpdatedMsg, ConnStatusMsg, ConnectedMsg, DetachSessionMsg,
- ExitMsg, ExitReason as ProtoExitReason, FailedToStartWebServerMsg, FirstClientConnectedMsg,
- ForegroundColorMsg, InputMode as ProtoInputMode, KeyMsg, KillSessionMsg, LogErrorMsg,
- LogMsg, QueryTerminalSizeMsg, RenamedSessionMsg, RenderMsg,
+ client_to_server_msg, server_to_client_msg, ActionMsg, AttachClientMsg,
+ AttachWatcherClientMsg, BackgroundColorMsg, CliPipeOutputMsg, ClientExitedMsg,
+ ClientToServerMsg as ProtoClientToServerMsg, ColorRegistersMsg, ConfigFileUpdatedMsg,
+ ConnStatusMsg, ConnectedMsg, DetachSessionMsg, ExitMsg, ExitReason as ProtoExitReason,
+ FailedToStartWebServerMsg, FirstClientConnectedMsg, ForegroundColorMsg,
+ InputMode as ProtoInputMode, KeyMsg, KillSessionMsg, LogErrorMsg, LogMsg,
+ QueryTerminalSizeMsg, RenamedSessionMsg, RenderMsg,
ServerToClientMsg as ProtoServerToClientMsg, StartWebServerMsg, SwitchSessionMsg,
TerminalPixelDimensionsMsg, TerminalResizeMsg, UnblockCliPipeInputMsg,
UnblockInputThreadMsg, WebServerStartedMsg,
@@ -68,6 +69,11 @@ impl From<ClientToServerMsg> for ProtoClientToServerMsg {
pane_to_focus: pane_to_focus.map(|p| p.into()),
is_web_client,
}),
+ ClientToServerMsg::AttachWatcherClient { terminal_size } => {
+ client_to_server_msg::Message::AttachWatcherClient(AttachWatcherClientMsg {
+ terminal_size: Some(terminal_size.into()),
+ })
+ },
ClientToServerMsg::Action {
action,
terminal_id,
@@ -177,6 +183,14 @@ impl TryFrom<ProtoClientToServerMsg> for ClientToServerMsg {
is_web_client: attach.is_web_client,
})
},
+ Some(client_to_server_msg::Message::AttachWatcherClient(attach_watcher)) => {
+ Ok(ClientToServerMsg::AttachWatcherClient {
+ terminal_size: attach_watcher
+ .terminal_size
+ .ok_or_else(|| anyhow::anyhow!("Missing terminal_size"))?
+ .try_into()?,
+ })
+ },
Some(client_to_server_msg::Message::Action(action)) => Ok(ClientToServerMsg::Action {
action: action
.action