diff options
| author | Aram Drevekenin <aram@poor.dev> | 2025-12-11 14:25:42 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-11 14:25:42 +0100 |
| commit | 693fa082def5ef0fe030cd7fdc3b1df051b35dc6 (patch) | |
| tree | b3f651462bbc1cd2fa5b2d79207343413ef6b83c /zellij-server/src/plugins/mod.rs | |
| parent | fix(zellij-server): unblock building on 32bit targets (#4484) (diff) | |
| download | sl0ppij-693fa082def5ef0fe030cd7fdc3b1df051b35dc6.tar.gz sl0ppij-693fa082def5ef0fe030cd7fdc3b1df051b35dc6.tar.xz sl0ppij-693fa082def5ef0fe030cd7fdc3b1df051b35dc6.zip | |
Command Sequences, Blocking CLI Commands, New Plugin APIs (#4546)
* fix deadlocks
* initial logging to plugin implementation
* only log actions, include keys as Action::Write
* send actions to plugins as a new Event::UserAction
* add Action::Write metadata to plugin API
* run_action plugin command and permission
* block-until-exit/success/failure in the cli
* fix tests
* add NewBlockingPane to the plugin API
* run actions in a different thread so as not to block plugin execution
* add custom context to run_action flow
* fixes for floating pane z_index sorting and unknown protobuf events not crashing plugins
* always render the frame of pinned panes
* macros module
* add macros to config
* KDL macro parsing
* thread macros to the plugin thread
* get/update/delete macros from plugins
* add macros updated event
* add ability to rename macros
* fix deadlock
* fix z_indices with pinned unselectable panes bug
* allow plugins to opt-in to show_cursor
* change show_cursor(bool) to show_cursor(Option<coordinates>)
* test
* upgrade strum to allow proper enum iteration and case insensitive fromstr implementation for Actions
* better cwd tracking for exited command panes
* add initial panes to NewTab Action (no-op for now)
* add initial panes to cli newtab action
* make initial panes work
* add close_on_exit and start_suspended to the cli
* properly convert newtab action (potentially breaking for plugins)
* allow first pane in tab to block
* make distinction between opening panes with the last active client and the current pane in the cli
* improve some apis
* fix fixed size closing pane bug
* fix plugin cursor coordinates
* fix issues with launch-or-focus-plugin having to do with in-place and suppressed panes
* fix: set affected pane in replace pane
* allow setting a pane in place when it is suppressed and being focused (tests failing)
* fix tests
* some fixes for unsuppression of panes
* some fixes for completion_tx in new tab action
* allow replace/suppressed rather than replace/close only
* fixes for inserting suppressed panes without conflicts
* pane focus history and explicit unsuppress plugin api
* fix: prefer explicitly provided pane id in placement in actions that provide it
* fix floating pane coordinate change and z_index
* fix plugin cache dir to persist between sessions
* fix some stack focusing issues when adding panes without a client id
* make sure pinned panes are always above non-pinned floating panes
* allow plugins to copy to clipboard
* initial text styling additions implementations - buggy
* fix dimming issues
* remove extras, stay with just dim and unbold
* unbold and dim as indices
* allow ui components to render success/error colors
* allow plugins to send sigint/sigkill to processes, as well as receive their pid
* ui component fixes and send originating plugin context with run_action
* originating plugin for new tab too
* make plugn show pane command also expand stacked panes
* add sequence plugin
* remove macros
* remove snapshots
* add shortcut for sequence plugin
* fix plugin tests
* plugin tests for new apis
* update snapshots for sequence shortcut
* cleanups and formatting
* Event::CwdChanged
* moar cleanups
* remove some warnings
* remove mroe warnings
* remove dead code
* remove more dead code
* fix minor bugs in sequence plugin
* update sequence help and format codebase
* fix conditional blocking cli commands
* fix initial-command new-tab cli flag
* add client_ids to CwdChanged Event
* last fixes
* add pr
Diffstat (limited to 'zellij-server/src/plugins/mod.rs')
| -rw-r--r-- | zellij-server/src/plugins/mod.rs | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs index cede7901..24a1e811 100644 --- a/zellij-server/src/plugins/mod.rs +++ b/zellij-server/src/plugins/mod.rs @@ -30,12 +30,13 @@ use wasm_bridge::WasmBridge; use async_std::{channel, future::timeout, task}; use zellij_utils::{ data::{ - ClientInfo, Event, EventType, FloatingPaneCoordinates, InputMode, MessageToPlugin, - PermissionStatus, PermissionType, PipeMessage, PipeSource, PluginCapabilities, - WebServerStatus, + ClientInfo, CommandOrPlugin, Event, EventType, FloatingPaneCoordinates, InputMode, + MessageToPlugin, PermissionStatus, PermissionType, PipeMessage, PipeSource, + PluginCapabilities, WebServerStatus, }, errors::{prelude::*, ContextType, PluginContext}, input::{ + actions::Action, command::TerminalAction, keybinds::Keybinds, layout::{FloatingPaneLayout, Layout, Run, RunPlugin, RunPluginOrAlias, TiledPaneLayout}, @@ -86,10 +87,12 @@ pub enum PluginInstruction { Option<TerminalAction>, Option<TiledPaneLayout>, Vec<FloatingPaneLayout>, - usize, // tab_index - bool, // should change focus to new tab - (ClientId, bool), // bool -> is_web_client - Option<NotificationEnd>, // completion signal + usize, // tab_index + Option<Vec<CommandOrPlugin>>, // initial_panes + bool, // block_on_first_terminal + bool, // should change focus to new tab + (ClientId, bool), // bool -> is_web_client + Option<NotificationEnd>, // completion signal ), ApplyCachedEvents { plugin_ids: Vec<PluginId>, @@ -175,6 +178,12 @@ pub enum PluginInstruction { WebServerStarted(String), // String -> the base url of the web server FailedToStartWebServer(String), PaneRenderReport(PaneRenderReport), + UserInput { + client_id: ClientId, + action: Action, + terminal_id: Option<u32>, + cli_client_id: Option<ClientId>, + }, Exit, } @@ -225,6 +234,7 @@ impl From<&PluginInstruction> for PluginContext { PluginInstruction::WebServerStarted(..) => PluginContext::WebServerStarted, PluginInstruction::FailedToStartWebServer(..) => PluginContext::FailedToStartWebServer, PluginInstruction::PaneRenderReport(..) => PluginContext::PaneRenderReport, + PluginInstruction::UserInput { .. } => PluginContext::UserInput, } } } @@ -453,6 +463,8 @@ pub(crate) fn plugin_thread_main( mut tab_layout, mut floating_panes_layout, tab_index, + initial_panes, + block_on_first_terminal, should_change_focus_to_new_tab, (client_id, is_web_client), completion_tx, @@ -469,6 +481,26 @@ pub(crate) fn plugin_thread_main( let mut plugin_ids: HashMap<RunPluginOrAlias, Vec<PluginId>> = HashMap::new(); tab_layout = tab_layout.or_else(|| Some(layout.new_tab().0)); + + // Match initial_panes plugins to empty slots in the layout + if let Some(ref initial_panes_vec) = initial_panes { + if let Some(ref mut tiled_layout) = tab_layout { + for initial_pane in initial_panes_vec.iter() { + if let CommandOrPlugin::Plugin(run_plugin_or_alias) = initial_pane { + if !tiled_layout.replace_next_empty_slot_with_run(Run::Plugin( + run_plugin_or_alias.clone(), + )) { + log::warn!( + "More initial_panes provided than empty slots available" + ); + break; + } + } + // Skip CommandOrPlugin::Command entries (handled by pty thread) + } + } + } + tab_layout.as_mut().map(|t| { t.populate_plugin_aliases_in_layout(&plugin_aliases); if let Some(cwd) = cwd.as_ref() { @@ -481,7 +513,7 @@ pub(crate) fn plugin_thread_main( .as_mut() .map(|f| f.populate_run_plugin_if_needed(&plugin_aliases)); }); - let mut extracted_run_instructions = tab_layout + let extracted_run_instructions = tab_layout .clone() .unwrap_or_else(|| layout.new_tab().0) .extract_run_instructions(); @@ -496,8 +528,10 @@ pub(crate) fn plugin_thread_main( .filter(|f| !f.already_running) .map(|f| f.run.clone()) .collect(); - extracted_run_instructions.append(&mut extracted_floating_plugins); - for run_instruction in extracted_run_instructions { + let mut all_run_instructions = extracted_run_instructions; + all_run_instructions.append(&mut extracted_floating_plugins); + + for run_instruction in all_run_instructions { if let Some(Run::Plugin(run_plugin_or_alias)) = run_instruction { let run_plugin = run_plugin_or_alias.get_run_plugin(); let cwd = run_plugin_or_alias @@ -525,6 +559,8 @@ pub(crate) fn plugin_thread_main( floating_panes_layout, tab_index, plugin_ids, + initial_panes, + block_on_first_terminal, should_change_focus_to_new_tab, (client_id, is_web_client), completion_tx, @@ -989,6 +1025,20 @@ pub(crate) fn plugin_thread_main( .handle_pane_render_report(pane_render_report, shutdown_send.clone()) .non_fatal(); }, + PluginInstruction::UserInput { + client_id, + action, + terminal_id, + cli_client_id, + } => { + // Fire Event::UserAction to all subscribed plugins with InterceptInput permission + let updates = vec![( + None, + None, + Event::UserAction(action, client_id, terminal_id, cli_client_id), + )]; + wasm_bridge.update_plugins(updates, shutdown_send.clone())?; + }, PluginInstruction::Exit => { break; }, |
