mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-25 23:33:08 +03:00
feat(plugins): command pane re-run event (#3553)
This commit is contained in:
parent
affbd9237e
commit
a3ad621dc7
@ -1332,6 +1332,7 @@ fn check_event_permission(
|
||||
| Event::PaneClosed(..)
|
||||
| Event::EditPaneOpened(..)
|
||||
| Event::EditPaneExited(..)
|
||||
| Event::CommandPaneReRun(..)
|
||||
| Event::InputReceived => PermissionType::ReadApplicationState,
|
||||
_ => return (PermissionStatus::Granted, None),
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user