summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-08-25 12:24:43 +0200
committerGitHub <noreply@github.com>2023-08-25 12:24:43 +0200
commitb44ba85895b4db3a67a0f5c329c62fe120079ff0 (patch)
treeff34fb572a4ca5e0ff71fc0db9bacb9ef3c56093
parent877c467f9f757ca560d77ceef83456c9a50f4917 (diff)
feat(plugins): optionally move plugin to focused tab (#2725)
* feat(plugins): move_to_focused_tab attribute for LaunchOrFocusPlugin * style(fmt): rustfmt
-rw-r--r--default-plugins/status-bar/src/second_line.rs2
-rw-r--r--zellij-server/src/route.rs3
-rw-r--r--zellij-server/src/screen.rs49
-rw-r--r--zellij-server/src/tab/mod.rs43
-rw-r--r--zellij-server/src/unit/screen_tests.rs2
-rw-r--r--zellij-utils/assets/config/default.kdl1
-rw-r--r--zellij-utils/src/cli.rs2
-rw-r--r--zellij-utils/src/input/actions.rs9
-rw-r--r--zellij-utils/src/kdl/mod.rs9
-rw-r--r--zellij-utils/src/plugin_api/action.proto1
-rw-r--r--zellij-utils/src/plugin_api/action.rs10
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap2
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap2
16 files changed, 129 insertions, 12 deletions
diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs
index 4376616a3..e505e66aa 100644
--- a/default-plugins/status-bar/src/second_line.rs
+++ b/default-plugins/status-bar/src/second_line.rs
@@ -240,7 +240,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<Key>)> {
action_key(&km, &[A::SearchToggleOption(SOpt::WholeWord)])),
]} else if mi.mode == IM::Session { vec![
(s("Detach"), s("Detach"), action_key(&km, &[Action::Detach])),
- (s("Session Manager"), s("Manager"), action_key(&km, &[A::LaunchOrFocusPlugin(Default::default(), true), TO_NORMAL])), // not entirely accurate
+ (s("Session Manager"), s("Manager"), action_key(&km, &[A::LaunchOrFocusPlugin(Default::default(), true, true), TO_NORMAL])), // not entirely accurate
(s("Select pane"), s("Select"), to_normal_key),
]} else if mi.mode == IM::Tmux { vec![
(s("Move focus"), s("Move"), action_key_group(&km, &[
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 26b551866..b29dd934f 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -621,11 +621,12 @@ pub(crate) fn route_action(
.send_to_screen(ScreenInstruction::StartOrReloadPluginPane(run_plugin, None))
.with_context(err_context)?;
},
- Action::LaunchOrFocusPlugin(run_plugin, should_float) => {
+ Action::LaunchOrFocusPlugin(run_plugin, should_float, move_to_focused_tab) => {
senders
.send_to_screen(ScreenInstruction::LaunchOrFocusPlugin(
run_plugin,
should_float,
+ move_to_focused_tab,
client_id,
))
.with_context(err_context)?;
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index 2c018dcf3..8015075fc 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -281,9 +281,9 @@ pub enum ScreenInstruction {
StartPluginLoadingIndication(u32, LoadingIndication), // u32 - plugin_id
ProgressPluginLoadingOffset(u32), // u32 - plugin id
RequestStateUpdateForPlugins,
- LaunchOrFocusPlugin(RunPlugin, bool, ClientId), // bool is should_float
- SuppressPane(PaneId, ClientId), // bool is should_float
- FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float
+ LaunchOrFocusPlugin(RunPlugin, bool, bool, ClientId), // bools are: should_float, move_to_focused_tab
+ SuppressPane(PaneId, ClientId), // bool is should_float
+ FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float
RenamePane(PaneId, Vec<u8>),
RenameTab(usize, Vec<u8>),
RequestPluginPermissions(
@@ -1618,18 +1618,47 @@ impl Screen {
&mut self,
run_plugin: &RunPlugin,
should_float: bool,
+ move_to_focused_tab: bool,
client_id: ClientId,
) -> Result<bool> {
// true => found and focused, false => not
let err_context = || format!("failed to focus_plugin_pane");
let mut tab_index_and_plugin_pane_id = None;
+ let mut plugin_pane_to_move_to_active_tab = None;
+ let focused_tab_index = *self.active_tab_indices.get(&client_id).unwrap_or(&0);
let all_tabs = self.get_tabs_mut();
for (tab_index, tab) in all_tabs.iter_mut() {
if let Some(plugin_pane_id) = tab.find_plugin(&run_plugin) {
tab_index_and_plugin_pane_id = Some((*tab_index, plugin_pane_id));
+ if move_to_focused_tab && focused_tab_index != *tab_index {
+ plugin_pane_to_move_to_active_tab =
+ tab.extract_pane(plugin_pane_id, Some(client_id));
+ }
+
break;
}
}
+ if let Some(plugin_pane_to_move_to_active_tab) = plugin_pane_to_move_to_active_tab.take() {
+ let pane_id = plugin_pane_to_move_to_active_tab.pid();
+ let new_active_tab = self.get_active_tab_mut(client_id)?;
+
+ if should_float {
+ new_active_tab.show_floating_panes();
+ new_active_tab.add_floating_pane(
+ plugin_pane_to_move_to_active_tab,
+ pane_id,
+ Some(client_id),
+ )?;
+ } else {
+ new_active_tab.hide_floating_panes();
+ new_active_tab.add_tiled_pane(
+ plugin_pane_to_move_to_active_tab,
+ pane_id,
+ Some(client_id),
+ )?;
+ }
+ return Ok(true);
+ }
match tab_index_and_plugin_pane_id {
Some((tab_index, plugin_pane_id)) => {
self.go_to_tab(tab_index + 1, client_id)?;
@@ -2969,7 +2998,12 @@ pub(crate) fn screen_thread_main(
screen.log_and_report_session_state()?;
screen.render()?;
},
- ScreenInstruction::LaunchOrFocusPlugin(run_plugin, should_float, client_id) => {
+ ScreenInstruction::LaunchOrFocusPlugin(
+ run_plugin,
+ should_float,
+ move_to_focused_tab,
+ client_id,
+ ) => {
let client_id = if screen.active_tab_indices.contains_key(&client_id) {
Some(client_id)
} else {
@@ -2983,7 +3017,12 @@ pub(crate) fn screen_thread_main(
});
match client_id_and_focused_tab {
Some((tab_index, client_id)) => {
- if screen.focus_plugin_pane(&run_plugin, should_float, client_id)? {
+ if screen.focus_plugin_pane(
+ &run_plugin,
+ should_float,
+ move_to_focused_tab,
+ client_id,
+ )? {
screen.render()?;
screen.log_and_report_session_state()?;
} else {
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index 2da5306a9..799cebcb2 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -2245,6 +2245,49 @@ impl Tab {
closed_pane
}
}
+ pub fn extract_pane(
+ &mut self,
+ id: PaneId,
+ client_id: Option<ClientId>,
+ ) -> Option<Box<dyn Pane>> {
+ if self.floating_panes.panes_contain(&id) {
+ let closed_pane = self.floating_panes.remove_pane(id);
+ self.floating_panes.move_clients_out_of_pane(id);
+ if !self.floating_panes.has_panes() {
+ self.hide_floating_panes();
+ }
+ self.set_force_render();
+ self.floating_panes.set_force_render();
+ if self.auto_layout
+ && !self.swap_layouts.is_floating_damaged()
+ && self.floating_panes.visible_panes_count() > 0
+ {
+ self.swap_layouts.set_is_floating_damaged();
+ // only relayout if the user is already "in" a layout, otherwise this might be
+ // confusing
+ let _ = self.next_swap_layout(client_id, false);
+ }
+ closed_pane
+ } else if self.tiled_panes.panes_contain(&id) {
+ if self.tiled_panes.fullscreen_is_active() {
+ self.tiled_panes.unset_fullscreen();
+ }
+ let closed_pane = self.tiled_panes.remove_pane(id);
+ self.set_force_render();
+ self.tiled_panes.set_force_render();
+ if self.auto_layout && !self.swap_layouts.is_tiled_damaged() {
+ self.swap_layouts.set_is_tiled_damaged();
+ // only relayout if the user is already "in" a layout, otherwise this might be
+ // confusing
+ let _ = self.next_swap_layout(client_id, false);
+ }
+ closed_pane
+ } else if self.suppressed_panes.contains_key(&id) {
+ self.suppressed_panes.remove(&id)
+ } else {
+ None
+ }
+ }
pub fn hold_pane(
&mut self,
id: PaneId,
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index 8d1debd35..2f123ddcc 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -2564,6 +2564,7 @@ pub fn send_cli_launch_or_focus_plugin_action() {
);
let cli_action = CliAction::LaunchOrFocusPlugin {
floating: true,
+ move_to_focused_tab: true,
url: url::Url::parse("file:/path/to/fake/plugin").unwrap(),
configuration: Default::default(),
};
@@ -2621,6 +2622,7 @@ pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded() {
);
let cli_action = CliAction::LaunchOrFocusPlugin {
floating: true,
+ move_to_focused_tab: true,
url: url::Url::parse("file:/path/to/fake/plugin").unwrap(),
configuration: Default::default(),
};
diff --git a/zellij-utils/assets/config/default.kdl b/zellij-utils/assets/config/default.kdl
index aea41f274..bf54c8620 100644
--- a/zellij-utils/assets/config/default.kdl
+++ b/zellij-utils/assets/config/default.kdl
@@ -116,6 +116,7 @@ keybinds {
bind "w" {
LaunchOrFocusPlugin "zellij:session-manager" {
floating true
+ move_to_focused_tab true
};
SwitchToMode "Normal"
}
diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs
index fd2bdcda7..957a13c1a 100644
--- a/zellij-utils/src/cli.rs
+++ b/zellij-utils/src/cli.rs
@@ -384,6 +384,8 @@ pub enum CliAction {
LaunchOrFocusPlugin {
#[clap(short, long, value_parser)]
floating: bool,
+ #[clap(short, long, value_parser)]
+ move_to_focused_tab: bool,
url: Url,
#[clap(short, long, value_parser)]
configuration: Option<PluginUserConfiguration>,
diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs
index faeb8a4e7..054273a0a 100644
--- a/zellij-utils/src/input/actions.rs
+++ b/zellij-utils/src/input/actions.rs
@@ -204,7 +204,7 @@ pub enum Action {
LeftClick(Position),
RightClick(Position),
MiddleClick(Position),
- LaunchOrFocusPlugin(RunPlugin, bool), // bool => should float
+ LaunchOrFocusPlugin(RunPlugin, bool, bool), // bools => should float, move_to_focused_tab
LeftMouseRelease(Position),
RightMouseRelease(Position),
MiddleMouseRelease(Position),
@@ -501,6 +501,7 @@ impl Action {
CliAction::LaunchOrFocusPlugin {
url,
floating,
+ move_to_focused_tab,
configuration,
} => {
let current_dir = get_current_dir();
@@ -511,7 +512,11 @@ impl Action {
_allow_exec_host_cmd: false,
configuration: configuration.unwrap_or_default(),
};
- Ok(vec![Action::LaunchOrFocusPlugin(run_plugin, floating)])
+ Ok(vec![Action::LaunchOrFocusPlugin(
+ run_plugin,
+ floating,
+ move_to_focused_tab,
+ )])
},
}
}
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index af49dbb30..1d09bdac5 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -906,6 +906,9 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
let should_float = command_metadata
.and_then(|c_m| kdl_child_bool_value_for_entry(c_m, "floating"))
.unwrap_or(false);
+ let move_to_focused_tab = command_metadata
+ .and_then(|c_m| kdl_child_bool_value_for_entry(c_m, "move_to_focused_tab"))
+ .unwrap_or(false);
let current_dir = std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."));
let location = RunPluginLocation::parse(&plugin_path, Some(current_dir))?;
let configuration = KdlLayoutParser::parse_plugin_user_configuration(&kdl_action)?;
@@ -914,7 +917,11 @@ impl TryFrom<(&KdlNode, &Options)> for Action {
_allow_exec_host_cmd: false,
configuration,
};
- Ok(Action::LaunchOrFocusPlugin(run_plugin, should_float))
+ Ok(Action::LaunchOrFocusPlugin(
+ run_plugin,
+ should_float,
+ move_to_focused_tab,
+ ))
},
"PreviousSwapLayout" => Ok(Action::PreviousSwapLayout),
"NextSwapLayout" => Ok(Action::NextSwapLayout),
diff --git a/zellij-utils/src/plugin_api/action.proto b/zellij-utils/src/plugin_api/action.proto
index 05fa5c6ed..429c8432e 100644
--- a/zellij-utils/src/plugin_api/action.proto
+++ b/zellij-utils/src/plugin_api/action.proto
@@ -84,6 +84,7 @@ message LaunchOrFocusPluginPayload {
string plugin_url = 1;
bool should_float = 2;
optional PluginConfiguration plugin_configuration = 3;
+ bool move_to_focused_tab = 4;
}
message GoToTabNamePayload {
diff --git a/zellij-utils/src/plugin_api/action.rs b/zellij-utils/src/plugin_api/action.rs
index 1a964fa9b..b3bff6f84 100644
--- a/zellij-utils/src/plugin_api/action.rs
+++ b/zellij-utils/src/plugin_api/action.rs
@@ -399,7 +399,12 @@ impl TryFrom<ProtobufAction> for Action {
configuration,
};
let should_float = payload.should_float;
- Ok(Action::LaunchOrFocusPlugin(run_plugin, should_float))
+ let move_to_focused_tab = payload.move_to_focused_tab;
+ Ok(Action::LaunchOrFocusPlugin(
+ run_plugin,
+ should_float,
+ move_to_focused_tab,
+ ))
},
_ => Err("Wrong payload for Action::LaunchOrFocusPlugin"),
}
@@ -954,7 +959,7 @@ impl TryFrom<Action> for ProtobufAction {
optional_payload: Some(OptionalPayload::MiddleClickPayload(position)),
})
},
- Action::LaunchOrFocusPlugin(run_plugin, should_float) => {
+ Action::LaunchOrFocusPlugin(run_plugin, should_float, move_to_focused_tab) => {
let url: Url = Url::from(&run_plugin.location);
Ok(ProtobufAction {
name: ProtobufActionName::LaunchOrFocusPlugin as i32,
@@ -962,6 +967,7 @@ impl TryFrom<Action> for ProtobufAction {
LaunchOrFocusPluginPayload {
plugin_url: url.into(),
should_float,
+ move_to_focused_tab,
plugin_configuration: Some(run_plugin.configuration.try_into()?),
},
)),
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
index 367866e09..06c90a689 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap
@@ -2503,10 +2503,12 @@ Config {
configuration: PluginUserConfiguration(
{
"floating": "true",
+ "move_to_focused_tab": "true",
},
),
},
true,
+ true,
),
SwitchToMode(
Normal,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
index 5af23a0a5..b2c4305cb 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap
@@ -2503,10 +2503,12 @@ Config {
configuration: PluginUserConfiguration(
{
"floating": "true",
+ "move_to_focused_tab": "true",
},
),
},
true,
+ true,
),
SwitchToMode(
Normal,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap
index 55173c3ab..42cd12c25 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap
@@ -2503,10 +2503,12 @@ Config {
configuration: PluginUserConfiguration(
{
"floating": "true",
+ "move_to_focused_tab": "true",
},
),
},
true,
+ true,
),
SwitchToMode(
Normal,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
index a7613eee1..9f5749f55 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap
@@ -2503,10 +2503,12 @@ Config {
configuration: PluginUserConfiguration(
{
"floating": "true",
+ "move_to_focused_tab": "true",
},
),
},
true,
+ true,
),
SwitchToMode(
Normal,
diff --git a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
index dae918163..8da67cf04 100644
--- a/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
+++ b/zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap
@@ -2503,10 +2503,12 @@ Config {
configuration: PluginUserConfiguration(
{
"floating": "true",
+ "move_to_focused_tab": "true",
},
),
},
true,
+ true,
),
SwitchToMode(
Normal,