feat(plugins): command pane re-run event (#3553)
This commit is contained in:
parent
affbd9237e
commit
a3ad621dc7
6 changed files with 92 additions and 4 deletions
|
|
@ -1332,6 +1332,7 @@ fn check_event_permission(
|
||||||
| Event::PaneClosed(..)
|
| Event::PaneClosed(..)
|
||||||
| Event::EditPaneOpened(..)
|
| Event::EditPaneOpened(..)
|
||||||
| Event::EditPaneExited(..)
|
| Event::EditPaneExited(..)
|
||||||
|
| Event::CommandPaneReRun(..)
|
||||||
| Event::InputReceived => PermissionType::ReadApplicationState,
|
| Event::InputReceived => PermissionType::ReadApplicationState,
|
||||||
_ => return (PermissionStatus::Granted, None),
|
_ => return (PermissionStatus::Granted, None),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,15 @@ use crate::{
|
||||||
};
|
};
|
||||||
use async_std::task::{self, JoinHandle};
|
use async_std::task::{self, JoinHandle};
|
||||||
use std::sync::Arc;
|
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::nix::unistd::Pid;
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
async_std,
|
async_std,
|
||||||
data::{Event, FloatingPaneCoordinates},
|
data::{Event, FloatingPaneCoordinates, OriginatingPlugin},
|
||||||
errors::prelude::*,
|
errors::prelude::*,
|
||||||
errors::{ContextType, PtyContext},
|
errors::{ContextType, PtyContext},
|
||||||
input::{
|
input::{
|
||||||
|
|
@ -128,6 +132,7 @@ pub(crate) struct Pty {
|
||||||
pub active_panes: HashMap<ClientId, PaneId>,
|
pub active_panes: HashMap<ClientId, PaneId>,
|
||||||
pub bus: Bus<PtyInstruction>,
|
pub bus: Bus<PtyInstruction>,
|
||||||
pub id_to_child_pid: HashMap<u32, RawFd>, // terminal_id => child raw fd
|
pub id_to_child_pid: HashMap<u32, RawFd>, // terminal_id => child raw fd
|
||||||
|
originating_plugins: HashMap<u32, OriginatingPlugin>,
|
||||||
debug_to_file: bool,
|
debug_to_file: bool,
|
||||||
task_handles: HashMap<u32, JoinHandle<()>>, // terminal_id to join-handle
|
task_handles: HashMap<u32, JoinHandle<()>>, // terminal_id to join-handle
|
||||||
default_editor: Option<PathBuf>,
|
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) =
|
if let Some(originating_plugin) =
|
||||||
run_command.and_then(|r| r.originating_plugin)
|
run_command.and_then(|r| r.originating_plugin)
|
||||||
{
|
{
|
||||||
|
pty.originating_plugins
|
||||||
|
.insert(pid, originating_plugin.clone());
|
||||||
let update_event =
|
let update_event =
|
||||||
Event::CommandPaneOpened(pid, originating_plugin.context.clone());
|
Event::CommandPaneOpened(pid, originating_plugin.context.clone());
|
||||||
pty.bus
|
pty.bus
|
||||||
|
|
@ -777,6 +784,7 @@ impl Pty {
|
||||||
debug_to_file,
|
debug_to_file,
|
||||||
task_handles: HashMap::new(),
|
task_handles: HashMap::new(),
|
||||||
default_editor,
|
default_editor,
|
||||||
|
originating_plugins: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_default_terminal(
|
pub fn get_default_terminal(
|
||||||
|
|
@ -1348,19 +1356,37 @@ impl Pty {
|
||||||
pub fn rerun_command_in_pane(
|
pub fn rerun_command_in_pane(
|
||||||
&mut self,
|
&mut self,
|
||||||
pane_id: PaneId,
|
pane_id: PaneId,
|
||||||
run_command: RunCommand,
|
mut run_command: RunCommand,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let err_context = || format!("failed to rerun command in pane {:?}", pane_id);
|
let err_context = || format!("failed to rerun command in pane {:?}", pane_id);
|
||||||
|
|
||||||
match pane_id {
|
match pane_id {
|
||||||
PaneId::Terminal(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.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 _ = 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 hold_on_close = run_command.hold_on_close;
|
||||||
|
let originating_plugin = Arc::new(run_command.originating_plugin.clone());
|
||||||
let quit_cb = Box::new({
|
let quit_cb = Box::new({
|
||||||
let senders = self.bus.senders.clone();
|
let senders = self.bus.senders.clone();
|
||||||
move |pane_id, exit_status, command| {
|
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 {
|
if hold_on_close {
|
||||||
let _ = senders.send_to_screen(ScreenInstruction::HoldPane(
|
let _ = senders.send_to_screen(ScreenInstruction::HoldPane(
|
||||||
pane_id,
|
pane_id,
|
||||||
|
|
@ -1407,6 +1433,16 @@ impl Pty {
|
||||||
|
|
||||||
self.task_handles.insert(id, terminal_bytes);
|
self.task_handles.insert(id, terminal_bytes);
|
||||||
self.id_to_child_pid.insert(id, child_fd);
|
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(())
|
Ok(())
|
||||||
},
|
},
|
||||||
_ => Err(anyhow!("cannot respawn plugin panes")).with_context(err_context),
|
_ => Err(anyhow!("cannot respawn plugin panes")).with_context(err_context),
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub struct Event {
|
||||||
pub name: i32,
|
pub name: i32,
|
||||||
#[prost(
|
#[prost(
|
||||||
oneof = "event::Payload",
|
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>,
|
pub payload: ::core::option::Option<event::Payload>,
|
||||||
}
|
}
|
||||||
|
|
@ -58,10 +58,20 @@ pub mod event {
|
||||||
EditPaneOpenedPayload(super::EditPaneOpenedPayload),
|
EditPaneOpenedPayload(super::EditPaneOpenedPayload),
|
||||||
#[prost(message, tag = "20")]
|
#[prost(message, tag = "20")]
|
||||||
EditPaneExitedPayload(super::EditPaneExitedPayload),
|
EditPaneExitedPayload(super::EditPaneExitedPayload),
|
||||||
|
#[prost(message, tag = "21")]
|
||||||
|
CommandPaneRerunPayload(super::CommandPaneReRunPayload),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
#[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 {
|
pub struct PaneClosedPayload {
|
||||||
#[prost(message, optional, tag = "1")]
|
#[prost(message, optional, tag = "1")]
|
||||||
pub pane_id: ::core::option::Option<PaneId>,
|
pub pane_id: ::core::option::Option<PaneId>,
|
||||||
|
|
@ -415,6 +425,7 @@ pub enum EventType {
|
||||||
PaneClosed = 21,
|
PaneClosed = 21,
|
||||||
EditPaneOpened = 22,
|
EditPaneOpened = 22,
|
||||||
EditPaneExited = 23,
|
EditPaneExited = 23,
|
||||||
|
CommandPaneReRun = 24,
|
||||||
}
|
}
|
||||||
impl EventType {
|
impl EventType {
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
|
@ -447,6 +458,7 @@ impl EventType {
|
||||||
EventType::PaneClosed => "PaneClosed",
|
EventType::PaneClosed => "PaneClosed",
|
||||||
EventType::EditPaneOpened => "EditPaneOpened",
|
EventType::EditPaneOpened => "EditPaneOpened",
|
||||||
EventType::EditPaneExited => "EditPaneExited",
|
EventType::EditPaneExited => "EditPaneExited",
|
||||||
|
EventType::CommandPaneReRun => "CommandPaneReRun",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
|
@ -476,6 +488,7 @@ impl EventType {
|
||||||
"PaneClosed" => Some(Self::PaneClosed),
|
"PaneClosed" => Some(Self::PaneClosed),
|
||||||
"EditPaneOpened" => Some(Self::EditPaneOpened),
|
"EditPaneOpened" => Some(Self::EditPaneOpened),
|
||||||
"EditPaneExited" => Some(Self::EditPaneExited),
|
"EditPaneExited" => Some(Self::EditPaneExited),
|
||||||
|
"CommandPaneReRun" => Some(Self::CommandPaneReRun),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -919,6 +919,7 @@ pub enum Event {
|
||||||
PaneClosed(PaneId),
|
PaneClosed(PaneId),
|
||||||
EditPaneOpened(u32, Context), // u32 - terminal_pane_id
|
EditPaneOpened(u32, Context), // u32 - terminal_pane_id
|
||||||
EditPaneExited(u32, Option<i32>, Context), // u32 - terminal_pane_id, Option<i32> - exit code
|
EditPaneExited(u32, Option<i32>, Context), // u32 - terminal_pane_id, Option<i32> - exit code
|
||||||
|
CommandPaneReRun(u32, Context), // u32 - terminal_pane_id, Option<i32> -
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ enum EventType {
|
||||||
PaneClosed = 21;
|
PaneClosed = 21;
|
||||||
EditPaneOpened = 22;
|
EditPaneOpened = 22;
|
||||||
EditPaneExited = 23;
|
EditPaneExited = 23;
|
||||||
|
CommandPaneReRun = 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EventNameList {
|
message EventNameList {
|
||||||
|
|
@ -75,9 +76,15 @@ message Event {
|
||||||
PaneClosedPayload pane_closed_payload = 18;
|
PaneClosedPayload pane_closed_payload = 18;
|
||||||
EditPaneOpenedPayload edit_pane_opened_payload = 19;
|
EditPaneOpenedPayload edit_pane_opened_payload = 19;
|
||||||
EditPaneExitedPayload edit_pane_exited_payload = 20;
|
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 {
|
message PaneClosedPayload {
|
||||||
PaneId pane_id = 1;
|
PaneId pane_id = 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,19 @@ impl TryFrom<ProtobufEvent> for Event {
|
||||||
},
|
},
|
||||||
_ => Err("Malformed payload for the EditPaneExited 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"),
|
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::PaneClosed => EventType::PaneClosed,
|
||||||
ProtobufEventType::EditPaneOpened => EventType::EditPaneOpened,
|
ProtobufEventType::EditPaneOpened => EventType::EditPaneOpened,
|
||||||
ProtobufEventType::EditPaneExited => EventType::EditPaneExited,
|
ProtobufEventType::EditPaneExited => EventType::EditPaneExited,
|
||||||
|
ProtobufEventType::CommandPaneReRun => EventType::CommandPaneReRun,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1132,6 +1161,7 @@ impl TryFrom<EventType> for ProtobufEventType {
|
||||||
EventType::PaneClosed => ProtobufEventType::PaneClosed,
|
EventType::PaneClosed => ProtobufEventType::PaneClosed,
|
||||||
EventType::EditPaneOpened => ProtobufEventType::EditPaneOpened,
|
EventType::EditPaneOpened => ProtobufEventType::EditPaneOpened,
|
||||||
EventType::EditPaneExited => ProtobufEventType::EditPaneExited,
|
EventType::EditPaneExited => ProtobufEventType::EditPaneExited,
|
||||||
|
EventType::CommandPaneReRun => ProtobufEventType::CommandPaneReRun,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue