aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2025-02-20 10:03:34 +0100
committerGitHub <noreply@github.com>2025-02-20 10:03:34 +0100
commitd1a45093455ecc1291a226fb9cbb1eacb35ac01a (patch)
treee88ef9a7b5d20be6e995eb45029ff177666931d9
parentdocs(changelog): resize shortcuts (diff)
downloadsl0ppij-d1a45093455ecc1291a226fb9cbb1eacb35ac01a.tar.gz
sl0ppij-d1a45093455ecc1291a226fb9cbb1eacb35ac01a.tar.xz
sl0ppij-d1a45093455ecc1291a226fb9cbb1eacb35ac01a.zip
fix(ux): some filepicker improvements (#4007)
* allow closing plugin pane after replacing it * start of strider improvements * improve strider's ux * fix selected text ui component * style(fmt): rustfmt * style(fmt): rustfmt
-rw-r--r--default-plugins/strider/src/file_list_view.rs10
-rw-r--r--default-plugins/strider/src/main.rs26
-rw-r--r--default-plugins/strider/src/state.rs79
-rw-r--r--zellij-server/src/plugins/zellij_exports.rs45
-rw-r--r--zellij-server/src/pty.rs4
-rw-r--r--zellij-server/src/route.rs4
-rw-r--r--zellij-server/src/screen.rs14
-rw-r--r--zellij-server/src/tab/mod.rs98
-rw-r--r--zellij-server/src/ui/components/text.rs9
-rw-r--r--zellij-tile/src/shim.rs21
-rw-r--r--zellij-utils/assets/prost/api.plugin_command.rs6
-rw-r--r--zellij-utils/src/data.rs7
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.proto3
-rw-r--r--zellij-utils/src/plugin_api/plugin_command.rs65
14 files changed, 276 insertions, 115 deletions
diff --git a/default-plugins/strider/src/file_list_view.rs b/default-plugins/strider/src/file_list_view.rs
index 9a2a388e..ccbbe292 100644
--- a/default-plugins/strider/src/file_list_view.rs
+++ b/default-plugins/strider/src/file_list_view.rs
@@ -30,14 +30,14 @@ impl FileListView {
self.path.pop();
self.path_is_dir = true;
self.files.clear();
- self.reset_selected();
+ self.clear_selected();
refresh_directory(&self.path);
}
pub fn descend_to_root_path(&mut self) {
self.path.clear();
self.path_is_dir = true;
self.files.clear();
- self.reset_selected();
+ self.clear_selected();
refresh_directory(&self.path);
}
pub fn enter_dir(&mut self, entry: &FsEntry) {
@@ -46,10 +46,10 @@ impl FileListView {
self.path = path;
self.path_is_dir = is_dir;
self.files.clear();
- self.reset_selected();
+ self.clear_selected();
}
- pub fn reset_selected(&mut self) {
- *self.selected_mut() = self.selected().unwrap_or(0);
+ pub fn clear_selected(&mut self) {
+ self.cursor_hist.remove(&self.path);
}
pub fn update_files(
&mut self,
diff --git a/default-plugins/strider/src/main.rs b/default-plugins/strider/src/main.rs
index b1c2308b..cd9dda4d 100644
--- a/default-plugins/strider/src/main.rs
+++ b/default-plugins/strider/src/main.rs
@@ -32,7 +32,7 @@ impl ZellijPlugin for State {
EventType::Timer,
EventType::FileSystemUpdate,
]);
- self.file_list_view.reset_selected();
+ 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
@@ -73,7 +73,11 @@ impl ZellijPlugin for State {
should_render = true;
},
BareKey::Esc if key.has_no_modifiers() => {
- self.clear_search_term_or_descend();
+ if self.is_searching {
+ self.clear_search_term();
+ } else {
+ self.file_list_view.clear_selected();
+ }
should_render = true;
},
BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => {
@@ -87,15 +91,11 @@ impl ZellijPlugin for State {
self.move_selection_down();
should_render = true;
},
- BareKey::Enter
- if key.has_no_modifiers() && self.handling_filepick_request_from.is_some() =>
- {
- self.send_filepick_response();
- },
- BareKey::Enter if key.has_no_modifiers() => {
- self.open_selected_path();
+ BareKey::Right | BareKey::Tab | BareKey::Enter if key.has_no_modifiers() => {
+ self.traverse_dir();
+ should_render = true;
},
- BareKey::Right | BareKey::Tab if key.has_no_modifiers() => {
+ BareKey::Right if key.has_no_modifiers() => {
self.traverse_dir();
should_render = true;
},
@@ -123,6 +123,12 @@ impl ZellijPlugin for State {
self.handle_left_click(line);
should_render = true;
},
+ Mouse::Hover(line, _) => {
+ if line >= 0 {
+ self.handle_mouse_hover(line);
+ should_render = true;
+ }
+ },
_ => {},
},
_ => {
diff --git a/default-plugins/strider/src/state.rs b/default-plugins/strider/src/state.rs
index 87f70d4b..0bf5b268 100644
--- a/default-plugins/strider/src/state.rs
+++ b/default-plugins/strider/src/state.rs
@@ -14,9 +14,6 @@ pub struct State {
pub file_list_view: FileListView,
pub search_view: SearchView,
pub hide_hidden_files: bool,
- pub loading: bool,
- pub loading_animation_offset: u8,
- pub should_open_floating: 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
@@ -50,6 +47,12 @@ impl State {
.update_search_results(&self.search_term, &self.file_list_view.files);
}
}
+ pub fn clear_search_term(&mut self) {
+ self.search_term.clear();
+ self.search_view
+ .update_search_results(&self.search_term, &self.file_list_view.files);
+ self.is_searching = false;
+ }
pub fn clear_search_term_or_descend(&mut self) {
if self.search_term.is_empty() {
self.descend_to_previous_path();
@@ -85,7 +88,7 @@ impl State {
);
let prev_selected = self.search_view.selected_search_result;
self.search_view.selected_search_result =
- (line as usize).saturating_sub(2) + start_index;
+ (line as usize).saturating_sub(4) + start_index;
if prev_selected == self.search_view.selected_search_result {
self.traverse_dir();
}
@@ -97,13 +100,35 @@ impl State {
);
let prev_selected = self.file_list_view.selected();
*self.file_list_view.selected_mut() =
- (line as usize).saturating_sub(2) + start_index;
+ (line as usize).saturating_sub(4) + start_index;
if prev_selected == self.file_list_view.selected() {
self.traverse_dir();
}
}
}
}
+ pub fn handle_mouse_hover(&mut self, line: isize) {
+ if let Some(current_rows) = self.current_rows {
+ let rows_for_list = current_rows.saturating_sub(5);
+ if self.is_searching {
+ let (start_index, _selected_index_in_range, _end_index) = calculate_list_bounds(
+ self.search_view.search_result_count(),
+ rows_for_list,
+ Some(self.search_view.selected_search_result),
+ );
+ self.search_view.selected_search_result =
+ (line as usize).saturating_sub(4) + start_index;
+ } else {
+ let (start_index, _selected_index_in_range, _end_index) = calculate_list_bounds(
+ self.file_list_view.files.len(),
+ rows_for_list,
+ self.file_list_view.selected(),
+ );
+ *self.file_list_view.selected_mut() =
+ (line as usize).saturating_sub(4) + start_index;
+ }
+ }
+ }
pub fn descend_to_previous_path(&mut self) {
self.search_term.clear();
self.search_view.clear_and_reset_selection();
@@ -134,8 +159,17 @@ impl State {
FsEntry::File(_p, _) => {
self.file_list_view.enter_dir(&entry);
self.search_view.clear_and_reset_selection();
+ if self.handling_filepick_request_from.is_some() {
+ self.send_filepick_response();
+ } else {
+ self.open_selected_path();
+ }
},
}
+ } else if self.handling_filepick_request_from.is_some() {
+ self.send_filepick_response();
+ } else {
+ self.open_selected_path();
}
self.is_searching = false;
self.search_term.clear();
@@ -147,20 +181,37 @@ impl State {
}
pub fn open_selected_path(&mut self) {
if self.file_list_view.path_is_dir {
- open_terminal(&self.file_list_view.path);
+ if self.close_on_selection {
+ open_terminal_in_place_of_plugin(&self.file_list_view.path, true);
+ } else {
+ open_terminal(&self.file_list_view.path);
+ }
} else {
if let Some(parent_folder) = self.file_list_view.path.parent() {
- open_file(
- FileToOpen::new(&self.file_list_view.path).with_cwd(parent_folder.into()),
- BTreeMap::new(),
- );
+ if self.close_on_selection {
+ open_file_in_place_of_plugin(
+ FileToOpen::new(&self.file_list_view.path).with_cwd(parent_folder.into()),
+ true,
+ BTreeMap::new(),
+ );
+ } else {
+ open_file(
+ FileToOpen::new(&self.file_list_view.path).with_cwd(parent_folder.into()),
+ BTreeMap::new(),
+ );
+ }
} else {
- open_file(FileToOpen::new(&self.file_list_view.path), BTreeMap::new());
+ if self.close_on_selection {
+ open_file_in_place_of_plugin(
+ FileToOpen::new(&self.file_list_view.path),
+ true,
+ BTreeMap::new(),
+ );
+ } else {
+ open_file(FileToOpen::new(&self.file_list_view.path), BTreeMap::new());
+ }
}
}
- if self.close_on_selection {
- close_self();
- }
}
pub fn send_filepick_response(&mut self) {
let selected_path = self.initial_cwd.join(
diff --git a/zellij-server/src/plugins/zellij_exports.rs b/zellij-server/src/plugins/zellij_exports.rs
index 158d8c0a..4c6496cc 100644
--- a/zellij-server/src/plugins/zellij_exports.rs
+++ b/zellij-server/src/plugins/zellij_exports.rs
@@ -256,15 +256,26 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
PluginCommand::OpenTerminalInPlace(cwd) => {
open_terminal_in_place(env, cwd.path.try_into()?)
},
- PluginCommand::OpenTerminalInPlaceOfPlugin(cwd) => {
- open_terminal_in_place_of_plugin(env, cwd.path.try_into()?)
+ PluginCommand::OpenTerminalInPlaceOfPlugin(cwd, close_plugin_after_replace) => {
+ open_terminal_in_place_of_plugin(
+ env,
+ cwd.path.try_into()?,
+ close_plugin_after_replace,
+ )
},
PluginCommand::OpenCommandPaneInPlace(command_to_run, context) => {
open_command_pane_in_place(env, command_to_run, context)
},
- PluginCommand::OpenCommandPaneInPlaceOfPlugin(command_to_run, context) => {
- open_command_pane_in_place_of_plugin(env, command_to_run, context)
- },
+ PluginCommand::OpenCommandPaneInPlaceOfPlugin(
+ command_to_run,
+ close_plugin_after_replace,
+ context,
+ ) => open_command_pane_in_place_of_plugin(
+ env,
+ command_to_run,
+ close_plugin_after_replace,
+ context,
+ ),
PluginCommand::RenameSession(new_session_name) => {
rename_session(env, new_session_name)
},
@@ -413,9 +424,16 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
floating_pane_coordinates,
context,
),
- PluginCommand::OpenFileInPlaceOfPlugin(file_to_open, context) => {
- open_file_in_place_of_plugin(env, file_to_open, context)
- },
+ PluginCommand::OpenFileInPlaceOfPlugin(
+ file_to_open,
+ close_plugin_after_replace,
+ context,
+ ) => open_file_in_place_of_plugin(
+ env,
+ file_to_open,
+ close_plugin_after_replace,
+ context,
+ ),
},
(PermissionStatus::Denied, permission) => {
log::error!(
@@ -703,6 +721,7 @@ fn open_file_floating_near_plugin(
fn open_file_in_place_of_plugin(
env: &PluginEnv,
file_to_open: FileToOpen,
+ close_plugin_after_replace: bool,
context: BTreeMap<String, String>,
) {
let cwd = file_to_open
@@ -719,6 +738,7 @@ fn open_file_in_place_of_plugin(
let pty_instr = PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
+ close_plugin_after_replace,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
);
let _ = env.senders.send_to_pty(pty_instr);
@@ -828,7 +848,11 @@ fn open_terminal_in_place(env: &PluginEnv, cwd: PathBuf) {
apply_action!(action, error_msg, env);
}
-fn open_terminal_in_place_of_plugin(env: &PluginEnv, cwd: PathBuf) {
+fn open_terminal_in_place_of_plugin(
+ env: &PluginEnv,
+ cwd: PathBuf,
+ close_plugin_after_replace: bool,
+) {
let cwd = env.plugin_cwd.join(cwd);
let mut default_shell = env.default_shell.clone().unwrap_or_else(|| {
TerminalAction::RunCommand(RunCommand {
@@ -843,6 +867,7 @@ fn open_terminal_in_place_of_plugin(env: &PluginEnv, cwd: PathBuf) {
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
Some(default_shell),
name,
+ close_plugin_after_replace,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
));
}
@@ -850,6 +875,7 @@ fn open_terminal_in_place_of_plugin(env: &PluginEnv, cwd: PathBuf) {
fn open_command_pane_in_place_of_plugin(
env: &PluginEnv,
command_to_run: CommandToRun,
+ close_plugin_after_replace: bool,
context: BTreeMap<String, String>,
) {
let command = command_to_run.path;
@@ -878,6 +904,7 @@ fn open_command_pane_in_place_of_plugin(
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
Some(run_cmd),
name,
+ close_plugin_after_replace,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
));
}
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index dc9e5809..3bb5f227 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -78,6 +78,7 @@ pub enum PtyInstruction {
SpawnInPlaceTerminal(
Option<TerminalAction>,
Option<String>,
+ bool, // close replaced pane
ClientTabIndexOrPaneId,
), // String is an optional pane name
DumpLayout(SessionLayoutMetadata, ClientId),
@@ -278,6 +279,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
PtyInstruction::SpawnInPlaceTerminal(
terminal_action,
name,
+ close_replaced_pane,
client_id_tab_index_or_pane_id,
) => {
let err_context = || {
@@ -318,6 +320,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
hold_for_command,
pane_title,
invoked_with,
+ close_replaced_pane,
client_id_tab_index_or_pane_id,
))
.with_context(err_context)?;
@@ -333,6 +336,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
hold_for_command,
pane_title,
invoked_with,
+ close_replaced_pane,
client_id_tab_index_or_pane_id,
))
.with_context(err_context)?;
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 8442db8c..ab42f825 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -312,11 +312,13 @@ pub(crate) fn route_action(
Some(pane_id) => PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
+ false,
ClientTabIndexOrPaneId::PaneId(pane_id),
),
None => PtyInstruction::SpawnInPlaceTerminal(
Some(open_file),
Some(title),
+ false,
ClientTabIndexOrPaneId::ClientId(client_id),
),
},
@@ -389,6 +391,7 @@ pub(crate) fn route_action(
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
run_cmd,
name,
+ false,
ClientTabIndexOrPaneId::PaneId(pane_id),
))
.with_context(err_context)?;
@@ -398,6 +401,7 @@ pub(crate) fn route_action(
.send_to_pty(PtyInstruction::SpawnInPlaceTerminal(
run_cmd,
name,
+ false,
ClientTabIndexOrPaneId::ClientId(client_id),
))
.with_context(err_context)?;
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 08c023da..fbc1d967 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -349,6 +349,7 @@ pub enum ScreenInstruction {
HoldForCommand,
Option<InitialTitle>,
Option<Run>,
+ bool, // close replaced pane
ClientTabIndexOrPaneId,
),
DumpLayoutToHd,
@@ -2397,10 +2398,16 @@ impl Screen {
hold_for_command: HoldForCommand,
run: Option<Run>,
pane_title: Option<InitialTitle>,
+ close_replaced_pane: bool,
client_id_tab_index_or_pane_id: ClientTabIndexOrPaneId,
) -> Result<()> {
let suppress_pane = |tab: &mut Tab, pane_id: PaneId, new_pane_id: PaneId| {
- let _ = tab.suppress_pane_and_replace_with_pid(pane_id, new_pane_id, run);
+ let _ = tab.suppress_pane_and_replace_with_pid(
+ pane_id,
+ new_pane_id,
+ close_replaced_pane,
+ run,
+ );
if let Some(pane_title) = pane_title {
let _ = tab.rename_pane(pane_title.as_bytes().to_vec(), new_pane_id);
}
@@ -4184,6 +4191,7 @@ pub(crate) fn screen_thread_main(
});
let run_plugin = Run::Plugin(run_plugin_or_alias);
+ let close_replaced_pane = false;
if should_be_in_place {
if let Some(pane_id_to_replace) = pane_id_to_replace {
let client_tab_index_or_pane_id =
@@ -4193,6 +4201,7 @@ pub(crate) fn screen_thread_main(
None,
Some(run_plugin),
Some(pane_title),
+ close_replaced_pane,
client_tab_index_or_pane_id,
)?;
} else if let Some(client_id) = client_id {
@@ -4203,6 +4212,7 @@ pub(crate) fn screen_thread_main(
None,
Some(run_plugin),
Some(pane_title),
+ close_replaced_pane,
client_tab_index_or_pane_id,
)?;
} else {
@@ -4508,6 +4518,7 @@ pub(crate) fn screen_thread_main(
hold_for_command,
pane_title,
invoked_with,
+ close_replaced_pane,
client_id_tab_index_or_pane_id,
) => {
screen.replace_pane(
@@ -4515,6 +4526,7 @@ pub(crate) fn screen_thread_main(
hold_for_command,
invoked_with,
pane_title,
+ close_replaced_pane,
client_id_tab_index_or_pane_id,
)?;
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 8a79ca00..f92cbb9e 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -1320,6 +1320,7 @@ impl Tab {
&mut self,
old_pane_id: PaneId,
new_pane_id: PaneId,
+ close_replaced_pane: bool,
run: Option<Run>,
) -> Result<()> {
// this method creates a new pane from pid and replaces it with the active pane
@@ -1356,27 +1357,36 @@ impl Tab {
self.tiled_panes
.replace_pane(old_pane_id, Box::new(new_pane))
};
- match replaced_pane {
- Some(replaced_pane) => {
- let _ = resize_pty!(
- replaced_pane,
- self.os_api,
- self.senders,
- self.character_cell_size
- );
- let is_scrollback_editor = false;
- self.suppressed_panes.insert(
- PaneId::Terminal(new_pane_id),
- (is_scrollback_editor, replaced_pane),
- );
- },
- None => {
- Err::<(), _>(anyhow!(
- "Could not find editor pane to replace - is no pane focused?"
- ))
- .with_context(err_context)
- .non_fatal();
- },
+ if close_replaced_pane {
+ if let Some(pid) = replaced_pane.as_ref().map(|p| p.pid()) {
+ self.senders
+ .send_to_pty(PtyInstruction::ClosePane(pid))
+ .with_context(err_context)?;
+ }
+ drop(replaced_pane);
+ } else {
+ match replaced_pane {
+ Some(replaced_pane) => {
+ let _ = resize_pty!(
+ replaced_pane,
+ self.os_api,
+ self.senders,
+ self.character_cell_size
+ );
+ let is_scrollback_editor = false;
+ self.suppressed_panes.insert(
+ PaneId::Terminal(new_pane_id),
+ (is_scrollback_editor, replaced_pane),
+ );
+ },
+ None => {
+ Err::<(), _>(anyhow!(
+ "Could not find editor pane to replace - is no pane focused?"
+ ))
+ .with_context(err_context)
+ .non_fatal();
+ },
+ }
}
},
PaneId::Plugin(plugin_pid) => {
@@ -1410,27 +1420,31 @@ impl Tab {
self.tiled_panes
.replace_pane(old_pane_id, Box::new(new_pane))
};
- match replaced_pane {
- Some(replaced_pane) => {
- let _ = resize_pty!(
- replaced_pane,
- self.os_api,
- self.senders,
- self.character_cell_size
- );
- let is_scrollback_editor = false;
- self.suppressed_panes.insert(
- PaneId::Plugin(plugin_pid),
- (is_scrollback_editor, replaced_pane),
- );
- },
- None => {
- Err::<(), _>(anyhow!(
- "Could not find editor pane to replace - is no pane focused?"
- ))
- .with_context(err_context)
- .non_fatal();
- },
+ if close_replaced_pane {
+ drop(replaced_pane);
+ } else {
+ match replaced_pane {
+ Some(replaced_pane) => {
+ let _ = resize_pty!(
+ replaced_pane,
+ self.os_api,
+ self.senders,
+ self.character_cell_size
+ );
+ let is_scrollback_editor = false;
+ self.suppressed_panes.insert(
+ PaneId::Plugin(plugin_pid),
+ (is_scrollback_editor, replaced_pane),
+ );
+ },
+ None => {
+ Err::<(), _>(anyhow!(
+ "Could not find editor pane to replace - is no pane focused?"
+ ))
+ .with_context(err_context)
+ .non_fatal();
+ },
+ }
}
},
}
diff --git a/zellij-server/src/ui/components/text.rs b/zellij-server/src/ui/components/text.rs
index 6c46fc31..56b1f428 100644
--- a/zellij-server/src/ui/components/text.rs
+++ b/zellij-server/src/ui/components/text.rs
@@ -58,7 +58,14 @@ pub fn stringify_text(
break;
}
text_width += character_width;
- if !text.indices.is_empty() {
+
+ if text.selected {
+ // we do this so that selected text will appear selected
+ // even if it does not have color indices
+ stringified.push_str(&format!("{}", base_text_style));
+ }
+
+ if !text.indices.is_empty() || text.selected {
let character_with_styling =
color_index_character(character, i, &text, style, base_text_style);
stringified.push_str(&character_with_styling);
diff --git a/zellij-tile/src/shim.rs b/zellij-tile/src/shim.rs
index b717031d..ed7b124e 100644
--- a/zellij-tile/src/shim.rs
+++ b/zellij-tile/src/shim.rs
@@ -126,8 +126,13 @@ pub fn open_file_floating_near_plugin(
}
/// Open a file in the user's default `$EDITOR`, replacing the plugin pane
-pub fn open_file_in_place_of_plugin(file_to_open: FileToOpen, context: BTreeMap<String, String>) {
- let plugin_command = PluginCommand::OpenFileInPlaceOfPlugin(file_to_open, context);
+pub fn open_file_in_place_of_plugin(
+ file_to_open: FileToOpen,
+ close_plugin_after_replace: bool,
+ context: BTreeMap<String, String>,
+) {
+ let plugin_command =
+ PluginCommand::OpenFileInPlaceOfPlugin(file_to_open, close_plugin_after_replace, context);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
@@ -190,9 +195,10 @@ pub fn open_terminal_in_place<P: AsRef<Path>>(path: P) {
/// Open a new terminal pane to the specified location on the host filesystem, temporarily
/// replacing the plugin pane
-pub fn open_terminal_in_place_of_plugin<P: AsRef<Path>>(path: P) {
+pub fn open_terminal_in_place_of_plugin<P: AsRef<Path>>(path: P, close_plugin_after_replace: bool) {
let file_to_open = FileToOpen::new(path.as_ref().to_path_buf());
- let plugin_command = PluginCommand::OpenTerminalInPlaceOfPlugin(file_to_open);
+ let plugin_command =
+ PluginCommand::OpenTerminalInPlaceOfPlugin(file_to_open, close_plugin_after_replace);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
@@ -260,9 +266,14 @@ pub fn open_command_pane_in_place(command_to_run: CommandToRun, context: BTreeMa
/// plugin pane rather than whichever pane the user is focused on
pub fn open_command_pane_in_place_of_plugin(
command_to_run: CommandToRun,
+ close_plugin_after_replace: bool,
context: BTreeMap<String, String>,
) {
- let plugin_command = PluginCommand::OpenCommandPaneInPlaceOfPlugin(command_to_run, context);
+ let plugin_command = PluginCommand::OpenCommandPaneInPlaceOfPlugin(
+ command_to_run,
+ close_plugin_after_replace,
+ context,
+ );
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
diff --git a/zellij-utils/assets/prost/api.plugin_command.rs b/zellij-utils/assets/prost/api.plugin_command.rs
index 1920f6b6..338af3c8 100644
--- a/zellij-utils/assets/prost/api.plugin_command.rs
+++ b/zellij-utils/assets/prost/api.plugin_command.rs
@@ -219,6 +219,8 @@ pub struct OpenFileInPlaceOfPluginPayload {
pub floating_pane_coordinates: ::core::option::Option<FloatingPaneCoordinates>,
#[prost(message, repeated, tag = "3")]
pub context: ::prost::alloc::vec::Vec<ContextItem>,
+ #[prost(bool, tag = "4")]
+ pub close_plugin_after_replace: bool,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -247,6 +249,8 @@ pub struct OpenCommandPaneInPlaceOfPluginPayload {
pub command_to_run: ::core::option::Option<super::command::Command>,
#[prost(message, repeated, tag = "3")]
pub context: ::prost::alloc::vec::Vec<ContextItem>,
+ #[prost(bool, tag = "4")]
+ pub close_plugin_after_replace: bool,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -265,6 +269,8 @@ pub struct OpenTerminalInPlaceOfPluginPayload {
pub file_to_open: ::core::option::Option<super::file::File>,
#[prost(message, repeated, tag = "3")]
pub context: ::prost::alloc::vec::Vec<ContextItem>,
+ #[prost(bool, tag = "4")]
+ pub close_plugin_after_replace: bool,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
diff --git a/zellij-utils/src/data.rs b/zellij-utils/src/data.rs
index 8399b199..a1be6274 100644
--- a/zellij-utils/src/data.rs
+++ b/zellij-utils/src/data.rs
@@ -2299,10 +2299,11 @@ pub enum PluginCommand {
OpenCommandPaneNearPlugin(CommandToRun, Context),
OpenTerminalNearPlugin(FileToOpen),
OpenTerminalFloatingNearPlugin(FileToOpen, Option<FloatingPaneCoordinates>),
- OpenTerminalInPlaceOfPlugin(FileToOpen),
+ OpenTerminalInPlaceOfPlugin(FileToOpen, bool), // bool -> close_plugin_after_replace
OpenCommandPaneFloatingNearPlugin(CommandToRun, Option<FloatingPaneCoordinates>, Context),
- OpenCommandPaneInPlaceOfPlugin(CommandToRun, Context),
+ OpenCommandPaneInPlaceOfPlugin(CommandToRun, bool, Context), // bool ->
+ // close_plugin_after_replace
OpenFileNearPlugin(FileToOpen, Context),
OpenFileFloatingNearPlugin(FileToOpen, Option<FloatingPaneCoordinates>, Context),
- OpenFileInPlaceOfPlugin(FileToOpen, Context),
+ OpenFileInPlaceOfPlugin(FileToOpen, bool, Context), // bool -> close_plugin_after_replace
}
diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto
index e132909e..3fa321cc 100644
--- a/zellij-utils/src/plugin_api/plugin_command.proto
+++ b/zellij-utils/src/plugin_api/plugin_command.proto
@@ -243,6 +243,7 @@ message OpenFileInPlaceOfPluginPayload {
file.File file_to_open = 1;
optional FloatingPaneCoordinates floating_pane_coordinates = 2;
repeated ContextItem context = 3;
+ bool close_plugin_after_replace = 4;
}
message OpenFileFloatingNearPluginPayload {
@@ -260,6 +261,7 @@ message OpenFileNearPluginPayload {
message OpenCommandPaneInPlaceOfPluginPayload {
command.Command command_to_run = 1;
repeated ContextItem context = 3;
+ bool close_plugin_after_replace = 4;
}
message OpenCommandPaneFloatingNearPluginPayload {
@@ -271,6 +273,7 @@ message OpenCommandPaneFloatingNearPluginPayload {
message OpenTerminalInPlaceOfPluginPayload {
file.File file_to_open = 1;
repeated ContextItem context = 3;
+ bool close_plugin_after_replace = 4;
}
message OpenTerminalFloatingNearPluginPayload {
diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs
index 1ec95d0f..0de590e7 100644
--- a/zellij-utils/src/plugin_api/plugin_command.rs
+++ b/zellij-utils/src/plugin_api/plugin_command.rs
@@ -1422,6 +1422,7 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
)) => match open_terminal_in_place_of_plugin_payload.file_to_open {
Some(file_to_open) => Ok(PluginCommand::OpenTerminalInPlaceOfPlugin(
file_to_open.try_into()?,
+ open_terminal_in_place_of_plugin_payload.close_plugin_after_replace,
)),
None => Err("Malformed open terminal in place of plugin payload"),
},
@@ -1467,6 +1468,8 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
.collect();
Ok(PluginCommand::OpenCommandPaneInPlaceOfPlugin(
command_to_run.try_into()?,
+ open_command_pane_in_place_of_plugin_payload
+ .close_plugin_after_replace,
context,
))
},
@@ -1528,6 +1531,7 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
.collect();
Ok(PluginCommand::OpenFileInPlaceOfPlugin(
file_to_open.try_into()?,
+ file_to_open_payload.close_plugin_after_replace,
context,
))
},
@@ -2467,16 +2471,23 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
)),
})
},
- PluginCommand::OpenTerminalInPlaceOfPlugin(cwd) => Ok(ProtobufPluginCommand {
- name: CommandName::OpenTerminalInPlaceOfPlugin as i32,
- payload: Some(Payload::OpenTerminalInPlaceOfPluginPayload(
- OpenTerminalInPlaceOfPluginPayload {
- file_to_open: Some(cwd.try_into()?),
- context: vec![], // will be added in the future
- },
- )),
- }),
- PluginCommand::OpenCommandPaneInPlaceOfPlugin(command_to_run, context) => {
+ PluginCommand::OpenTerminalInPlaceOfPlugin(cwd, close_plugin_after_replace) => {
+ Ok(ProtobufPluginCommand {
+ name: CommandName::OpenTerminalInPlaceOfPlugin as i32,
+ payload: Some(Payload::OpenTerminalInPlaceOfPluginPayload(
+ OpenTerminalInPlaceOfPluginPayload {
+ file_to_open: Some(cwd.try_into()?),
+ close_plugin_after_replace,
+ context: vec![], // will be added in the future
+ },
+ )),
+ })
+ },
+ PluginCommand::OpenCommandPaneInPlaceOfPlugin(
+ command_to_run,
+ close_plugin_after_replace,
+ context,
+ ) => {
let context: Vec<_> = context
.into_iter()
.map(|(name, value)| ContextItem { name, value })
@@ -2486,6 +2497,7 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
payload: Some(Payload::OpenCommandPaneInPlaceOfPluginPayload(
OpenCommandPaneInPlaceOfPluginPayload {
command_to_run: Some(command_to_run.try_into()?),
+ close_plugin_after_replace,
context,
},
)),
@@ -2521,21 +2533,24 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
},
)),
}),
- PluginCommand::OpenFileInPlaceOfPlugin(file_to_open, context) => {
- Ok(ProtobufPluginCommand {
- name: CommandName::OpenFileInPlaceOfPlugin as i32,
- payload: Some(Payload::OpenFileInPlaceOfPluginPayload(
- OpenFileInPlaceOfPluginPayload {
- file_to_open: Some(file_to_open.try_into()?),
- floating_pane_coordinates: None,
- context: context
- .into_iter()
- .map(|(name, value)| ContextItem { name, value })
- .collect(),
- },
- )),
- })
- },
+ PluginCommand::OpenFileInPlaceOfPlugin(
+ file_to_open,
+ close_plugin_after_replace,
+ context,
+ ) => Ok(ProtobufPluginCommand {
+ name: CommandName::OpenFileInPlaceOfPlugin as i32,
+ payload: Some(Payload::OpenFileInPlaceOfPluginPayload(
+ OpenFileInPlaceOfPluginPayload {
+ file_to_open: Some(file_to_open.try_into()?),
+ floating_pane_coordinates: None,
+ close_plugin_after_replace,
+ context: context
+ .into_iter()
+ .map(|(name, value)| ContextItem { name, value })
+ .collect(),
+ },
+ )),
+ }),
}
}
}