aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-server
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2026-03-08 21:18:05 +0100
committerGitHub <noreply@github.com>2026-03-08 21:18:05 +0100
commita8d99b64a3fe73284b0954da7daabf04da1c432d (patch)
treec03e80df9f2673253d402cc9077741694390c97e /zellij-server
parentAllow subscribing to pane viewport updates (renders) from the CLI (#4814) (diff)
downloadsl0ppij-a8d99b64a3fe73284b0954da7daabf04da1c432d.tar.gz
sl0ppij-a8d99b64a3fe73284b0954da7daabf04da1c432d.tar.xz
sl0ppij-a8d99b64a3fe73284b0954da7daabf04da1c432d.zip
Add cli paste action (#4817)
* add cli paste action * add pr
Diffstat (limited to 'zellij-server')
-rw-r--r--zellij-server/src/route.rs14
-rw-r--r--zellij-server/src/screen.rs27
-rw-r--r--zellij-server/src/tab/mod.rs29
3 files changed, 70 insertions, 0 deletions
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 540f398f..4289cb6d 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -277,6 +277,20 @@ pub(crate) fn route_action(
))
.with_context(err_context)?;
},
+ Action::Paste { chars, pane_id } => {
+ senders
+ .send_to_screen(ScreenInstruction::ClearScroll(client_id))
+ .with_context(err_context)?;
+ let bytes = chars.into_bytes();
+ senders
+ .send_to_screen(ScreenInstruction::Paste(
+ bytes,
+ pane_id.map(|p| p.into()),
+ client_id,
+ Some(NotificationEnd::new(completion_tx)),
+ ))
+ .with_context(err_context)?;
+ },
Action::SetPaneColor { pane_id, fg, bg } => {
senders
.send_to_screen(ScreenInstruction::SetPaneColor(
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index c907cfd6..8ebe10c5 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -602,6 +602,7 @@ pub enum ScreenInstruction {
ResizePaneWithId(ResizeStrategy, PaneId),
EditScrollbackForPaneWithId(PaneId, Option<NotificationEnd>),
WriteToPaneId(Vec<u8>, PaneId, Option<NotificationEnd>),
+ Paste(Vec<u8>, Option<PaneId>, ClientId, Option<NotificationEnd>),
SetPaneColor(
PaneId,
Option<String>,
@@ -891,6 +892,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenContext::EditScrollbackForPaneWithId
},
ScreenInstruction::WriteToPaneId(..) => ScreenContext::WriteToPaneId,
+ ScreenInstruction::Paste(..) => ScreenContext::Paste,
ScreenInstruction::SetPaneColor(..) => ScreenContext::SetPaneColor,
ScreenInstruction::WriteKeyToPaneId(..) => ScreenContext::WriteKeyToPaneId,
ScreenInstruction::CopyTextToClipboard(..) => ScreenContext::CopyTextToClipboard,
@@ -7395,6 +7397,31 @@ pub(crate) fn screen_thread_main(
}
screen.render(None)?;
},
+ ScreenInstruction::Paste(bytes, pane_id, client_id, _completion) => {
+ match pane_id {
+ Some(pane_id) => {
+ let all_tabs = screen.get_tabs_mut();
+ for tab in all_tabs.values_mut() {
+ if tab.has_pane_with_pid(&pane_id) {
+ tab.paste_to_pane_id(bytes, pane_id, _completion)
+ .non_fatal();
+ break;
+ }
+ }
+ },
+ None => {
+ active_tab_and_connected_client_id!(
+ screen,
+ client_id,
+ |tab: &mut Tab, _client_id: ClientId| {
+ tab.paste_to_active_terminal(bytes, client_id, _completion)
+ .non_fatal();
+ }
+ );
+ },
+ }
+ screen.render(None)?;
+ },
ScreenInstruction::SetPaneColor(pane_id, fg, bg, _completion) => {
let all_tabs = screen.get_tabs_mut();
for tab in all_tabs.values_mut() {
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 7ade6b68..fba48de1 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -2803,6 +2803,35 @@ impl Tab {
Ok(())
}
+ pub fn paste_to_pane_id(
+ &mut self,
+ bytes: Vec<u8>,
+ pane_id: PaneId,
+ completion: Option<NotificationEnd>,
+ ) -> Result<()> {
+ let bracketed_paste_begin = vec![27, 91, 50, 48, 48, 126];
+ let bracketed_paste_end = vec![27, 91, 50, 48, 49, 126];
+
+ self.write_to_pane_id(&None, bracketed_paste_begin, false, pane_id, None, None)?;
+ self.write_to_pane_id(&None, bytes, false, pane_id, None, None)?;
+ self.write_to_pane_id(&None, bracketed_paste_end, false, pane_id, None, completion)?;
+ Ok(())
+ }
+
+ pub fn paste_to_active_terminal(
+ &mut self,
+ bytes: Vec<u8>,
+ client_id: ClientId,
+ completion: Option<NotificationEnd>,
+ ) -> Result<()> {
+ let err_context = || format!("failed to paste to active terminal for client {client_id}");
+ let active_pane_id = self
+ .get_active_pane_id(client_id)
+ .ok_or_else(|| anyhow!("no active pane for client {client_id}"))
+ .with_context(err_context)?;
+ self.paste_to_pane_id(bytes, active_pane_id, completion)
+ }
+
pub fn write_to_pane_id(
&mut self,
key_with_modifier: &Option<KeyWithModifier>,