diff options
author | Aram Drevekenin <aram@poor.dev> | 2024-08-14 16:08:40 +0200 |
---|---|---|
committer | Aram Drevekenin <aram@poor.dev> | 2024-08-14 16:08:40 +0200 |
commit | 357661e0b9ac31ed41b5eaee1106418040365f6e (patch) | |
tree | 8f44347dfc824d5c35a838ea009903045c647d06 | |
parent | affbd9237ec3f705d44e9a33236572e241209748 (diff) |
feat(plugins): command pane re-run eventcommand-pane-rerun-event
-rw-r--r-- | zellij-server/src/plugins/wasm_bridge.rs | 1 | ||||
-rw-r--r-- | zellij-server/src/pty.rs | 42 | ||||
-rw-r--r-- | zellij-utils/assets/prost/api.event.rs | 15 | ||||
-rw-r--r-- | zellij-utils/src/data.rs | 1 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/event.proto | 7 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/event.rs | 30 |
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, }) } } |