aboutsummaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/plugin_api
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-09-30 18:04:40 +0200
committerGitHub <noreply@github.com>2024-09-30 18:04:40 +0200
commit9f1e38f9fa6efd166f5205eaa8603d6b05a68b2b (patch)
tree3e41bdf65e4bb83fc08f3ad23f913630a97a3d97 /zellij-utils/src/plugin_api
parentdocs(changelog): background plugins (diff)
downloadsl0ppij-9f1e38f9fa6efd166f5205eaa8603d6b05a68b2b.tar.gz
sl0ppij-9f1e38f9fa6efd166f5205eaa8603d6b05a68b2b.tar.xz
sl0ppij-9f1e38f9fa6efd166f5205eaa8603d6b05a68b2b.zip
feat(ui): built-in plugin manager (#3633)
* add plugin list to session info * feat(plugins): new_plugin and reload_plugin API commands * feat(plugins): built-in plugin manager * style(fmt): rustfmt * update plugins
Diffstat (limited to 'zellij-utils/src/plugin_api')
-rw-r--r--zellij-utils/src/plugin_api/event.proto7
-rw-r--r--zellij-utils/src/plugin_api/event.rs52
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto15
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs64
4 files changed, 126 insertions, 12 deletions
diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto
index a985806f..e3f3cacb 100644
--- a/zellij-utils/src/plugin_api/event.proto
+++ b/zellij-utils/src/plugin_api/event.proto
@@ -223,6 +223,13 @@ message SessionManifest {
uint32 connected_clients = 4;
bool is_current_session = 5;
repeated LayoutInfo available_layouts = 6;
+ repeated PluginInfo plugins = 7;
+}
+
+message PluginInfo {
+ uint32 plugin_id = 1;
+ string plugin_url = 2;
+ repeated ContextItem plugin_config = 3;
}
message LayoutInfo {
diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs
index faeb53d2..d1e2f50d 100644
--- a/zellij-utils/src/plugin_api/event.rs
+++ b/zellij-utils/src/plugin_api/event.rs
@@ -8,7 +8,7 @@ pub use super::generated_api::api::{
LayoutInfo as ProtobufLayoutInfo, ModeUpdatePayload as ProtobufModeUpdatePayload,
PaneId as ProtobufPaneId, PaneInfo as ProtobufPaneInfo,
PaneManifest as ProtobufPaneManifest, PaneType as ProtobufPaneType,
- ResurrectableSession as ProtobufResurrectableSession,
+ PluginInfo as ProtobufPluginInfo, ResurrectableSession as ProtobufResurrectableSession,
SessionManifest as ProtobufSessionManifest, TabInfo as ProtobufTabInfo, *,
},
input_mode::InputMode as ProtobufInputMode,
@@ -19,13 +19,13 @@ pub use super::generated_api::api::{
use crate::data::{
CopyDestination, Event, EventType, FileMetadata, InputMode, KeyWithModifier, LayoutInfo,
ModeInfo, Mouse, PaneId, PaneInfo, PaneManifest, PermissionStatus, PluginCapabilities,
- SessionInfo, Style, TabInfo,
+ PluginInfo, SessionInfo, Style, TabInfo,
};
use crate::errors::prelude::*;
use crate::input::actions::Action;
-use std::collections::{HashMap, HashSet};
+use std::collections::{BTreeMap, HashMap, HashSet};
use std::convert::TryFrom;
use std::path::PathBuf;
use std::time::Duration;
@@ -667,10 +667,29 @@ impl TryFrom<SessionInfo> for ProtobufSessionManifest {
.into_iter()
.filter_map(|l| ProtobufLayoutInfo::try_from(l).ok())
.collect(),
+ plugins: session_info
+ .plugins
+ .into_iter()
+ .map(|p| ProtobufPluginInfo::from(p))
+ .collect(),
})
}
}
+impl From<(u32, PluginInfo)> for ProtobufPluginInfo {
+ fn from((plugin_id, plugin_info): (u32, PluginInfo)) -> ProtobufPluginInfo {
+ ProtobufPluginInfo {
+ plugin_id,
+ plugin_url: plugin_info.location,
+ plugin_config: plugin_info
+ .configuration
+ .into_iter()
+ .map(|(name, value)| ContextItem { name, value })
+ .collect(),
+ }
+ }
+}
+
impl TryFrom<ProtobufSessionManifest> for SessionInfo {
type Error = &'static str;
fn try_from(protobuf_session_manifest: ProtobufSessionManifest) -> Result<Self, &'static str> {
@@ -689,6 +708,20 @@ impl TryFrom<ProtobufSessionManifest> for SessionInfo {
let panes = PaneManifest {
panes: pane_manifest,
};
+ let mut plugins = BTreeMap::new();
+ for plugin_info in protobuf_session_manifest.plugins.into_iter() {
+ let mut configuration = BTreeMap::new();
+ for context_item in plugin_info.plugin_config.into_iter() {
+ configuration.insert(context_item.name, context_item.value);
+ }
+ plugins.insert(
+ plugin_info.plugin_id,
+ PluginInfo {
+ location: plugin_info.plugin_url,
+ configuration,
+ },
+ );
+ }
Ok(SessionInfo {
name: protobuf_session_manifest.name,
tabs: protobuf_session_manifest
@@ -704,6 +737,7 @@ impl TryFrom<ProtobufSessionManifest> for SessionInfo {
.into_iter()
.filter_map(|l| LayoutInfo::try_from(l).ok())
.collect(),
+ plugins,
})
}
}
@@ -1702,6 +1736,16 @@ fn serialize_session_update_event_with_non_default_values() {
},
];
panes.insert(0, panes_list);
+ let mut plugins = BTreeMap::new();
+ let mut plugin_configuration = BTreeMap::new();
+ plugin_configuration.insert("config_key".to_owned(), "config_value".to_owned());
+ plugins.insert(
+ 1,
+ PluginInfo {
+ location: "https://example.com/my-plugin.wasm".to_owned(),
+ configuration: plugin_configuration,
+ },
+ );
let session_info_1 = SessionInfo {
name: "session 1".to_owned(),
tabs: tab_infos,
@@ -1713,6 +1757,7 @@ fn serialize_session_update_event_with_non_default_values() {
LayoutInfo::BuiltIn("layout2".to_owned()),
LayoutInfo::File("layout3".to_owned()),
],
+ plugins,
};
let session_info_2 = SessionInfo {
name: "session 2".to_owned(),
@@ -1727,6 +1772,7 @@ fn serialize_session_update_event_with_non_default_values() {
LayoutInfo::BuiltIn("layout2".to_owned()),
LayoutInfo::File("layout3".to_owned()),
],
+ plugins: Default::default(),
};
let session_infos = vec![session_info_1, session_info_2];
let resurrectable_sessions = vec![];
diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto
index 758d4e77..adb91e53 100644
--- a/zellij-utils/src/plugin_api/plugin_command.proto
+++ b/zellij-utils/src/plugin_api/plugin_command.proto
@@ -121,6 +121,8 @@ enum CommandName {
CloseTabWithIndex = 107;
BreakPanesToNewTab = 108;
BreakPanesToTabWithIndex = 109;
+ ReloadPlugin = 110;
+ LoadNewPlugin = 111;
}
message PluginCommand {
@@ -201,9 +203,22 @@ message PluginCommand {
CloseTabWithIndexPayload close_tab_with_index_payload = 83;
BreakPanesToNewTabPayload break_panes_to_new_tab_payload = 84;
BreakPanesToTabWithIndexPayload break_panes_to_tab_with_index_payload = 85;
+ ReloadPluginPayload reload_plugin_payload = 86;
+ LoadNewPluginPayload load_new_plugin_payload = 87;
}
}
+message LoadNewPluginPayload {
+ string plugin_url = 1;
+ repeated ContextItem plugin_config = 2;
+ bool should_load_plugin_in_background = 3;
+ bool should_skip_plugin_cache = 4;
+}
+
+message ReloadPluginPayload {
+ uint32 plugin_id = 1;
+}
+
message BreakPanesToTabWithIndexPayload {
repeated PaneId pane_ids = 1;
uint32 tab_index = 2;
diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs
index 15c56d03..d455500a 100644
--- a/zellij-utils/src/plugin_api/plugin_command.rs
+++ b/zellij-utils/src/plugin_api/plugin_command.rs
@@ -9,18 +9,19 @@ pub use super::generated_api::api::{
FixedOrPercent as ProtobufFixedOrPercent,
FixedOrPercentValue as ProtobufFixedOrPercentValue,
FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HidePaneWithIdPayload,
- HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, MessageToPluginPayload,
- MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload, MovePayload,
- NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload,
+ HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, LoadNewPluginPayload,
+ MessageToPluginPayload, MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload,
+ MovePayload, NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload,
OpenCommandPanePayload, OpenFilePayload, PageScrollDownInPaneIdPayload,
PageScrollUpInPaneIdPayload, PaneId as ProtobufPaneId, PaneType as ProtobufPaneType,
PluginCommand as ProtobufPluginCommand, PluginMessagePayload, ReconfigurePayload,
- RequestPluginPermissionPayload, RerunCommandPanePayload, ResizePaneIdWithDirectionPayload,
- ResizePayload, RunCommandPayload, ScrollDownInPaneIdPayload, ScrollToBottomInPaneIdPayload,
- ScrollToTopInPaneIdPayload, ScrollUpInPaneIdPayload, SetTimeoutPayload,
- ShowPaneWithIdPayload, SubscribePayload, SwitchSessionPayload, SwitchTabToPayload,
- TogglePaneEmbedOrEjectForPaneIdPayload, TogglePaneIdFullscreenPayload, UnsubscribePayload,
- WebRequestPayload, WriteCharsToPaneIdPayload, WriteToPaneIdPayload,
+ ReloadPluginPayload, RequestPluginPermissionPayload, RerunCommandPanePayload,
+ ResizePaneIdWithDirectionPayload, ResizePayload, RunCommandPayload,
+ ScrollDownInPaneIdPayload, ScrollToBottomInPaneIdPayload, ScrollToTopInPaneIdPayload,
+ ScrollUpInPaneIdPayload, SetTimeoutPayload, ShowPaneWithIdPayload, SubscribePayload,
+ SwitchSessionPayload, SwitchTabToPayload, TogglePaneEmbedOrEjectForPaneIdPayload,
+ TogglePaneIdFullscreenPayload, UnsubscribePayload, WebRequestPayload,
+ WriteCharsToPaneIdPayload, WriteToPaneIdPayload,
},
plugin_permission::PermissionType as ProtobufPermissionType,
resize::ResizeAction as ProtobufResizeAction,
@@ -1203,6 +1204,28 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
)),
_ => Err("Mismatched payload for BreakPanesToTabWithIndex"),
},
+ Some(CommandName::ReloadPlugin) => match protobuf_plugin_command.payload {
+ Some(Payload::ReloadPluginPayload(reload_plugin_payload)) => {
+ Ok(PluginCommand::ReloadPlugin(reload_plugin_payload.plugin_id))
+ },
+ _ => Err("Mismatched payload for ReloadPlugin"),
+ },
+ Some(CommandName::LoadNewPlugin) => match protobuf_plugin_command.payload {
+ Some(Payload::LoadNewPluginPayload(load_new_plugin_payload)) => {
+ Ok(PluginCommand::LoadNewPlugin {
+ url: load_new_plugin_payload.plugin_url,
+ config: load_new_plugin_payload
+ .plugin_config
+ .into_iter()
+ .map(|e| (e.name, e.value))
+ .collect(),
+ load_in_background: load_new_plugin_payload
+ .should_load_plugin_in_background,
+ skip_plugin_cache: load_new_plugin_payload.should_skip_plugin_cache,
+ })
+ },
+ _ => Err("Mismatched payload for LoadNewPlugin"),
+ },
None => Err("Unrecognized plugin command"),
}
}
@@ -1985,6 +2008,29 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
},
)),
}),
+ PluginCommand::ReloadPlugin(plugin_id) => Ok(ProtobufPluginCommand {
+ name: CommandName::ReloadPlugin as i32,
+ payload: Some(Payload::ReloadPluginPayload(ReloadPluginPayload {
+ plugin_id,
+ })),
+ }),
+ PluginCommand::LoadNewPlugin {
+ url,
+ config,
+ load_in_background,
+ skip_plugin_cache,
+ } => Ok(ProtobufPluginCommand {
+ name: CommandName::LoadNewPlugin as i32,
+ payload: Some(Payload::LoadNewPluginPayload(LoadNewPluginPayload {
+ plugin_url: url,
+ plugin_config: config
+ .into_iter()
+ .map(|(name, value)| ContextItem { name, value })
+ .collect(),
+ should_skip_plugin_cache: skip_plugin_cache,
+ should_load_plugin_in_background: load_in_background,
+ })),
+ }),
}
}
}