summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-03-26 17:47:03 +0100
committerAram Drevekenin <aram@poor.dev>2024-03-26 17:47:03 +0100
commitab0804dc97e72189b8552a493a138952c2bca226 (patch)
treee86909cdfce996d08442c5152fa4bacdbf203745
parentb24dd87b8044be59a9897bb19604deee85b236b0 (diff)
feat(plugins): add api to dump the current session layout to a plugindump-layout-to-plugin
-rw-r--r--zellij-server/src/plugins/mod.rs29
-rw-r--r--zellij-server/src/plugins/zellij_exports.rs10
-rw-r--r--zellij-server/src/pty.rs16
-rw-r--r--zellij-server/src/screen.rs18
-rw-r--r--zellij-tile/src/shim.rs8
-rw-r--r--zellij-utils/assets/prost/api.plugin_command.rs3
-rw-r--r--zellij-utils/src/data.rs1
-rw-r--r--zellij-utils/src/errors.rs3
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto1
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs8
10 files changed, 95 insertions, 2 deletions
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs
index 44e88ae0f..e55168939 100644
--- a/zellij-server/src/plugins/mod.rs
+++ b/zellij-server/src/plugins/mod.rs
@@ -37,6 +37,7 @@ use zellij_utils::{
},
ipc::ClientAttributes,
pane_size::Size,
+ session_serialization,
};
pub type PluginId = u32;
@@ -104,6 +105,7 @@ pub enum PluginInstruction {
Option<PathBuf>,
),
DumpLayout(SessionLayoutMetadata, ClientId),
+ DumpLayoutToPlugin(SessionLayoutMetadata, PluginId),
LogLayoutToHd(SessionLayoutMetadata),
CliPipe {
pipe_id: String,
@@ -178,6 +180,7 @@ impl From<&PluginInstruction> for PluginContext {
PluginInstruction::UnblockCliPipes { .. } => PluginContext::UnblockCliPipes,
PluginInstruction::WatchFilesystem => PluginContext::WatchFilesystem,
PluginInstruction::KeybindPipe { .. } => PluginContext::KeybindPipe,
+ PluginInstruction::DumpLayoutToPlugin(..) => PluginContext::DumpLayoutToPlugin,
}
}
}
@@ -484,6 +487,32 @@ pub(crate) fn plugin_thread_main(
client_id,
)));
},
+ PluginInstruction::DumpLayoutToPlugin(mut session_layout_metadata, plugin_id) => {
+ populate_session_layout_metadata(&mut session_layout_metadata, &wasm_bridge);
+ match session_serialization::serialize_session_layout(
+ session_layout_metadata.into(),
+ ) {
+ Ok((layout, _pane_contents)) => {
+ let updates = vec![(
+ Some(plugin_id),
+ None,
+ Event::CustomMessage("session_layout".to_owned(), layout),
+ )];
+ wasm_bridge.update_plugins(updates, shutdown_send.clone())?;
+ },
+ Err(e) => {
+ let updates = vec![(
+ Some(plugin_id),
+ None,
+ Event::CustomMessage(
+ "session_layout_error".to_owned(),
+ format!("{}", e),
+ ),
+ )];
+ wasm_bridge.update_plugins(updates, shutdown_send.clone())?;
+ },
+ }
+ },
PluginInstruction::LogLayoutToHd(mut session_layout_metadata) => {
populate_session_layout_metadata(&mut session_layout_metadata, &wasm_bridge);
drop(
diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs
index 65c18e16b..1f65fad54 100644
--- a/zellij-server/src/plugins/zellij_exports.rs
+++ b/zellij-server/src/plugins/zellij_exports.rs
@@ -263,6 +263,7 @@ fn host_run_plugin_command(env: FunctionEnvMut<ForeignFunctionEnv>) {
scan_host_folder(env, folder_to_scan)
},
PluginCommand::WatchFilesystem => watch_filesystem(env),
+ PluginCommand::DumpSessionLayout => dump_session_layout(env),
},
(PermissionStatus::Denied, permission) => {
log::error!(
@@ -1340,6 +1341,14 @@ fn watch_filesystem(env: &ForeignFunctionEnv) {
.map(|sender| sender.send(PluginInstruction::WatchFilesystem));
}
+fn dump_session_layout(env: &ForeignFunctionEnv) {
+ let _ = env.plugin_env.senders.to_screen.as_ref().map(|sender| {
+ sender.send(ScreenInstruction::DumpLayoutToPlugin(
+ env.plugin_env.plugin_id,
+ ))
+ });
+}
+
fn scan_host_folder(env: &ForeignFunctionEnv, folder_to_scan: PathBuf) {
if !folder_to_scan.starts_with("/host") {
log::error!(
@@ -1542,6 +1551,7 @@ fn check_command_permission(
| PluginCommand::BlockCliPipeInput(..)
| PluginCommand::CliPipeOutput(..) => PermissionType::ReadCliPipes,
PluginCommand::MessageToPlugin(..) => PermissionType::MessageAndLaunchOtherPlugins,
+ PluginCommand::DumpSessionLayout => PermissionType::ReadApplicationState,
_ => return (PermissionStatus::Granted, None),
};
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index cc219f372..c4e810536 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -2,7 +2,7 @@ use crate::background_jobs::BackgroundJob;
use crate::terminal_bytes::TerminalBytes;
use crate::{
panes::PaneId,
- plugins::PluginInstruction,
+ plugins::{PluginId, PluginInstruction},
screen::ScreenInstruction,
session_layout_metadata::SessionLayoutMetadata,
thread_bus::{Bus, ThreadSenders},
@@ -77,6 +77,7 @@ pub enum PtyInstruction {
ClientTabIndexOrPaneId,
), // String is an optional pane name
DumpLayout(SessionLayoutMetadata, ClientId),
+ DumpLayoutToPlugin(SessionLayoutMetadata, PluginId),
LogLayoutToHd(SessionLayoutMetadata),
FillPluginCwd(
Option<bool>, // should float
@@ -110,6 +111,7 @@ impl From<&PtyInstruction> for PtyContext {
PtyInstruction::DropToShellInPane { .. } => PtyContext::DropToShellInPane,
PtyInstruction::SpawnInPlaceTerminal(..) => PtyContext::SpawnInPlaceTerminal,
PtyInstruction::DumpLayout(..) => PtyContext::DumpLayout,
+ PtyInstruction::DumpLayoutToPlugin(..) => PtyContext::DumpLayoutToPlugin,
PtyInstruction::LogLayoutToHd(..) => PtyContext::LogLayoutToHd,
PtyInstruction::FillPluginCwd(..) => PtyContext::FillPluginCwd,
PtyInstruction::Exit => PtyContext::Exit,
@@ -630,6 +632,18 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
},
}
},
+ PtyInstruction::DumpLayoutToPlugin(mut session_layout_metadata, plugin_id) => {
+ let err_context = || format!("Failed to dump layout");
+ pty.populate_session_layout_metadata(&mut session_layout_metadata);
+ pty.bus
+ .senders
+ .send_to_plugin(PluginInstruction::DumpLayoutToPlugin(
+ session_layout_metadata,
+ plugin_id,
+ ))
+ .with_context(err_context)
+ .non_fatal();
+ },
PtyInstruction::LogLayoutToHd(mut session_layout_metadata) => {
let err_context = || format!("Failed to dump layout");
pty.populate_session_layout_metadata(&mut session_layout_metadata);
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 35ec8fee5..5384987de 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -36,7 +36,7 @@ use crate::{
output::Output,
panes::sixel::SixelImageStore,
panes::PaneId,
- plugins::{PluginInstruction, PluginRenderAsset},
+ plugins::{PluginId, PluginInstruction, PluginRenderAsset},
pty::{ClientTabIndexOrPaneId, PtyInstruction, VteBytes},
tab::Tab,
thread_bus::Bus,
@@ -180,6 +180,7 @@ pub enum ScreenInstruction {
DumpScreen(String, ClientId, bool),
DumpLayout(Option<PathBuf>, ClientId), // PathBuf is the default configured
// shell
+ DumpLayoutToPlugin(PluginId),
EditScrollback(ClientId),
ScrollUp(ClientId),
ScrollUpAt(Position, ClientId),
@@ -421,6 +422,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::ClearScreen(..) => ScreenContext::ClearScreen,
ScreenInstruction::DumpScreen(..) => ScreenContext::DumpScreen,
ScreenInstruction::DumpLayout(..) => ScreenContext::DumpLayout,
+ ScreenInstruction::DumpLayoutToPlugin(..) => ScreenContext::DumpLayoutToPlugin,
ScreenInstruction::EditScrollback(..) => ScreenContext::EditScrollback,
ScreenInstruction::ScrollUp(..) => ScreenContext::ScrollUp,
ScreenInstruction::ScrollDown(..) => ScreenContext::ScrollDown,
@@ -2630,6 +2632,20 @@ pub(crate) fn screen_thread_main(
))
.with_context(err_context)?;
},
+ ScreenInstruction::DumpLayoutToPlugin(plugin_id) => {
+ let err_context = || format!("Failed to dump layout");
+ let session_layout_metadata =
+ screen.get_layout_metadata(screen.default_shell.clone());
+ screen
+ .bus
+ .senders
+ .send_to_pty(PtyInstruction::DumpLayoutToPlugin(
+ session_layout_metadata,
+ plugin_id,
+ ))
+ .with_context(err_context)
+ .non_fatal();
+ },
ScreenInstruction::EditScrollback(client_id) => {
active_tab_and_connected_client_id!(
screen,
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index 2d04a7b6a..532a5fafe 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -784,6 +784,14 @@ pub fn watch_filesystem() {
unsafe { host_run_plugin_command() };
}
+/// Get the serialized session layout in KDL format as a CustomMessage Event
+pub fn dump_session_layout() {
+ let plugin_command = PluginCommand::DumpSessionLayout;
+ let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
+ object_to_stdout(&protobuf_plugin_command.encode_to_vec());
+ unsafe { host_run_plugin_command() };
+}
+
// Utility Functions
#[allow(unused)]
diff --git a/zellij-utils/assets/prost/api.plugin_command.rs b/zellij-utils/assets/prost/api.plugin_command.rs
index 5ec93e2e1..ca067fd97 100644
--- a/zellij-utils/assets/prost/api.plugin_command.rs
+++ b/zellij-utils/assets/prost/api.plugin_command.rs
@@ -420,6 +420,7 @@ pub enum CommandName {
KillSessions = 81,
ScanHostFolder = 82,
WatchFilesystem = 83,
+ DumpSessionLayout = 84,
}
impl CommandName {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -512,6 +513,7 @@ impl CommandName {
CommandName::KillSessions => "KillSessions",
CommandName::ScanHostFolder => "ScanHostFolder",
CommandName::WatchFilesystem => "WatchFilesystem",
+ CommandName::DumpSessionLayout => "DumpSessionLayout",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -601,6 +603,7 @@ impl CommandName {
"KillSessions" => Some(Self::KillSessions),
"ScanHostFolder" => Some(Self::ScanHostFolder),
"WatchFilesystem" => Some(Self::WatchFilesystem),
+ "DumpSessionLayout" => Some(Self::DumpSessionLayout),
_ => None,
}
}
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index 379fb126f..78fbbd770 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -1378,4 +1378,5 @@ pub enum PluginCommand {
KillSessions(Vec<String>), // one or more session names
ScanHostFolder(PathBuf), // TODO: rename to ScanHostFolder
WatchFilesystem,
+ DumpSessionLayout,
}
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index d05df3a25..51174b756 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -351,6 +351,7 @@ pub enum ScreenContext {
NewInPlacePluginPane,
DumpLayoutToHd,
RenameSession,
+ DumpLayoutToPlugin,
}
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
@@ -371,6 +372,7 @@ pub enum PtyContext {
DumpLayout,
LogLayoutToHd,
FillPluginCwd,
+ DumpLayoutToPlugin,
Exit,
}
@@ -402,6 +404,7 @@ pub enum PluginContext {
UnblockCliPipes,
WatchFilesystem,
KeybindPipe,
+ DumpLayoutToPlugin,
}
/// Stack call representations corresponding to the different types of [`ClientInstruction`]s.
diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto
index c95111e59..b05c8ac8a 100644
--- a/zellij-utils/src/plugin_api/plugin_command.proto
+++ b/zellij-utils/src/plugin_api/plugin_command.proto
@@ -95,6 +95,7 @@ enum CommandName {
KillSessions = 81;
ScanHostFolder = 82;
WatchFilesystem = 83;
+ DumpSessionLayout = 84;
}
message PluginCommand {
diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs
index e452e53cc..232a9f2dc 100644
--- a/zellij-utils/src/plugin_api/plugin_command.rs
+++ b/zellij-utils/src/plugin_api/plugin_command.rs
@@ -867,6 +867,10 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
Some(_) => Err("WatchFilesystem should have no payload, found a payload"),
None => Ok(PluginCommand::WatchFilesystem),
},
+ Some(CommandName::DumpSessionLayout) => match protobuf_plugin_command.payload {
+ Some(_) => Err("DumpSessionLayout should have no payload, found a payload"),
+ None => Ok(PluginCommand::DumpSessionLayout),
+ },
None => Err("Unrecognized plugin command"),
}
}
@@ -1381,6 +1385,10 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::WatchFilesystem as i32,
payload: None,
}),
+ PluginCommand::DumpSessionLayout => Ok(ProtobufPluginCommand {
+ name: CommandName::DumpSessionLayout as i32,
+ payload: None,
+ }),
}
}
}