aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2025-07-15 10:27:43 +0200
committerGitHub <noreply@github.com>2025-07-15 10:27:43 +0200
commitd4f5975527868d1bcc980e0d149be9aefd4efc34 (patch)
treeeb96b817d29f3cd4f346d1a579644c30b286678d
parentfix: populate layount metadata with the right cmd and cwd (#4287) (diff)
downloadsl0ppij-d4f5975527868d1bcc980e0d149be9aefd4efc34.tar.gz
sl0ppij-d4f5975527868d1bcc980e0d149be9aefd4efc34.tar.xz
sl0ppij-d4f5975527868d1bcc980e0d149be9aefd4efc34.zip
fix(plugins): forward CWD when opening new panes (#4290)
* use plugin cwd as last focused pane cwd when starting plugins * fix strider to use the new change_host_folder method * start terminals in same cwd as plugin pane if focused * style(fmt): rustfmt
-rw-r--r--default-plugins/strider/src/file_list_view.rs58
-rw-r--r--default-plugins/strider/src/main.rs37
-rw-r--r--default-plugins/strider/src/shared.rs21
-rw-r--r--default-plugins/strider/src/state.rs17
-rw-r--r--zellij-server/src/plugins/mod.rs40
-rw-r--r--zellij-server/src/plugins/unit/plugin_tests.rs108
-rw-r--r--zellij-server/src/plugins/wasm_bridge.rs27
-rw-r--r--zellij-server/src/plugins/zellij_exports.rs1
-rw-r--r--zellij-server/src/pty.rs68
-rw-r--r--zellij-utils/src/errors.rs1
10 files changed, 280 insertions, 98 deletions
diff --git a/default-plugins/strider/src/file_list_view.rs b/default-plugins/strider/src/file_list_view.rs
index ccbbe292..a5a0bfa9 100644
--- a/default-plugins/strider/src/file_list_view.rs
+++ b/default-plugins/strider/src/file_list_view.rs
@@ -2,7 +2,7 @@ use crate::shared::{calculate_list_bounds, render_list_tip};
use crate::state::{refresh_directory, ROOT};
use pretty_bytes::converter::convert as pretty_bytes;
use std::collections::HashMap;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
use unicode_width::UnicodeWidthStr;
use zellij_tile::prelude::*;
@@ -18,7 +18,7 @@ impl Default for FileListView {
fn default() -> Self {
FileListView {
path_is_dir: true,
- path: Default::default(),
+ path: PathBuf::new(),
files: Default::default(),
cursor_hist: Default::default(),
}
@@ -27,30 +27,48 @@ impl Default for FileListView {
impl FileListView {
pub fn descend_to_previous_path(&mut self) {
- self.path.pop();
+ if let Some(parent) = self.path.parent() {
+ self.path = parent.to_path_buf();
+ } else {
+ self.path = PathBuf::new();
+ }
self.path_is_dir = true;
self.files.clear();
self.clear_selected();
refresh_directory(&self.path);
}
- pub fn descend_to_root_path(&mut self) {
- self.path.clear();
+
+ pub fn descend_to_root_path(&mut self, initial_cwd: &PathBuf) {
+ self.path = initial_cwd.clone();
self.path_is_dir = true;
self.files.clear();
self.clear_selected();
- refresh_directory(&self.path);
}
+
pub fn enter_dir(&mut self, entry: &FsEntry) {
let is_dir = entry.is_folder();
- let path = entry.get_pathbuf_without_root_prefix();
+ let path = entry.get_full_pathbuf();
self.path = path;
self.path_is_dir = is_dir;
self.files.clear();
self.clear_selected();
}
+
pub fn clear_selected(&mut self) {
self.cursor_hist.remove(&self.path);
}
+
+ pub fn get_relative_path(&self) -> PathBuf {
+ if let Some(initial_cwd_part) = self.path.iter().next() {
+ self.path
+ .strip_prefix(initial_cwd_part)
+ .unwrap_or(&self.path)
+ .to_path_buf()
+ } else {
+ PathBuf::new()
+ }
+ }
+
pub fn update_files(
&mut self,
paths: Vec<(PathBuf, Option<FileMetadata>)>,
@@ -58,8 +76,11 @@ impl FileListView {
) {
let mut files = vec![];
for (entry, entry_metadata) in paths {
+ let entry = self
+ .path
+ .join(entry.strip_prefix("/host").unwrap_or(&entry));
if entry_metadata.map(|e| e.is_symlink).unwrap_or(false) {
- continue; // ignore symlinks
+ continue;
}
let entry = if entry_metadata.map(|e| e.is_dir).unwrap_or(false) {
FsEntry::Dir(entry)
@@ -74,20 +95,25 @@ impl FileListView {
self.files = files;
self.files.sort_unstable();
}
+
pub fn get_selected_entry(&self) -> Option<FsEntry> {
self.selected().and_then(|f| self.files.get(f).cloned())
}
+
pub fn selected_mut(&mut self) -> &mut usize {
self.cursor_hist.entry(self.path.clone()).or_default()
}
+
pub fn selected(&self) -> Option<usize> {
self.cursor_hist.get(&self.path).copied()
}
+
pub fn move_selection_up(&mut self) {
if let Some(selected) = self.selected() {
*self.selected_mut() = selected.saturating_sub(1);
}
}
+
pub fn move_selection_down(&mut self) {
if let Some(selected) = self.selected() {
let next = selected.saturating_add(1);
@@ -96,6 +122,7 @@ impl FileListView {
*self.selected_mut() = 0;
}
}
+
pub fn render(&mut self, rows: usize, cols: usize) {
let (start_index, selected_index_in_range, end_index) =
calculate_list_bounds(self.files.len(), rows.saturating_sub(1), self.selected());
@@ -121,7 +148,6 @@ impl FileListView {
);
format!("{}{}{}", file_or_folder_name, padding, size)
} else {
- // drop the size, no room for it
let padding = " ".repeat(cols.saturating_sub(file_or_folder_name_width));
format!("{}{}", file_or_folder_name, padding)
};
@@ -159,12 +185,14 @@ impl FsEntry {
};
path.file_name().unwrap().to_string_lossy().into_owned()
}
+
pub fn size(&self) -> Option<u64> {
match self {
FsEntry::Dir(_p) => None,
FsEntry::File(_, size) => Some(*size),
}
}
+
pub fn get_pathbuf_without_root_prefix(&self) -> PathBuf {
match self {
FsEntry::Dir(p) => p
@@ -178,14 +206,18 @@ impl FsEntry {
}
}
+ pub fn get_full_pathbuf(&self) -> PathBuf {
+ match self {
+ FsEntry::Dir(p) => p.clone(),
+ FsEntry::File(p, _) => p.clone(),
+ }
+ }
+
pub fn is_hidden_file(&self) -> bool {
self.name().starts_with('.')
}
pub fn is_folder(&self) -> bool {
- match self {
- FsEntry::Dir(_) => true,
- _ => false,
- }
+ matches!(self, FsEntry::Dir(_))
}
}
diff --git a/default-plugins/strider/src/main.rs b/default-plugins/strider/src/main.rs
index cd9dda4d..d770e495 100644
--- a/default-plugins/strider/src/main.rs
+++ b/default-plugins/strider/src/main.rs
@@ -31,29 +31,24 @@ impl ZellijPlugin for State {
EventType::CustomMessage,
EventType::Timer,
EventType::FileSystemUpdate,
+ EventType::HostFolderChanged,
+ EventType::PermissionRequestResult,
]);
self.file_list_view.clear_selected();
- // the caller_cwd might be different from the initial_cwd if this plugin was defined as an
- // alias, with access to a certain part of the file system (often broader) and was called
- // from an individual pane somewhere inside this broad scope - in this case, we want to
- // start in the same cwd as the caller, giving them the full access we were granted
- match configuration
- .get("caller_cwd")
- .map(|c| PathBuf::from(c))
- .and_then(|c| {
- c.strip_prefix(&self.initial_cwd)
- .ok()
- .map(|c| PathBuf::from(c))
- }) {
- Some(relative_caller_path) => {
- let relative_caller_path = FsEntry::Dir(relative_caller_path.to_path_buf());
- self.file_list_view.enter_dir(&relative_caller_path);
- refresh_directory(&self.file_list_view.path);
+
+ match configuration.get("caller_cwd").map(|c| PathBuf::from(c)) {
+ Some(caller_cwd) => {
+ self.file_list_view.path = caller_cwd;
},
None => {
- refresh_directory(&std::path::Path::new("/"));
+ self.file_list_view.path = self.initial_cwd.clone();
},
}
+ if self.initial_cwd != self.file_list_view.path {
+ change_host_folder(self.file_list_view.path.clone());
+ } else {
+ scan_host_folder(&"/host");
+ }
}
fn update(&mut self, event: Event) -> bool {
@@ -63,6 +58,10 @@ impl ZellijPlugin for State {
self.update_files(paths);
should_render = true;
},
+ Event::HostFolderChanged(new_host_folder) => {
+ scan_host_folder(&"/host");
+ should_render = true;
+ },
Event::Key(key) => match key.bare_key {
BareKey::Char(character) if key.has_no_modifiers() => {
self.update_search_term(character);
@@ -137,11 +136,10 @@ impl ZellijPlugin for State {
};
should_render
}
+
fn pipe(&mut self, pipe_message: PipeMessage) -> bool {
if pipe_message.is_private && pipe_message.name == "filepicker" {
if let PipeSource::Cli(pipe_id) = &pipe_message.source {
- // here we block the cli pipe input because we want it to wait until the user chose
- // a file
#[cfg(target_family = "wasm")]
block_cli_pipe_input(pipe_id);
}
@@ -157,7 +155,6 @@ impl ZellijPlugin for State {
let rows_for_list = rows.saturating_sub(6);
render_search_term(&self.search_term);
render_current_path(
- &self.initial_cwd,
&self.file_list_view.path,
self.file_list_view.path_is_dir,
self.handling_filepick_request_from.is_some(),
diff --git a/default-plugins/strider/src/shared.rs b/default-plugins/strider/src/shared.rs
index c51cb312..19728034 100644
--- a/default-plugins/strider/src/shared.rs
+++ b/default-plugins/strider/src/shared.rs
@@ -31,7 +31,6 @@ pub fn render_list_tip(y: usize, max_cols: usize) {
print_text_with_coordinates(tip, 0, y, Some(max_cols), None);
}
-// returns the list (start_index, selected_index_in_range, end_index)
pub fn calculate_list_bounds(
result_count: usize,
max_result_count: usize,
@@ -48,17 +47,17 @@ pub fn calculate_list_bounds(
break;
}
if !alternate && start_index > 0 {
- start_index -= 1;
- room_in_list -= 1;
+ start_index = start_index.saturating_sub(1);
+ room_in_list = room_in_list.saturating_sub(1);
} else if alternate && end_index < result_count {
end_index += 1;
- room_in_list -= 1;
+ room_in_list = room_in_list.saturating_sub(1);
} else if start_index > 0 {
- start_index -= 1;
- room_in_list -= 1;
+ start_index = start_index.saturating_sub(1);
+ room_in_list = room_in_list.saturating_sub(1);
} else if end_index < result_count {
end_index += 1;
- room_in_list -= 1;
+ room_in_list = room_in_list.saturating_sub(1);
} else {
break;
}
@@ -80,15 +79,13 @@ pub fn render_search_term(search_term: &str) {
}
pub fn render_current_path(
- initial_cwd: &PathBuf,
- path: &PathBuf,
+ full_path: &PathBuf,
path_is_dir: bool,
handling_filepick: bool,
max_cols: usize,
) {
let prompt = "PATH: ";
- let current_path = initial_cwd.join(path);
- let current_path = current_path.display().to_string();
+ let current_path = full_path.display().to_string();
let prompt_len = prompt.width();
let current_path_len = current_path.width();
@@ -118,7 +115,7 @@ pub fn render_current_path(
current_path
} else {
truncate_path(
- initial_cwd.join(path),
+ full_path.clone(),
current_path_len.saturating_sub(max_path_len),
)
};
diff --git a/default-plugins/strider/src/state.rs b/default-plugins/strider/src/state.rs
index 0bf5b268..93c6cf1b 100644
--- a/default-plugins/strider/src/state.rs
+++ b/default-plugins/strider/src/state.rs
@@ -16,7 +16,7 @@ pub struct State {
pub hide_hidden_files: bool,
pub current_rows: Option<usize>,
pub handling_filepick_request_from: Option<(PipeSource, BTreeMap<String, String>)>,
- pub initial_cwd: PathBuf, // TODO: get this from zellij
+ pub initial_cwd: PathBuf,
pub is_searching: bool,
pub search_term: String,
pub close_on_selection: bool,
@@ -137,7 +137,7 @@ impl State {
pub fn descend_to_root_path(&mut self) {
self.search_term.clear();
self.search_view.clear_and_reset_selection();
- self.file_list_view.descend_to_root_path();
+ self.file_list_view.descend_to_root_path(&self.initial_cwd);
refresh_directory(&self.file_list_view.path);
}
pub fn toggle_hidden_files(&mut self) {
@@ -214,13 +214,7 @@ impl State {
}
}
pub fn send_filepick_response(&mut self) {
- let selected_path = self.initial_cwd.join(
- self.file_list_view
- .path
- .strip_prefix(ROOT)
- .map(|p| p.to_path_buf())
- .unwrap_or_else(|_| self.file_list_view.path.clone()),
- );
+ let selected_path = &self.file_list_view.path;
match &self.handling_filepick_request_from {
Some((PipeSource::Plugin(plugin_id), args)) => {
pipe_message_to_plugin(
@@ -245,7 +239,6 @@ impl State {
}
}
-pub(crate) fn refresh_directory(path: &Path) {
- let path_on_host = Path::new(ROOT).join(path.strip_prefix("/").unwrap_or(path));
- scan_host_folder(&path_on_host);
+pub(crate) fn refresh_directory(full_path: &Path) {
+ change_host_folder(PathBuf::from(full_path));
}
diff --git a/zellij-server/src/plugins/mod.rs b/zellij-server/src/plugins/mod.rs
index 48620a99..6e84649a 100644
--- a/zellij-server/src/plugins/mod.rs
+++ b/zellij-server/src/plugins/mod.rs
@@ -54,9 +54,10 @@ pub enum PluginInstruction {
Option<PaneId>, // pane id to replace if this is to be opened "in-place"
ClientId,
Size,
- Option<PathBuf>, // cwd
- bool, // skip cache
- Option<bool>, // should focus plugin
+ Option<PathBuf>, // cwd
+ Option<PluginId>, // the focused plugin id if relevant
+ bool, // skip cache
+ Option<bool>, // should focus plugin
Option<FloatingPaneCoordinates>,
),
LoadBackgroundPlugin(RunPluginOrAlias, ClientId),
@@ -253,7 +254,7 @@ pub(crate) fn plugin_thread_main(
engine,
plugin_dir,
path_to_default_shell,
- zellij_cwd,
+ zellij_cwd.clone(),
capabilities,
client_attributes,
default_shell,
@@ -287,12 +288,19 @@ pub(crate) fn plugin_thread_main(
client_id,
size,
cwd,
+ focused_plugin_id,
skip_cache,
should_focus_plugin,
floating_pane_coordinates,
) => {
run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases);
- let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd);
+ let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd).or_else(|| {
+ if let Some(plugin_id) = focused_plugin_id {
+ wasm_bridge.get_plugin_cwd(plugin_id, client_id)
+ } else {
+ None
+ }
+ });
let run_plugin = run_plugin_or_alias.get_run_plugin();
let start_suppressed = false;
match wasm_bridge.load_plugin(
@@ -313,12 +321,17 @@ pub(crate) fn plugin_thread_main(
tab_index,
plugin_id,
pane_id_to_replace,
- cwd,
+ cwd.clone(),
start_suppressed,
floating_pane_coordinates,
should_focus_plugin,
Some(client_id),
)));
+
+ drop(bus.senders.send_to_pty(PtyInstruction::ReportPluginCwd(
+ plugin_id,
+ cwd.unwrap_or_else(|| zellij_cwd.clone()),
+ )));
},
Err(e) => {
log::error!("Failed to load plugin: {e}");
@@ -916,9 +929,18 @@ pub(crate) fn plugin_thread_main(
wasm_bridge.start_fs_watcher_if_not_started();
},
PluginInstruction::ChangePluginHostDir(new_host_folder, plugin_id, client_id) => {
- wasm_bridge
- .change_plugin_host_dir(new_host_folder, plugin_id, client_id)
- .non_fatal();
+ if let Ok(_) = wasm_bridge.change_plugin_host_dir(
+ new_host_folder.clone(),
+ plugin_id,
+ client_id,
+ ) {
+ drop(
+ bus.senders.send_to_pty(PtyInstruction::ReportPluginCwd(
+ plugin_id,
+ new_host_folder,
+ )),
+ );
+ }
},
PluginInstruction::WebServerStarted(base_url) => {
let updates = vec![(
diff --git a/zellij-server/src/plugins/unit/plugin_tests.rs b/zellij-server/src/plugins/unit/plugin_tests.rs
index 276461d9..700011c8 100644
--- a/zellij-server/src/plugins/unit/plugin_tests.rs
+++ b/zellij-server/src/plugins/unit/plugin_tests.rs
@@ -713,6 +713,7 @@ pub fn load_new_plugin_from_hd() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -795,6 +796,7 @@ pub fn load_new_plugin_with_plugin_alias() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -873,6 +875,7 @@ pub fn plugin_workers() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -955,6 +958,7 @@ pub fn plugin_workers_persist_state() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1047,6 +1051,7 @@ pub fn can_subscribe_to_hd_events() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1127,6 +1132,7 @@ pub fn switch_to_mode_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1201,6 +1207,7 @@ pub fn switch_to_mode_plugin_command_permission_denied() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1275,6 +1282,7 @@ pub fn new_tabs_with_layout_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1363,6 +1371,7 @@ pub fn new_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1437,6 +1446,7 @@ pub fn go_to_next_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1510,6 +1520,7 @@ pub fn go_to_previous_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1583,6 +1594,7 @@ pub fn resize_focused_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1656,6 +1668,7 @@ pub fn resize_focused_pane_with_direction_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1729,6 +1742,7 @@ pub fn focus_next_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1802,6 +1816,7 @@ pub fn focus_previous_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1875,6 +1890,7 @@ pub fn move_focus_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -1948,6 +1964,7 @@ pub fn move_focus_or_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2021,6 +2038,7 @@ pub fn edit_scrollback_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2094,6 +2112,7 @@ pub fn write_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2167,6 +2186,7 @@ pub fn write_chars_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2240,6 +2260,7 @@ pub fn toggle_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2313,6 +2334,7 @@ pub fn move_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2386,6 +2408,7 @@ pub fn move_pane_with_direction_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2460,6 +2483,7 @@ pub fn clear_screen_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2534,6 +2558,7 @@ pub fn scroll_up_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2607,6 +2632,7 @@ pub fn scroll_down_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2680,6 +2706,7 @@ pub fn scroll_to_top_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2753,6 +2780,7 @@ pub fn scroll_to_bottom_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2826,6 +2854,7 @@ pub fn page_scroll_up_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2899,6 +2928,7 @@ pub fn page_scroll_down_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -2972,6 +3002,7 @@ pub fn toggle_focus_fullscreen_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3045,6 +3076,7 @@ pub fn toggle_pane_frames_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3118,6 +3150,7 @@ pub fn toggle_pane_embed_or_eject_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3191,6 +3224,7 @@ pub fn undo_rename_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3264,6 +3298,7 @@ pub fn close_focus_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3337,6 +3372,7 @@ pub fn toggle_active_tab_sync_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3410,6 +3446,7 @@ pub fn close_focused_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3483,6 +3520,7 @@ pub fn undo_rename_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3556,6 +3594,7 @@ pub fn previous_swap_layout_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3629,6 +3668,7 @@ pub fn next_swap_layout_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3702,6 +3742,7 @@ pub fn go_to_tab_name_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3775,6 +3816,7 @@ pub fn focus_or_create_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3848,6 +3890,7 @@ pub fn go_to_tab() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -3921,6 +3964,7 @@ pub fn start_or_reload_plugin() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4001,6 +4045,7 @@ pub fn quit_zellij_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4081,6 +4126,7 @@ pub fn detach_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4161,6 +4207,7 @@ pub fn open_file_floating_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4245,6 +4292,7 @@ pub fn open_file_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4330,6 +4378,7 @@ pub fn open_file_with_line_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4414,6 +4463,7 @@ pub fn open_file_with_line_floating_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4498,6 +4548,7 @@ pub fn open_terminal_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4578,6 +4629,7 @@ pub fn open_terminal_floating_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4658,6 +4710,7 @@ pub fn open_command_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4738,6 +4791,7 @@ pub fn open_command_pane_floating_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4811,6 +4865,7 @@ pub fn switch_to_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4884,6 +4939,7 @@ pub fn hide_self_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -4956,6 +5012,7 @@ pub fn show_self_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5029,6 +5086,7 @@ pub fn close_terminal_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5102,6 +5160,7 @@ pub fn close_plugin_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5175,6 +5234,7 @@ pub fn focus_terminal_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5248,6 +5308,7 @@ pub fn focus_plugin_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5321,6 +5382,7 @@ pub fn rename_terminal_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5394,6 +5456,7 @@ pub fn rename_plugin_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5467,6 +5530,7 @@ pub fn rename_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5549,6 +5613,7 @@ pub fn send_configuration_to_plugins() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5619,6 +5684,7 @@ pub fn request_plugin_permissions() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5713,6 +5779,7 @@ pub fn granted_permission_request_result() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5806,6 +5873,7 @@ pub fn denied_permission_request_result() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5879,6 +5947,7 @@ pub fn run_command_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -5959,6 +6028,7 @@ pub fn run_command_with_env_vars_and_cwd_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6039,6 +6109,7 @@ pub fn web_request_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6112,6 +6183,7 @@ pub fn unblock_input_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6196,6 +6268,7 @@ pub fn block_input_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6288,6 +6361,7 @@ pub fn pipe_output_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6373,6 +6447,7 @@ pub fn pipe_message_to_plugin_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6469,6 +6544,7 @@ pub fn switch_session_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6552,6 +6628,7 @@ pub fn switch_session_with_layout_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6635,6 +6712,7 @@ pub fn switch_session_with_layout_and_cwd_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6718,6 +6796,7 @@ pub fn disconnect_other_clients_plugins_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6801,6 +6880,7 @@ pub fn reconfigure_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6888,6 +6968,7 @@ pub fn run_plugin_in_specific_cwd() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -6964,6 +7045,7 @@ pub fn hide_pane_with_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7037,6 +7119,7 @@ pub fn show_pane_with_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7117,6 +7200,7 @@ pub fn open_command_pane_background_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7194,6 +7278,7 @@ pub fn rerun_command_pane_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7267,6 +7352,7 @@ pub fn resize_pane_with_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7340,6 +7426,7 @@ pub fn edit_scrollback_for_pane_with_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7413,6 +7500,7 @@ pub fn write_to_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7486,6 +7574,7 @@ pub fn write_chars_to_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7559,6 +7648,7 @@ pub fn move_pane_with_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7632,6 +7722,7 @@ pub fn move_pane_with_pane_id_in_direction_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7705,6 +7796,7 @@ pub fn clear_screen_for_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7778,6 +7870,7 @@ pub fn scroll_up_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7851,6 +7944,7 @@ pub fn scroll_down_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7924,6 +8018,7 @@ pub fn scroll_to_top_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -7997,6 +8092,7 @@ pub fn scroll_to_bottom_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8070,6 +8166,7 @@ pub fn page_scroll_up_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8143,6 +8240,7 @@ pub fn page_scroll_down_in_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8216,6 +8314,7 @@ pub fn toggle_pane_id_fullscreen_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8289,6 +8388,7 @@ pub fn toggle_pane_embed_or_eject_for_pane_id_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8362,6 +8462,7 @@ pub fn close_tab_with_index_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8435,6 +8536,7 @@ pub fn break_panes_to_new_tab_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8508,6 +8610,7 @@ pub fn break_panes_to_tab_with_index_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8581,6 +8684,7 @@ pub fn reload_plugin_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8654,6 +8758,7 @@ pub fn load_new_plugin_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8734,6 +8839,7 @@ pub fn rebind_keys_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8810,6 +8916,7 @@ pub fn list_clients_plugin_command() {
client_id,
size,
None,
+ None,
false,
None,
None,
@@ -8883,6 +8990,7 @@ pub fn before_close_plugin_event() {
client_id,
size,
None,
+ None,
false,
None,
None,
diff --git a/zellij-server/src/plugins/wasm_bridge.rs b/zellij-server/src/plugins/wasm_bridge.rs
index fd4b0d36..9ccd7c1d 100644
--- a/zellij-server/src/plugins/wasm_bridge.rs
+++ b/zellij-server/src/plugins/wasm_bridge.rs
@@ -775,6 +775,27 @@ impl WasmBridge {
}
Ok(())
}
+ pub fn get_plugin_cwd(&self, plugin_id: PluginId, client_id: ClientId) -> Option<PathBuf> {
+ self.plugin_map
+ .lock()
+ .unwrap()
+ .running_plugins()
+ .iter()
+ .find_map(|(p_id, c_id, running_plugin)| {
+ if p_id == &plugin_id && c_id == &client_id {
+ let plugin_cwd = running_plugin
+ .lock()
+ .unwrap()
+ .store
+ .data()
+ .plugin_cwd
+ .clone();
+ Some(plugin_cwd)
+ } else {
+ None
+ }
+ })
+ }
pub fn change_plugin_host_dir(
&mut self,
new_host_dir: PathBuf,
@@ -793,12 +814,6 @@ impl WasmBridge {
.running_plugins_and_subscriptions()
.iter()
.cloned()
- .filter(|(plugin_id, _client_id, _running_plugin, _subscriptions)| {
- // TODO: cache this somehow in this case...
- !&self
- .cached_events_for_pending_plugins
- .contains_key(&plugin_id)
- })
.collect();
task::spawn({
let senders = self.senders.clone();
diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs
index 3b61f445..ebed4cbb 100644
--- a/zellij-server/src/plugins/zellij_exports.rs
+++ b/zellij-server/src/plugins/zellij_exports.rs
@@ -2222,6 +2222,7 @@ fn load_new_plugin(
client_id,
size,
cwd,
+ None,
skip_cache,
None,
None,
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 26fe7203..88bfee7d 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -176,6 +176,7 @@ pub enum PtyInstruction {
post_command_discovery_hook: Option<String>,
},
ListClientsToPlugin(SessionLayoutMetadata, PluginId, ClientId),
+ ReportPluginCwd(PluginId, PathBuf),
Exit,
}
@@ -199,6 +200,7 @@ impl From<&PtyInstruction> for PtyContext {
PtyInstruction::ListClientsMetadata(..) => PtyContext::ListClientsMetadata,
PtyInstruction::Reconfigure { .. } => PtyContext::Reconfigure,
PtyInstruction::ListClientsToPlugin(..) => PtyContext::ListClientsToPlugin,
+ PtyInstruction::ReportPluginCwd(..) => PtyContext::ReportPluginCwd,
PtyInstruction::Exit => PtyContext::Exit,
}
}
@@ -213,6 +215,7 @@ pub(crate) struct Pty {
task_handles: HashMap<u32, JoinHandle<()>>, // terminal_id to join-handle
default_editor: Option<PathBuf>,
post_command_discovery_hook: Option<String>,
+ plugin_cwds: HashMap<u32, PathBuf>, // plugin_id -> cwd
}
pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
@@ -676,6 +679,9 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
.with_context(err_context)
.non_fatal();
},
+ PtyInstruction::ReportPluginCwd(plugin_id, cwd) => {
+ pty.plugin_cwds.insert(plugin_id, cwd);
+ },
PtyInstruction::LogLayoutToHd(mut session_layout_metadata) => {
let err_context = || format!("Failed to dump layout");
pty.populate_session_layout_metadata(&mut session_layout_metadata);
@@ -755,6 +761,7 @@ impl Pty {
default_editor,
originating_plugins: HashMap::new(),
post_command_discovery_hook,
+ plugin_cwds: HashMap::new(),
}
}
pub fn get_default_terminal(
@@ -803,27 +810,31 @@ impl Pty {
.active_panes
.get(&client_id)
.and_then(|pane| match pane {
- PaneId::Plugin(..) => None,
- PaneId::Terminal(id) => self.id_to_child_pid.get(id),
+ PaneId::Plugin(plugin_id) => self.plugin_cwds.get(plugin_id).cloned(),
+ PaneId::Terminal(id) => self.id_to_child_pid.get(id).and_then(|&id| {
+ self.bus
+ .os_input
+ .as_ref()
+ .and_then(|input| input.get_cwd(Pid::from_raw(id)))
+ }),
})
- .and_then(|&id| {
- self.bus
- .os_input
- .as_ref()
- .and_then(|input| input.get_cwd(Pid::from_raw(id)))
- });
};
};
}
- fn fill_cwd_from_pane_id(&self, terminal_action: &mut TerminalAction, pane_id: &u32) {
+ fn fill_cwd_from_pane_id(&self, terminal_action: &mut TerminalAction, pane_id: &PaneId) {
if let TerminalAction::RunCommand(run_command) = terminal_action {
if run_command.cwd.is_none() {
- run_command.cwd = self.id_to_child_pid.get(pane_id).and_then(|&id| {
- self.bus
- .os_input
- .as_ref()
- .and_then(|input| input.get_cwd(Pid::from_raw(id)))
- });
+ run_command.cwd = match pane_id {
+ PaneId::Terminal(terminal_pane_id) => {
+ self.id_to_child_pid.get(terminal_pane_id).and_then(|&id| {
+ self.bus
+ .os_input
+ .as_ref()
+ .and_then(|input| input.get_cwd(Pid::from_raw(id)))
+ })
+ },
+ PaneId::Plugin(plugin_id) => self.plugin_cwds.get(plugin_id).cloned(),
+ };
};
};
}
@@ -849,9 +860,7 @@ impl Pty {
ClientTabIndexOrPaneId::PaneId(pane_id) => {
let mut terminal_action =
terminal_action.unwrap_or_else(|| self.get_default_terminal(None, None));
- if let PaneId::Terminal(terminal_pane_id) = pane_id {
- self.fill_cwd_from_pane_id(&mut terminal_action, &terminal_pane_id);
- }
+ self.fill_cwd_from_pane_id(&mut terminal_action, &pane_id);
terminal_action
},
};
@@ -1482,18 +1491,24 @@ impl Pty {
self.active_panes
.get(&client_id)
.and_then(|pane| match pane {
- PaneId::Plugin(..) => None,
- PaneId::Terminal(id) => self.id_to_child_pid.get(id),
- })
- .and_then(|&id| {
- self.bus
- .os_input
- .as_ref()
- .and_then(|input| input.get_cwd(Pid::from_raw(id)))
+ PaneId::Plugin(plugin_id) => self.plugin_cwds.get(plugin_id).cloned(),
+ PaneId::Terminal(id) => self.id_to_child_pid.get(id).and_then(|&id| {
+ self.bus
+ .os_input
+ .as_ref()
+ .and_then(|input| input.get_cwd(Pid::from_raw(id)))
+ }),
})
};
let cwd = cwd.or_else(get_focused_cwd);
+ let focused_plugin_id = self
+ .active_panes
+ .get(&client_id)
+ .and_then(|pane| match pane {
+ PaneId::Plugin(plugin_id) => Some(*plugin_id),
+ _ => None,
+ });
if let RunPluginOrAlias::Alias(alias) = &mut run {
let cwd = get_focused_cwd();
@@ -1509,6 +1524,7 @@ impl Pty {
client_id,
size,
cwd,
+ focused_plugin_id,
skip_cache,
should_focus_plugin,
floating_pane_coordinates,
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index 854410b6..836b5100 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -412,6 +412,7 @@ pub enum PtyContext {
ListClientsMetadata,
Reconfigure,
ListClientsToPlugin,
+ ReportPluginCwd,
Exit,
}