summaryrefslogtreecommitdiffstats
path: root/zellij-utils
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-11-04 11:20:50 +0100
committerGitHub <noreply@github.com>2023-11-04 11:20:50 +0100
commit4c6b03acc16c968663d2875556aae25ef6dac87c (patch)
tree679530bd592cd7e5bfcedbc4e3f49708618b4886 /zellij-utils
parent37bc6364fa0a906616b1abafceb84e2c8511045d (diff)
feat(sessions): resurrect sessions through the session-manager (and plugin API) (#2902)
* working with table and scrolling * ui and functionality complete * fix formatting * refactor: background jobs * style(fmt): rustfmt
Diffstat (limited to 'zellij-utils')
-rw-r--r--zellij-utils/assets/prost/api.event.rs10
-rw-r--r--zellij-utils/assets/prost/api.plugin_command.rs10
-rw-r--r--zellij-utils/src/data.rs8
-rw-r--r--zellij-utils/src/plugin_api/event.proto6
-rw-r--r--zellij-utils/src/plugin_api/event.rs43
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto3
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs15
7 files changed, 89 insertions, 6 deletions
diff --git a/zellij-utils/assets/prost/api.event.rs b/zellij-utils/assets/prost/api.event.rs
index 0f6221dfc..c095bed21 100644
--- a/zellij-utils/assets/prost/api.event.rs
+++ b/zellij-utils/assets/prost/api.event.rs
@@ -55,6 +55,8 @@ pub mod event {
pub struct SessionUpdatePayload {
#[prost(message, repeated, tag = "1")]
pub session_manifests: ::prost::alloc::vec::Vec<SessionManifest>,
+ #[prost(message, repeated, tag = "2")]
+ pub resurrectable_sessions: ::prost::alloc::vec::Vec<ResurrectableSession>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -173,6 +175,14 @@ pub struct SessionManifest {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct ResurrectableSession {
+ #[prost(string, tag = "1")]
+ pub name: ::prost::alloc::string::String,
+ #[prost(uint64, tag = "2")]
+ pub creation_time: u64,
+}
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
pub struct PaneInfo {
#[prost(uint32, tag = "1")]
pub id: u32,
diff --git a/zellij-utils/assets/prost/api.plugin_command.rs b/zellij-utils/assets/prost/api.plugin_command.rs
index a97032b40..f0d2fe02f 100644
--- a/zellij-utils/assets/prost/api.plugin_command.rs
+++ b/zellij-utils/assets/prost/api.plugin_command.rs
@@ -5,7 +5,7 @@ pub struct PluginCommand {
pub name: i32,
#[prost(
oneof = "plugin_command::Payload",
- tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44"
+ tags = "2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45"
)]
pub payload: ::core::option::Option<plugin_command::Payload>,
}
@@ -100,6 +100,8 @@ pub mod plugin_command {
RunCommandPayload(super::RunCommandPayload),
#[prost(message, tag = "44")]
WebRequestPayload(super::WebRequestPayload),
+ #[prost(string, tag = "45")]
+ DeleteDeadSessionPayload(::prost::alloc::string::String),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
@@ -311,6 +313,8 @@ pub enum CommandName {
OpenFileInPlace = 70,
RunCommand = 71,
WebRequest = 72,
+ DeleteDeadSession = 73,
+ DeleteAllDeadSessions = 74,
}
impl CommandName {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -392,6 +396,8 @@ impl CommandName {
CommandName::OpenFileInPlace => "OpenFileInPlace",
CommandName::RunCommand => "RunCommand",
CommandName::WebRequest => "WebRequest",
+ CommandName::DeleteDeadSession => "DeleteDeadSession",
+ CommandName::DeleteAllDeadSessions => "DeleteAllDeadSessions",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -470,6 +476,8 @@ impl CommandName {
"OpenFileInPlace" => Some(Self::OpenFileInPlace),
"RunCommand" => Some(Self::RunCommand),
"WebRequest" => Some(Self::WebRequest),
+ "DeleteDeadSession" => Some(Self::DeleteDeadSession),
+ "DeleteAllDeadSessions" => Some(Self::DeleteAllDeadSessions),
_ => None,
}
}
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index 91cf13087..82daf118d 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -6,6 +6,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt;
use std::path::{Path, PathBuf};
use std::str::FromStr;
+use std::time::Duration;
use strum_macros::{Display, EnumDiscriminants, EnumIter, EnumString, ToString};
pub type ClientId = u16; // TODO: merge with crate type?
@@ -495,7 +496,10 @@ pub enum Event {
FileSystemDelete(Vec<PathBuf>),
/// A Result of plugin permission request
PermissionRequestResult(PermissionStatus),
- SessionUpdate(Vec<SessionInfo>),
+ SessionUpdate(
+ Vec<SessionInfo>,
+ Vec<(String, Duration)>, // resurrectable sessions
+ ),
RunCommandResult(Option<i32>, Vec<u8>, Vec<u8>, BTreeMap<String, String>), // exit_code, STDOUT, STDERR,
// context
WebRequestResult(
@@ -1082,6 +1086,8 @@ pub enum PluginCommand {
ReportPanic(String), // stringified panic
RequestPluginPermissions(Vec<PermissionType>),
SwitchSession(ConnectToSession),
+ DeleteDeadSession(String), // String -> session name
+ DeleteAllDeadSessions, // String -> session name
OpenTerminalInPlace(FileToOpen), // only used for the path as cwd
OpenFileInPlace(FileToOpen),
OpenCommandPaneInPlace(CommandToRun),
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index cfffe06f5..0d964a354 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -70,6 +70,7 @@ message Event {
message SessionUpdatePayload {
repeated SessionManifest session_manifests = 1;
+ repeated ResurrectableSession resurrectable_sessions = 2;
}
message RunCommandResultPayload {
@@ -153,6 +154,11 @@ message SessionManifest {
bool is_current_session = 5;
}
+message ResurrectableSession {
+ string name = 1;
+ uint64 creation_time = 2;
+}
+
message PaneInfo {
uint32 id = 1;
bool is_plugin = 2;
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index a322ec3bf..d9e5341d6 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -6,6 +6,7 @@ pub use super::generated_api::api::{
EventType as ProtobufEventType, InputModeKeybinds as ProtobufInputModeKeybinds,
KeyBind as ProtobufKeyBind, ModeUpdatePayload as ProtobufModeUpdatePayload,
PaneInfo as ProtobufPaneInfo, PaneManifest as ProtobufPaneManifest,
+ ResurrectableSession as ProtobufResurrectableSession,
SessionManifest as ProtobufSessionManifest, TabInfo as ProtobufTabInfo, *,
},
input_mode::InputMode as ProtobufInputMode,
@@ -23,6 +24,7 @@ use crate::input::actions::Action;
use std::collections::{HashMap, HashSet};
use std::convert::TryFrom;
use std::path::PathBuf;
+use std::time::Duration;
impl TryFrom<ProtobufEvent> for Event {
type Error = &'static str;
@@ -176,10 +178,19 @@ impl TryFrom<ProtobufEvent> for Event {
protobuf_session_update_payload,
)) => {
let mut session_infos: Vec<SessionInfo> = vec![];
+ let mut resurrectable_sessions: Vec<(String, Duration)> = vec![];
for protobuf_session_info in protobuf_session_update_payload.session_manifests {
session_infos.push(SessionInfo::try_from(protobuf_session_info)?);
}
- Ok(Event::SessionUpdate(session_infos))
+ for protobuf_resurrectable_session in
+ protobuf_session_update_payload.resurrectable_sessions
+ {
+ resurrectable_sessions.push(protobuf_resurrectable_session.into());
+ }
+ Ok(Event::SessionUpdate(
+ session_infos,
+ resurrectable_sessions.into(),
+ ))
},
_ => Err("Malformed payload for the SessionUpdate Event"),
},
@@ -359,13 +370,18 @@ impl TryFrom<Event> for ProtobufEvent {
)),
})
},
- Event::SessionUpdate(session_infos) => {
+ Event::SessionUpdate(session_infos, resurrectable_sessions) => {
let mut protobuf_session_manifests = vec![];
for session_info in session_infos {
protobuf_session_manifests.push(session_info.try_into()?);
}
+ let mut protobuf_resurrectable_sessions = vec![];
+ for resurrectable_session in resurrectable_sessions {
+ protobuf_resurrectable_sessions.push(resurrectable_session.into());
+ }
let session_update_payload = SessionUpdatePayload {
session_manifests: protobuf_session_manifests,
+ resurrectable_sessions: protobuf_resurrectable_sessions,
};
Ok(ProtobufEvent {
name: ProtobufEventType::SessionUpdate as i32,
@@ -887,6 +903,24 @@ impl TryFrom<EventType> for ProtobufEventType {
}
}
+impl From<ProtobufResurrectableSession> for (String, Duration) {
+ fn from(protobuf_resurrectable_session: ProtobufResurrectableSession) -> (String, Duration) {
+ (
+ protobuf_resurrectable_session.name,
+ Duration::from_secs(protobuf_resurrectable_session.creation_time),
+ )
+ }
+}
+
+impl From<(String, Duration)> for ProtobufResurrectableSession {
+ fn from(session_name_and_creation_time: (String, Duration)) -> ProtobufResurrectableSession {
+ ProtobufResurrectableSession {
+ name: session_name_and_creation_time.0,
+ creation_time: session_name_and_creation_time.1.as_secs(),
+ }
+ }
+}
+
#[test]
fn serialize_mode_update_event() {
use prost::Message;
@@ -1249,7 +1283,7 @@ fn serialize_file_system_delete_event() {
#[test]
fn serialize_session_update_event() {
use prost::Message;
- let session_update_event = Event::SessionUpdate(Default::default());
+ let session_update_event = Event::SessionUpdate(Default::default(), Default::default());
let protobuf_event: ProtobufEvent = session_update_event.clone().try_into().unwrap();
let serialized_protobuf_event = protobuf_event.encode_to_vec();
let deserialized_protobuf_event: ProtobufEvent =
@@ -1360,8 +1394,9 @@ fn serialize_session_update_event_with_non_default_values() {
is_current_session: false,
};
let session_infos = vec![session_info_1, session_info_2];
+ let resurrectable_sessions = vec![];
- let session_update_event = Event::SessionUpdate(session_infos);
+ let session_update_event = Event::SessionUpdate(session_infos, resurrectable_sessions);
let protobuf_event: ProtobufEvent = session_update_event.clone().try_into().unwrap();
let serialized_protobuf_event = protobuf_event.encode_to_vec();
let deserialized_protobuf_event: ProtobufEvent =
diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto
index 93e7d6b2b..0b950ff0e 100644
--- a/zellij-utils/src/plugin_api/plugin_command.proto
+++ b/zellij-utils/src/plugin_api/plugin_command.proto
@@ -84,6 +84,8 @@ enum CommandName {
OpenFileInPlace = 70;
RunCommand = 71;
WebRequest = 72;
+ DeleteDeadSession = 73;
+ DeleteAllDeadSessions = 74;
}
message PluginCommand {
@@ -132,6 +134,7 @@ message PluginCommand {
OpenCommandPanePayload open_command_pane_in_place_payload = 42;
RunCommandPayload run_command_payload = 43;
WebRequestPayload web_request_payload = 44;
+ string delete_dead_session_payload = 45;
}
}
diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs
index 84c083ad5..6b70b18eb 100644
--- a/zellij-utils/src/plugin_api/plugin_command.rs
+++ b/zellij-utils/src/plugin_api/plugin_command.rs
@@ -628,6 +628,13 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
},
_ => Err("Mismatched payload for WebRequest"),
},
+ Some(CommandName::DeleteDeadSession) => match protobuf_plugin_command.payload {
+ Some(Payload::DeleteDeadSessionPayload(dead_session_name)) => {
+ Ok(PluginCommand::DeleteDeadSession(dead_session_name))
+ },
+ _ => Err("Mismatched payload for DeleteDeadSession"),
+ },
+ Some(CommandName::DeleteAllDeadSessions) => Ok(PluginCommand::DeleteAllDeadSessions),
None => Err("Unrecognized plugin command"),
}
}
@@ -1044,6 +1051,14 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
})),
})
},
+ PluginCommand::DeleteDeadSession(dead_session_name) => Ok(ProtobufPluginCommand {
+ name: CommandName::DeleteDeadSession as i32,
+ payload: Some(Payload::DeleteDeadSessionPayload(dead_session_name)),
+ }),
+ PluginCommand::DeleteAllDeadSessions => Ok(ProtobufPluginCommand {
+ name: CommandName::DeleteAllDeadSessions as i32,
+ payload: None,
+ }),
}
}
}