diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-11-04 11:20:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-04 11:20:50 +0100 |
commit | 4c6b03acc16c968663d2875556aae25ef6dac87c (patch) | |
tree | 679530bd592cd7e5bfcedbc4e3f49708618b4886 /zellij-utils | |
parent | 37bc6364fa0a906616b1abafceb84e2c8511045d (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.rs | 10 | ||||
-rw-r--r-- | zellij-utils/assets/prost/api.plugin_command.rs | 10 | ||||
-rw-r--r-- | zellij-utils/src/data.rs | 8 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/event.proto | 6 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/event.rs | 43 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.proto | 3 | ||||
-rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.rs | 15 |
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, + }), } } } |