diff options
| author | Aram Drevekenin <aram@poor.dev> | 2024-09-30 18:04:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-30 18:04:40 +0200 |
| commit | 9f1e38f9fa6efd166f5205eaa8603d6b05a68b2b (patch) | |
| tree | 3e41bdf65e4bb83fc08f3ad23f913630a97a3d97 /zellij-utils/src/plugin_api | |
| parent | docs(changelog): background plugins (diff) | |
| download | sl0ppij-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.proto | 7 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/event.rs | 52 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.proto | 15 | ||||
| -rw-r--r-- | zellij-utils/src/plugin_api/plugin_command.rs | 64 |
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, + })), + }), } } } |
