Skip to content

Commit

Permalink
implement a dump_screen plugin shim function
Browse files Browse the repository at this point in the history
  • Loading branch information
doy committed Jan 8, 2025
1 parent 3dda02f commit f11f373
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 2 deletions.
11 changes: 11 additions & 0 deletions zellij-server/src/plugins/zellij_exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
},
PluginCommand::WatchFilesystem => watch_filesystem(env),
PluginCommand::DumpSessionLayout => dump_session_layout(env),
PluginCommand::DumpScreen(full) => dump_screen(env, full),
PluginCommand::CloseSelf => close_self(env),
PluginCommand::Reconfigure(new_config, write_config_to_disk) => {
reconfigure(env, new_config, write_config_to_disk)?
Expand Down Expand Up @@ -1496,6 +1497,16 @@ fn dump_session_layout(env: &PluginEnv) {
.map(|sender| sender.send(ScreenInstruction::DumpLayoutToPlugin(env.plugin_id)));
}

fn dump_screen(env: &PluginEnv, full: bool) {
let _ = env.senders.to_screen.as_ref().map(|sender| {
sender.send(ScreenInstruction::DumpScreenToPlugin(
env.plugin_id,
env.client_id,
full,
))
});
}

fn list_clients(env: &PluginEnv) {
let _ = env.senders.to_screen.as_ref().map(|sender| {
sender.send(ScreenInstruction::ListClientsToPlugin(
Expand Down
28 changes: 28 additions & 0 deletions zellij-server/src/screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ pub enum ScreenInstruction {
DumpLayout(Option<PathBuf>, ClientId), // PathBuf is the default configured
// shell
DumpLayoutToPlugin(PluginId),
DumpScreenToPlugin(PluginId, ClientId, bool),
EditScrollback(ClientId),
ScrollUp(ClientId),
ScrollUpAt(Position, ClientId),
Expand Down Expand Up @@ -471,6 +472,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenInstruction::Exit => ScreenContext::Exit,
ScreenInstruction::ClearScreen(..) => ScreenContext::ClearScreen,
ScreenInstruction::DumpScreen(..) => ScreenContext::DumpScreen,
ScreenInstruction::DumpScreenToPlugin(..) => ScreenContext::DumpScreenToPlugin,
ScreenInstruction::DumpLayout(..) => ScreenContext::DumpLayout,
ScreenInstruction::DumpLayoutToPlugin(..) => ScreenContext::DumpLayoutToPlugin,
ScreenInstruction::EditScrollback(..) => ScreenContext::EditScrollback,
Expand Down Expand Up @@ -3161,6 +3163,32 @@ pub(crate) fn screen_thread_main(
screen.render(None)?;
screen.unblock_input()?;
},
ScreenInstruction::DumpScreenToPlugin(plugin_id, client_id, full) => {
let err_context = || format!("Failed to dump screen");
let mut dump = None;
active_tab_and_connected_client_id!(
screen,
client_id,
|tab: &mut Tab, client_id: ClientId| {
if let Some(active_pane) =
tab.get_active_pane_or_floating_pane_mut(client_id)
{
dump = Some(active_pane.dump_screen(full));
}
}
);
if let Some(dump) = dump {
screen
.bus
.senders
.send_to_plugin(PluginInstruction::Update(vec![(
Some(plugin_id),
Some(client_id),
Event::ScreenContents(dump),
)]))
.with_context(err_context)?;
}
},
ScreenInstruction::DumpLayout(default_shell, client_id) => {
let err_context = || format!("Failed to dump layout");
let session_layout_metadata = screen.get_layout_metadata(default_shell);
Expand Down
8 changes: 8 additions & 0 deletions zellij-tile/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,14 @@ pub fn dump_session_layout() {
unsafe { host_run_plugin_command() };
}

/// Get the screen contents as a ScreenContents event
pub fn dump_screen(full: bool) {
let plugin_command = PluginCommand::DumpScreen(full);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
}

/// Get a list of clients, their focused pane and running command or focused plugin back as an
/// Event::ListClients (note: this event must be subscribed to)
pub fn list_clients() {
Expand Down
7 changes: 6 additions & 1 deletion zellij-utils/assets/prost/api.event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, 21, 22, 23, 24, 25"
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"
)]
pub payload: ::core::option::Option<event::Payload>,
}
Expand Down Expand Up @@ -68,6 +68,8 @@ pub mod event {
HostFolderChangedPayload(super::HostFolderChangedPayload),
#[prost(message, tag = "25")]
FailedToChangeHostFolderPayload(super::FailedToChangeHostFolderPayload),
#[prost(string, tag = "26")]
ScreenContentsPayload(::prost::alloc::string::String),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down Expand Up @@ -486,6 +488,7 @@ pub enum EventType {
ListClients = 26,
HostFolderChanged = 27,
FailedToChangeHostFolder = 28,
ScreenContents = 29,
}
impl EventType {
/// String value of the enum field names used in the ProtoBuf definition.
Expand Down Expand Up @@ -523,6 +526,7 @@ impl EventType {
EventType::ListClients => "ListClients",
EventType::HostFolderChanged => "HostFolderChanged",
EventType::FailedToChangeHostFolder => "FailedToChangeHostFolder",
EventType::ScreenContents => "ScreenContents",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
Expand Down Expand Up @@ -557,6 +561,7 @@ impl EventType {
"ListClients" => Some(Self::ListClients),
"HostFolderChanged" => Some(Self::HostFolderChanged),
"FailedToChangeHostFolder" => Some(Self::FailedToChangeHostFolder),
"ScreenContents" => Some(Self::ScreenContents),
_ => None,
}
}
Expand Down
7 changes: 6 additions & 1 deletion zellij-utils/assets/prost/api.plugin_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91"
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, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92"
)]
pub payload: ::core::option::Option<plugin_command::Payload>,
}
Expand Down Expand Up @@ -180,6 +180,8 @@ pub mod plugin_command {
SetFloatingPanePinnedPayload(super::SetFloatingPanePinnedPayload),
#[prost(message, tag = "91")]
StackPanesPayload(super::StackPanesPayload),
#[prost(bool, tag = "92")]
DumpScreenPayload(bool),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down Expand Up @@ -747,6 +749,7 @@ pub enum CommandName {
ChangeHostFolder = 114,
SetFloatingPanePinned = 115,
StackPanes = 116,
DumpScreen = 117,
}
impl CommandName {
/// String value of the enum field names used in the ProtoBuf definition.
Expand Down Expand Up @@ -874,6 +877,7 @@ impl CommandName {
CommandName::ChangeHostFolder => "ChangeHostFolder",
CommandName::SetFloatingPanePinned => "SetFloatingPanePinned",
CommandName::StackPanes => "StackPanes",
CommandName::DumpScreen => "DumpScreen",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
Expand Down Expand Up @@ -998,6 +1002,7 @@ impl CommandName {
"ChangeHostFolder" => Some(Self::ChangeHostFolder),
"SetFloatingPanePinned" => Some(Self::SetFloatingPanePinned),
"StackPanes" => Some(Self::StackPanes),
"DumpScreen" => Some(Self::DumpScreen),
_ => None,
}
}
Expand Down
3 changes: 3 additions & 0 deletions zellij-utils/assets/prost/api.plugin_permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub enum PermissionType {
MessageAndLaunchOtherPlugins = 8,
Reconfigure = 9,
FullHdAccess = 10,
ReadScreen = 11,
}
impl PermissionType {
/// String value of the enum field names used in the ProtoBuf definition.
Expand All @@ -33,6 +34,7 @@ impl PermissionType {
}
PermissionType::Reconfigure => "Reconfigure",
PermissionType::FullHdAccess => "FullHdAccess",
PermissionType::ReadScreen => "ReadScreen",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
Expand All @@ -49,6 +51,7 @@ impl PermissionType {
"MessageAndLaunchOtherPlugins" => Some(Self::MessageAndLaunchOtherPlugins),
"Reconfigure" => Some(Self::Reconfigure),
"FullHdAccess" => Some(Self::FullHdAccess),
"ReadScreen" => Some(Self::ReadScreen),
_ => None,
}
}
Expand Down
6 changes: 6 additions & 0 deletions zellij-utils/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,7 @@ pub enum Event {
ListClients(Vec<ClientInfo>),
HostFolderChanged(PathBuf), // PathBuf -> new host folder
FailedToChangeHostFolder(Option<String>), // String -> the error we got when changing
ScreenContents(String),
}

#[derive(
Expand Down Expand Up @@ -945,6 +946,7 @@ pub enum Permission {
MessageAndLaunchOtherPlugins,
Reconfigure,
FullHdAccess,
ReadScreen,
}

impl PermissionType {
Expand All @@ -967,6 +969,9 @@ impl PermissionType {
},
PermissionType::Reconfigure => "Change Zellij runtime configuration".to_owned(),
PermissionType::FullHdAccess => "Full access to the hard-drive".to_owned(),
PermissionType::ReadScreen => {
"Read contents of the terminal screen and scrollback".to_owned()
},
}
}
}
Expand Down Expand Up @@ -1857,6 +1862,7 @@ pub enum PluginCommand {
ScanHostFolder(PathBuf), // TODO: rename to ScanHostFolder
WatchFilesystem,
DumpSessionLayout,
DumpScreen(bool),
CloseSelf,
NewTabsWithLayoutInfo(LayoutInfo),
Reconfigure(String, bool), // String -> stringified configuration, bool -> save configuration
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ pub enum ScreenContext {
Exit,
ClearScreen,
DumpScreen,
DumpScreenToPlugin,
DumpLayout,
EditScrollback,
ScrollUp,
Expand Down Expand Up @@ -425,6 +426,7 @@ pub enum PluginContext {
PluginSubscribedToEvents,
PermissionRequestResult,
DumpLayout,
DumpScreen,
LogLayoutToHd,
CliPipe,
Message,
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/plugin_api/event.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ enum EventType {
ListClients = 26;
HostFolderChanged = 27;
FailedToChangeHostFolder = 28;
ScreenContents = 29;
}

message EventNameList {
Expand Down Expand Up @@ -85,6 +86,7 @@ message Event {
ListClientsPayload list_clients_payload = 23;
HostFolderChangedPayload host_folder_changed_payload = 24;
FailedToChangeHostFolderPayload failed_to_change_host_folder_payload = 25;
string ScreenContentsPayload = 26;
}
}

Expand Down
12 changes: 12 additions & 0 deletions zellij-utils/src/plugin_api/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,12 @@ impl TryFrom<ProtobufEvent> for Event {
)),
_ => Err("Malformed payload for the FailedToChangeHostFolder Event"),
},
Some(ProtobufEventType::ScreenContents) => match protobuf_event.payload {
Some(ProtobufEventPayload::ScreenContentsPayload(dump)) => {
Ok(Event::ScreenContents(dump))
},
_ => Err("Malformed payload for the ScreenContents Event"),
},
None => Err("Unknown Protobuf Event"),
}
}
Expand Down Expand Up @@ -713,6 +719,10 @@ impl TryFrom<Event> for ProtobufEvent {
FailedToChangeHostFolderPayload { error_message },
)),
}),
Event::ScreenContents(dump) => Ok(ProtobufEvent {
name: ProtobufEventType::ScreenContents as i32,
payload: Some(event::Payload::ScreenContentsPayload(dump)),
}),
}
}
}
Expand Down Expand Up @@ -1260,6 +1270,7 @@ impl TryFrom<ProtobufEventType> for EventType {
ProtobufEventType::ListClients => EventType::ListClients,
ProtobufEventType::HostFolderChanged => EventType::HostFolderChanged,
ProtobufEventType::FailedToChangeHostFolder => EventType::FailedToChangeHostFolder,
ProtobufEventType::ScreenContents => EventType::ScreenContents,
})
}
}
Expand Down Expand Up @@ -1297,6 +1308,7 @@ impl TryFrom<EventType> for ProtobufEventType {
EventType::ListClients => ProtobufEventType::ListClients,
EventType::HostFolderChanged => ProtobufEventType::HostFolderChanged,
EventType::FailedToChangeHostFolder => ProtobufEventType::FailedToChangeHostFolder,
EventType::ScreenContents => ProtobufEventType::ScreenContents,
})
}
}
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/plugin_api/plugin_command.proto
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ enum CommandName {
ChangeHostFolder = 114;
SetFloatingPanePinned = 115;
StackPanes = 116;
DumpScreen = 117;
}

message PluginCommand {
Expand Down Expand Up @@ -216,6 +217,7 @@ message PluginCommand {
ChangeHostFolderPayload change_host_folder_payload = 89;
SetFloatingPanePinnedPayload set_floating_pane_pinned_payload = 90;
StackPanesPayload stack_panes_payload = 91;
bool dump_screen_payload = 92;
}
}

Expand Down
8 changes: 8 additions & 0 deletions zellij-utils/src/plugin_api/plugin_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,10 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
Some(_) => Err("DumpSessionLayout should have no payload, found a payload"),
None => Ok(PluginCommand::DumpSessionLayout),
},
Some(CommandName::DumpScreen) => match protobuf_plugin_command.payload {
Some(Payload::DumpScreenPayload(full)) => Ok(PluginCommand::DumpScreen(full)),
_ => Err("Mismatched payload for DumpScreen"),
},
Some(CommandName::CloseSelf) => match protobuf_plugin_command.payload {
Some(_) => Err("CloseSelf should have no payload, found a payload"),
None => Ok(PluginCommand::CloseSelf),
Expand Down Expand Up @@ -1897,6 +1901,10 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
name: CommandName::DumpSessionLayout as i32,
payload: None,
}),
PluginCommand::DumpScreen(full) => Ok(ProtobufPluginCommand {
name: CommandName::DumpScreen as i32,
payload: Some(Payload::DumpScreenPayload(full)),
}),
PluginCommand::CloseSelf => Ok(ProtobufPluginCommand {
name: CommandName::CloseSelf as i32,
payload: None,
Expand Down
1 change: 1 addition & 0 deletions zellij-utils/src/plugin_api/plugin_permission.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ enum PermissionType {
MessageAndLaunchOtherPlugins = 8;
Reconfigure = 9;
FullHdAccess = 10;
ReadScreen = 11;
}
2 changes: 2 additions & 0 deletions zellij-utils/src/plugin_api/plugin_permission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl TryFrom<ProtobufPermissionType> for PermissionType {
},
ProtobufPermissionType::Reconfigure => Ok(PermissionType::Reconfigure),
ProtobufPermissionType::FullHdAccess => Ok(PermissionType::FullHdAccess),
ProtobufPermissionType::ReadScreen => Ok(PermissionType::ReadScreen),
}
}
}
Expand Down Expand Up @@ -53,6 +54,7 @@ impl TryFrom<PermissionType> for ProtobufPermissionType {
},
PermissionType::Reconfigure => Ok(ProtobufPermissionType::Reconfigure),
PermissionType::FullHdAccess => Ok(ProtobufPermissionType::FullHdAccess),
PermissionType::ReadScreen => Ok(ProtobufPermissionType::ReadScreen),
}
}
}

0 comments on commit f11f373

Please sign in to comment.