summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-08-14 16:08:40 +0200
committerAram Drevekenin <aram@poor.dev>2024-08-14 16:08:40 +0200
commit357661e0b9ac31ed41b5eaee1106418040365f6e (patch)
tree8f44347dfc824d5c35a838ea009903045c647d06
parentaffbd9237ec3f705d44e9a33236572e241209748 (diff)
feat(plugins): command pane re-run eventcommand-pane-rerun-event
-rw-r--r--zellij-server/src/plugins/wasm_bridge.rs1
-rw-r--r--zellij-server/src/pty.rs42
-rw-r--r--zellij-utils/assets/prost/api.event.rs15
-rw-r--r--zellij-utils/src/data.rs1
-rw-r--r--zellij-utils/src/plugin_api/event.proto7
-rw-r--r--zellij-utils/src/plugin_api/event.rs30
6 files changed, 92 insertions, 4 deletions
diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs
index 768351830..cefa6c504 100644
--- a/zellij-server/src/plugins/wasm_bridge.rs
+++ b/zellij-server/src/plugins/wasm_bridge.rs
@@ -1332,6 +1332,7 @@ fn check_event_permission(
| Event::PaneClosed(..)
| Event::EditPaneOpened(..)
| Event::EditPaneExited(..)
+ | Event::CommandPaneReRun(..)
| Event::InputReceived => PermissionType::ReadApplicationState,
_ => return (PermissionStatus::Granted, None),
};
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 9206804f3..5a910af11 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -10,11 +10,15 @@ use crate::{
};
use async_std::task::{self, JoinHandle};
use std::sync::Arc;
-use std::{collections::HashMap, os::unix::io::RawFd, path::PathBuf};
+use std::{
+ collections::{BTreeMap, HashMap},
+ os::unix::io::RawFd,
+ path::PathBuf,
+};
use zellij_utils::nix::unistd::Pid;
use zellij_utils::{
async_std,
- data::{Event, FloatingPaneCoordinates},
+ data::{Event, FloatingPaneCoordinates, OriginatingPlugin},
errors::prelude::*,
errors::{ContextType, PtyContext},
input::{
@@ -128,6 +132,7 @@ pub(crate) struct Pty {
pub active_panes: HashMap<ClientId, PaneId>,
pub bus: Bus<PtyInstruction>,
pub id_to_child_pid: HashMap<u32, RawFd>, // terminal_id => child raw fd
+ originating_plugins: HashMap<u32, OriginatingPlugin>,
debug_to_file: bool,
task_handles: HashMap<u32, JoinHandle<()>>, // terminal_id to join-handle
default_editor: Option<PathBuf>,
@@ -189,6 +194,8 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
if let Some(originating_plugin) =
run_command.and_then(|r| r.originating_plugin)
{
+ pty.originating_plugins
+ .insert(pid, originating_plugin.clone());
let update_event =
Event::CommandPaneOpened(pid, originating_plugin.context.clone());
pty.bus
@@ -777,6 +784,7 @@ impl Pty {
debug_to_file,
task_handles: HashMap::new(),
default_editor,
+ originating_plugins: HashMap::new(),
}
}
pub fn get_default_terminal(
@@ -1348,19 +1356,37 @@ impl Pty {
pub fn rerun_command_in_pane(
&mut self,
pane_id: PaneId,
- run_command: RunCommand,
+ mut run_command: RunCommand,
) -> Result<()> {
let err_context = || format!("failed to rerun command in pane {:?}", pane_id);
match pane_id {
PaneId::Terminal(id) => {
+ if let Some(originating_plugins) = self.originating_plugins.get(&id) {
+ run_command.originating_plugin = Some(originating_plugins.clone());
+ }
let _ = self.task_handles.remove(&id); // if all is well, this shouldn't be here
let _ = self.id_to_child_pid.remove(&id); // if all is wlel, this shouldn't be here
let hold_on_close = run_command.hold_on_close;
+ let originating_plugin = Arc::new(run_command.originating_plugin.clone());
let quit_cb = Box::new({
let senders = self.bus.senders.clone();
move |pane_id, exit_status, command| {
+ if let PaneId::Terminal(pane_id) = pane_id {
+ if let Some(originating_plugin) = originating_plugin.as_ref() {
+ let update_event = Event::CommandPaneExited(
+ pane_id,
+ exit_status,
+ originating_plugin.context.clone(),
+ );
+ let _ = senders.send_to_plugin(PluginInstruction::Update(vec![(
+ Some(originating_plugin.plugin_id),
+ Some(originating_plugin.client_id),
+ update_event,
+ )]));
+ }
+ }
if hold_on_close {
let _ = senders.send_to_screen(ScreenInstruction::HoldPane(
pane_id,
@@ -1407,6 +1433,16 @@ impl Pty {
self.task_handles.insert(id, terminal_bytes);
self.id_to_child_pid.insert(id, child_fd);
+ if let Some(originating_plugin) = self.originating_plugins.get(&id) {
+ self.bus
+ .senders
+ .send_to_plugin(PluginInstruction::Update(vec![(
+ Some(originating_plugin.plugin_id),
+ Some(originating_plugin.client_id),
+ Event::CommandPaneReRun(id, originating_plugin.context.clone()),
+ )]))
+ .with_context(err_context)?;
+ }
Ok(())
},
_ => Err(anyhow!("cannot respawn plugin panes")).with_context(err_context),
diff --git a/zellij-utils/assets/prost/api.event.rs b/zellij-utils/assets/prost/api.event.rs
index 988339bff..11ab070bf 100644
--- a/zellij-utils/assets/prost/api.event.rs
+++ b/zellij-utils/assets/prost/api.event.rs
@@ -11,7 +11,7 @@ pub struct Event {
pub name: i32,
#[prost(
oneof = "event::Payload",
- tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20"
+ tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21"
)]
pub payload: ::core::option::Option<event::Payload>,
}
@@ -58,10 +58,20 @@ pub mod event {
EditPaneOpenedPayload(super::EditPaneOpenedPayload),
#[prost(message, tag = "20")]
EditPaneExitedPayload(super::EditPaneExitedPayload),
+ #[prost(message, tag = "21")]
+ CommandPaneRerunPayload(super::CommandPaneReRunPayload),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct CommandPaneReRunPayload {
+ #[prost(uint32, tag = "1")]
+ pub terminal_pane_id: u32,
+ #[prost(message, repeated, tag = "3")]
+ pub context: ::prost::alloc::vec::Vec<ContextItem>,
+}
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PaneClosedPayload {
#[prost(message, optional, tag = "1")]
pub pane_id: ::core::option::Option<PaneId>,
@@ -415,6 +425,7 @@ pub enum EventType {
PaneClosed = 21,
EditPaneOpened = 22,
EditPaneExited = 23,
+ CommandPaneReRun = 24,
}
impl EventType {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -447,6 +458,7 @@ impl EventType {
EventType::PaneClosed => "PaneClosed",
EventType::EditPaneOpened => "EditPaneOpened",
EventType::EditPaneExited => "EditPaneExited",
+ EventType::CommandPaneReRun => "CommandPaneReRun",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -476,6 +488,7 @@ impl EventType {
"PaneClosed" => Some(Self::PaneClosed),
"EditPaneOpened" => Some(Self::EditPaneOpened),
"EditPaneExited" => Some(Self::EditPaneExited),
+ "CommandPaneReRun" => Some(Self::CommandPaneReRun),
_ => None,
}
}
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index d7dd89732..f03c01cf2 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -919,6 +919,7 @@ pub enum Event {
PaneClosed(PaneId),
EditPaneOpened(u32, Context), // u32 - terminal_pane_id
EditPaneExited(u32, Option<i32>, Context), // u32 - terminal_pane_id, Option<i32> - exit code
+ CommandPaneReRun(u32, Context), // u32 - terminal_pane_id, Option<i32> -
}
#[derive(
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index 1be5ced61..610a3ac40 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -47,6 +47,7 @@ enum EventType {
PaneClosed = 21;
EditPaneOpened = 22;
EditPaneExited = 23;
+ CommandPaneReRun = 24;
}
message EventNameList {
@@ -75,9 +76,15 @@ message Event {
PaneClosedPayload pane_closed_payload = 18;
EditPaneOpenedPayload edit_pane_opened_payload = 19;
EditPaneExitedPayload edit_pane_exited_payload = 20;
+ CommandPaneReRunPayload command_pane_rerun_payload = 21;
}
}
+message CommandPaneReRunPayload {
+ uint32 terminal_pane_id = 1;
+ repeated ContextItem context = 3;
+}
+
message PaneClosedPayload {
PaneId pane_id = 1;
}
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index 9dad19e93..b669a6729 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -299,6 +299,19 @@ impl TryFrom<ProtobufEvent> for Event {
},
_ => Err("Malformed payload for the EditPaneExited Event"),
},
+ Some(ProtobufEventType::CommandPaneReRun) => match protobuf_event.payload {
+ Some(ProtobufEventPayload::CommandPaneRerunPayload(command_pane_rerun_payload)) => {
+ Ok(Event::CommandPaneReRun(
+ command_pane_rerun_payload.terminal_pane_id,
+ command_pane_rerun_payload
+ .context
+ .into_iter()
+ .map(|c_i| (c_i.name, c_i.value))
+ .collect(),
+ ))
+ },
+ _ => Err("Malformed payload for the CommandPaneReRun Event"),
+ },
None => Err("Unknown Protobuf Event"),
}
}
@@ -592,6 +605,21 @@ impl TryFrom<Event> for ProtobufEvent {
)),
})
},
+ Event::CommandPaneReRun(terminal_pane_id, context) => {
+ let command_pane_rerun_payload = CommandPaneReRunPayload {
+ terminal_pane_id,
+ context: context
+ .into_iter()
+ .map(|(name, value)| ContextItem { name, value })
+ .collect(),
+ };
+ Ok(ProtobufEvent {
+ name: ProtobufEventType::CommandPaneReRun as i32,
+ payload: Some(event::Payload::CommandPaneRerunPayload(
+ command_pane_rerun_payload,
+ )),
+ })
+ },
}
}
}
@@ -1100,6 +1128,7 @@ impl TryFrom<ProtobufEventType> for EventType {
ProtobufEventType::PaneClosed => EventType::PaneClosed,
ProtobufEventType::EditPaneOpened => EventType::EditPaneOpened,
ProtobufEventType::EditPaneExited => EventType::EditPaneExited,
+ ProtobufEventType::CommandPaneReRun => EventType::CommandPaneReRun,
})
}
}
@@ -1132,6 +1161,7 @@ impl TryFrom<EventType> for ProtobufEventType {
EventType::PaneClosed => ProtobufEventType::PaneClosed,
EventType::EditPaneOpened => ProtobufEventType::EditPaneOpened,
EventType::EditPaneExited => ProtobufEventType::EditPaneExited,
+ EventType::CommandPaneReRun => ProtobufEventType::CommandPaneReRun,
})
}
}