summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-02-15 16:16:53 +0100
committerAram Drevekenin <aram@poor.dev>2023-02-15 16:16:53 +0100
commitc560f31b4552992ed29b3857cc65297f70047ed4 (patch)
treee9fb0847271a5b3c1a341b5cb5f6da53a92838e9
parent5dd319c8528ee5f25580baee94596e639513f3b9 (diff)
fix(ux): move pane forward/backwards also with floating panes
-rw-r--r--default-plugins/status-bar/src/second_line.rs1
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap2
-rw-r--r--src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_floating_panes.snap2
-rw-r--r--zellij-server/src/panes/floating_panes/floating_pane_grid.rs52
-rw-r--r--zellij-server/src/panes/floating_panes/mod.rs39
-rw-r--r--zellij-server/src/panes/tiled_panes/mod.rs8
-rw-r--r--zellij-server/src/panes/tiled_panes/stacked_panes.rs2
-rw-r--r--zellij-server/src/route.rs6
-rw-r--r--zellij-server/src/screen.rs12
-rw-r--r--zellij-server/src/tab/mod.rs21
-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.rs6
-rw-r--r--zellij-utils/src/errors.rs1
-rw-r--r--zellij-utils/src/input/actions.rs4
-rw-r--r--zellij-utils/src/kdl/mod.rs6
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__default_config_with_no_cli_arguments.snap7
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_env_vars_override_config_env_vars.snap7
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_plugins_override_config_plugins.snap7
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_themes_override_config_themes.snap7
-rw-r--r--zellij-utils/src/snapshots/zellij_utils__setup__setup_test__layout_ui_config_overrides_config_ui_config.snap7
21 files changed, 184 insertions, 16 deletions
diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs
index aa251cec1..b7c8a9cec 100644
--- a/default-plugins/status-bar/src/second_line.rs
+++ b/default-plugins/status-bar/src/second_line.rs
@@ -210,6 +210,7 @@ fn get_keys_and_hints(mi: &ModeInfo) -> Vec<(String, String, Vec<Key>)> {
&[Action::MovePane(Some(Dir::Left))], &[Action::MovePane(Some(Dir::Down))],
&[Action::MovePane(Some(Dir::Up))], &[Action::MovePane(Some(Dir::Right))]])),
(s("Next pane"), s("Next"), action_key(&km, &[Action::MovePane(None)])),
+ (s("Previous pane"), s("Previous"), action_key(&km, &[Action::MovePaneBackwards])),
]} else if mi.mode == IM::Scroll { vec![
(s("Scroll"), s("Scroll"),
action_key_group(&km, &[&[Action::ScrollDown], &[Action::ScrollUp]])),
diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap
index 00c75da3d..d797b10ba 100644
--- a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap
+++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__send_command_through_the_cli.snap
@@ -25,5 +25,5 @@ expression: last_snapshot
│ ││ │
│ ││ │
└──────────────────────────────────────────────────────────┘└ [ EXIT CODE: 0 ] <ENTER> to re-run, <Ctrl-c> to exit ────┘
- Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  BASE 
+ Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
Tip: Alt + <n> => new pane. Alt + <←↓↑→> or Alt + <hjkl> => navigate. Alt + <+|-> => resize pane.
diff --git a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_floating_panes.snap b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_floating_panes.snap
index 9eb969e7e..01f65fb12 100644
--- a/src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_floating_panes.snap
+++ b/src/tests/e2e/snapshots/zellij__tests__e2e__cases__toggle_floating_panes.snap
@@ -25,5 +25,5 @@ expression: last_snapshot
│ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
- Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT  BASE 
+ Ctrl + <g> LOCK  <p> PANE  <t> TAB  <n> RESIZE  <h> MOVE  <s> SEARCH  <o> SESSION  <q> QUIT 
(FLOATING PANES VISIBLE): Press Ctrl+p, <w> to hide.
diff --git a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
index 55ea46dd5..9f034956d 100644
--- a/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
+++ b/zellij-server/src/panes/floating_panes/floating_pane_grid.rs
@@ -703,6 +703,58 @@ impl<'a> FloatingPaneGrid<'a> {
.copied();
next_index
}
+ pub fn next_selectable_pane_id(&self, current_pane_id: &PaneId) -> Option<PaneId> {
+ let panes = self.panes.borrow();
+ let mut panes: Vec<(PaneId, &&mut Box<dyn Pane>)> = panes
+ .iter()
+ .filter(|(_, p)| p.selectable())
+ .map(|(p_id, p)| (*p_id, p))
+ .collect();
+ panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| {
+ if a_pane.y() == b_pane.y() {
+ a_pane.x().cmp(&b_pane.x())
+ } else {
+ a_pane.y().cmp(&b_pane.y())
+ }
+ });
+ let active_pane_position = panes
+ .iter()
+ .position(|(id, _)| id == current_pane_id)
+ .unwrap();
+
+ let next_active_pane_id = panes
+ .get(active_pane_position + 1)
+ .or_else(|| panes.get(0))
+ .map(|p| p.0)
+ .unwrap();
+ Some(next_active_pane_id)
+ }
+ pub fn previous_selectable_pane_id(&self, current_pane_id: &PaneId) -> Option<PaneId> {
+ let panes = self.panes.borrow();
+ let mut panes: Vec<(PaneId, &&mut Box<dyn Pane>)> = panes
+ .iter()
+ .filter(|(_, p)| p.selectable())
+ .map(|(p_id, p)| (*p_id, p))
+ .collect();
+ panes.sort_by(|(_a_id, a_pane), (_b_id, b_pane)| {
+ if a_pane.y() == b_pane.y() {
+ a_pane.x().cmp(&b_pane.x())
+ } else {
+ a_pane.y().cmp(&b_pane.y())
+ }
+ });
+ let active_pane_position = panes
+ .iter()
+ .position(|(id, _)| id == current_pane_id)?;
+
+ let last_pane = panes.last()?;
+ let previous_active_pane_id = if active_pane_position == 0 {
+ last_pane.0
+ } else {
+ panes.get(active_pane_position - 1)?.0
+ };
+ Some(previous_active_pane_id)
+ }
pub fn find_room_for_new_pane(&self) -> Option<PaneGeom> {
let panes = self.panes.borrow();
let pane_geoms: Vec<PaneGeom> = panes.values().map(|p| p.position_and_size()).collect();
diff --git a/zellij-server/src/panes/floating_panes/mod.rs b/zellij-server/src/panes/floating_panes/mod.rs
index 77abda645..34a5fc320 100644
--- a/zellij-server/src/panes/floating_panes/mod.rs
+++ b/zellij-server/src/panes/floating_panes/mod.rs
@@ -592,6 +592,45 @@ impl FloatingPanes {
self.set_force_render();
}
}
+ pub fn move_active_pane(&mut self, search_backwards: bool, os_api: &mut Box<dyn ServerOsApi>, client_id: ClientId) {
+ let active_pane_id = self.get_active_pane_id(client_id).unwrap();
+
+ let new_position_id = {
+ let pane_grid = FloatingPaneGrid::new(
+ &mut self.panes,
+ &mut self.desired_pane_positions,
+ *self.display_area.borrow(),
+ *self.viewport.borrow(),
+ );
+ if search_backwards {
+ pane_grid.previous_selectable_pane_id(&active_pane_id)
+ } else {
+ pane_grid.next_selectable_pane_id(&active_pane_id)
+ }
+ };
+ if let Some(new_position_id) = new_position_id {
+ let current_position = self.panes.get(&active_pane_id).unwrap();
+ let prev_geom = current_position.position_and_size();
+ let prev_geom_override = current_position.geom_override();
+
+ let new_position = self.panes.get_mut(&new_position_id).unwrap();
+ let next_geom = new_position.position_and_size();
+ let next_geom_override = new_position.geom_override();
+ new_position.set_geom(prev_geom);
+ if let Some(geom) = prev_geom_override {
+ new_position.set_geom_override(geom);
+ }
+ new_position.set_should_render(true);
+
+ let current_position = self.panes.get_mut(&active_pane_id).unwrap();
+ current_position.set_geom(next_geom);
+ if let Some(geom) = next_geom_override {
+ current_position.set_geom_override(geom);
+ }
+ current_position.set_should_render(true);
+ self.set_pane_frames(os_api);
+ }
+ }
pub fn move_clients_out_of_pane(&mut self, pane_id: PaneId) {
let active_panes: Vec<(ClientId, PaneId)> = self
.active_panes
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs
index dca3afd84..411e0178e 100644
--- a/zellij-server/src/panes/tiled_panes/mod.rs
+++ b/zellij-server/src/panes/tiled_panes/mod.rs
@@ -1017,7 +1017,7 @@ impl TiledPanes {
self.set_pane_frames(self.draw_pane_frames);
}
}
- pub fn move_active_pane(&mut self, client_id: ClientId) {
+ pub fn move_active_pane(&mut self, search_backwards: bool, client_id: ClientId) {
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
let new_position_id = {
@@ -1027,7 +1027,11 @@ impl TiledPanes {
*self.display_area.borrow(),
*self.viewport.borrow(),
);
- pane_grid.next_selectable_pane_id(&active_pane_id)
+ if search_backwards {
+ pane_grid.previous_selectable_pane_id(&active_pane_id)
+ } else {
+ pane_grid.next_selectable_pane_id(&active_pane_id)
+ }
};
if self.panes.get(&new_position_id).map(|p| p.current_geom().is_stacked).unwrap_or(false) {
let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide).focus_pane(&new_position_id);
diff --git a/zellij-server/src/panes/tiled_panes/stacked_panes.rs b/zellij-server/src/panes/tiled_panes/stacked_panes.rs
index 40f5bb1b1..3a3531de8 100644
--- a/zellij-server/src/panes/tiled_panes/stacked_panes.rs
+++ b/zellij-server/src/panes/tiled_panes/stacked_panes.rs
@@ -93,8 +93,6 @@ impl <'a>StackedPanes <'a>{
panes.get_mut(&flexible_pane_id).with_context(err_context)?.set_geom(flexible_pane);
for (i, (pid, _position)) in all_stacked_pane_positions.iter().enumerate() {
- // if (i < position_of_pane_to_focus && i < position_of_flexible_pane) || (i > position_of_pane_to_focus && i > position_of_flexible_pane) {
- // continue;
if i > position_of_pane_to_focus && i <= position_of_flexible_pane {
// the flexible pane has moved up the stack, we need to push this pane down
let pane = panes.get_mut(pid).with_context(err_context)?;
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 46f20c08b..028a81489 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -165,6 +165,12 @@ pub(crate) fn route_action(
.send_to_screen(screen_instr)
.with_context(err_context)?;
},
+ Action::MovePaneBackwards => {
+ session
+ .senders
+ .send_to_screen(ScreenInstruction::MovePaneBackwards(client_id))
+ .with_context(err_context)?;
+ },
Action::DumpScreen(val, full) => {
session
.senders
diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs
index ae18707cd..6d101ac6e 100644
--- a/zellij-server/src/screen.rs
+++ b/zellij-server/src/screen.rs
@@ -149,6 +149,7 @@ pub enum ScreenInstruction {
MoveFocusRight(ClientId),
MoveFocusRightOrNextTab(ClientId),
MovePane(ClientId),
+ MovePaneBackwards(ClientId),
MovePaneUp(ClientId),
MovePaneDown(ClientId),
MovePaneRight(ClientId),
@@ -287,6 +288,7 @@ impl From<&ScreenInstruction> for ScreenContext {
ScreenContext::MoveFocusRightOrNextTab
},
ScreenInstruction::MovePane(..) => ScreenContext::MovePane,
+ ScreenInstruction::MovePaneBackwards(..) => ScreenContext::MovePaneBackwards,
ScreenInstruction::MovePaneDown(..) => ScreenContext::MovePaneDown,
ScreenInstruction::MovePaneUp(..) => ScreenContext::MovePaneUp,
ScreenInstruction::MovePaneRight(..) => ScreenContext::MovePaneRight,
@@ -1660,6 +1662,16 @@ pub(crate) fn screen_thread_main(
screen.render()?;
screen.unblock_input()?;
},
+ ScreenInstruction::MovePaneBackwards(client_id) => {
+ active_tab_and_connected_client_id!(
+ screen,
+ client_id,
+ |tab: &mut Tab, client_id: ClientId| tab.move_active_pane_backwards(client_id)
+ );
+ screen.update_tabs()?; // update tabs so that the ui indication will be send to the plugins
+ screen.render()?;
+ screen.unblock_input()?;
+ },
ScreenInstruction::MovePaneDown(client_id) => {
active_tab_and_connected_client_id!(
screen,
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs
index a6c439e2a..99f471da5 100644
--- a/zellij-server/src/tab/mod.rs
+++ b/zellij-server/src/tab/mod.rs
@@ -2061,7 +2061,26 @@ impl Tab {
if self.tiled_panes.fullscreen_is_active() {
return;
}
- self.tiled_panes.move_active_pane(client_id);
+ let search_backwards = false;
+ if self.floating_panes.panes_are_visible() {
+ self.floating_panes.move_active_pane(search_backwards, &mut self.os_api, client_id);
+ } else {
+ self.tiled_panes.move_active_pane(search_backwards, client_id);
+ }
+ }
+ pub fn move_active_pane_backwards(&mut self, client_id: ClientId) {
+ if !self.has_selectable_panes() {
+ return;
+ }
+ if self.tiled_panes.fullscreen_is_active() {
+ return;
+ }
+ let search_backwards = true;
+ if self.floating_panes.panes_are_visible() {
+ self.floating_panes.move_active_pane(search_backwards, &mut self.os_api, client_id);
+ } else {
+ self.tiled_panes.move_active_pane(search_backwards, client_id);
+ }
}
pub fn move_active_pane_down(&mut self, client_id: ClientId) {
if self.floating_panes.panes_are_visible() {
diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs
index 00acac666..9a3d685ad 100644
--- a/zellij-server/src/unit/screen_tests.rs
+++ b/zellij-server/src/unit/screen_tests.rs
@@ -1222,7 +1222,7 @@ pub fn send_cli_move_pane_action() {
server_receiver
);
let cli_action = CliAction::MovePane {
- direction: Direction::Right,
+ direction: Some(Direction::Right),
};
send_cli_action_to_server(&session_metadata, cli_action, &mut mock_screen, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
diff --git a/zellij-utils/assets/config/default.kdl b/zellij-utils/assets/config/default.kdl
index df39c0de9..6131efc27 100644
--- a/zellij-utils/assets/config/default.kdl
+++ b/zellij-utils/assets/config/default.kdl
@@ -40,6 +40,7 @@ keybinds {
move {
bind "Ctrl h" { SwitchToMode "Normal"; }
bind "n" "Tab" { MovePane; }
+ bind "p" { MovePaneBackwards; }
bind "h" "Left" { MovePane "Left"; }
bind "j" "Down" { MovePane "Down"; }
bind "k" "Up" { MovePane "Up"; }
diff --git a/zellij-utils/src/cli.rs b/zellij-utils/src/cli.rs
index 660dc6d3c..4facc6443 100644
--- a/zellij-utils/src/cli.rs
+++ b/zellij-utils/src/cli.rs
@@ -197,9 +197,11 @@ pub enum CliAction {
/// Move focus to the pane or tab (if on screen edge) in the specified direction
/// [right|left|up|down]
MoveFocusOrTab { direction: Direction },
- /// Change the location of the focused pane in the specified direction
+ /// Change the location of the focused pane in the specified direction or rotate forwrads
/// [right|left|up|down]
- MovePane { direction: Direction },
+ MovePane { direction: Option<Direction> },
+ /// Rotate the location of the previous pane backwards
+ MovePaneBackwards,
/// Dump the focused pane to a file
DumpScreen {
path: PathBuf,
diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs
index 87f4ac3ec..0ea1190f6 100644
--- a/zellij-utils/src/errors.rs
+++ b/zellij-utils/src/errors.rs
@@ -285,6 +285,7 @@ pub enum ScreenContext {
MoveFocusRight,
MoveFocusRightOrNextTab,
MovePane,
+ MovePaneBackwards,
MovePaneDown,
MovePaneUp,
MovePaneRight,
diff --git a/zellij-utils/src/input/actions.rs b/zellij-utils/src/input/actions.rs
index 2aca3107c..8183f3263 100644
--- a/zellij-utils/src/input/actions.rs
+++ b/zellij-utils/src/input/actions.rs
@@ -115,6 +115,7 @@ pub enum Action {
/// If there is no pane in the direction, move to previous/next Tab.
MoveFocusOrTab(Direction),
MovePane(Option<Direction>),
+ MovePaneBackwards,
/// Dumps the screen to a file
DumpScreen(String, bool),
/// Scroll up in focus pane.
@@ -219,7 +220,8 @@ impl Action {
CliAction::FocusPreviousPane => Ok(vec![Action::FocusPreviousPane]),
CliAction::MoveFocus { direction } => Ok(vec![Action::MoveFocus(direction)]),
CliAction::MoveFocusOrTab { direction } => Ok(vec![Action::MoveFocusOrTab(direction)]),
- CliAction::MovePane { direction } => Ok(vec![Action::MovePane(Some(direction))]),
+ CliAction::MovePane { direction } => Ok(vec![Action::MovePane(direction)]),
+ CliAction::MovePaneBackwards => Ok(vec![Action::MovePaneBackwards]),
CliAction::DumpScreen { path, full } => Ok(vec![Action::DumpScreen(
path.as_os_str().to_string_lossy().into(),
full,
diff --git a/zellij-utils/src/kdl/mod.rs b/zellij-utils/src/kdl/mod.rs
index 8801f4612..cfe098cd6 100644
--- a/zellij-utils/src/kdl/mod.rs
+++ b/zellij-utils/src/kdl/mod.rs
@@ -453,6 +453,7 @@ impl Action {
Ok(Action::MovePane(Some(direction)))
}
},
+ "MovePaneBackwards" => Ok(Action::MovePaneBackwards),
"DumpScreen" => Ok(Action::DumpScreen(string, false)),
"NewPane" => {
if string.is_empty() {
@@ -727,6 +728,11 @@ impl TryFrom<&KdlNode> for Action {
action_arguments,
kdl_action
),
+ "MovePaneBackwards" => parse_kdl_action_char_or_string_arguments!(
+ action_name,
+ action_arguments,
+ kdl_action
+ ),
"DumpScreen" => parse_kdl_action_char_or_string_arguments!(
action_name,
action_arguments,
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 056a687ca..2d5aea7b4 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
@@ -1,6 +1,6 @@
---
source: zellij-utils/src/setup.rs
-assertion_line: 600
+assertion_line: 621
expression: "format!(\"{:#?}\", config)"
---
Config {
@@ -2737,6 +2737,11 @@ Config {
None,
),
],
+ Char(
+ 'p',
+ ): [
+ MovePaneBackwards,
+ ],
Alt(
Char(
'+',
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 5e72b510f..8e94086a5 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
@@ -1,6 +1,6 @@
---
source: zellij-utils/src/setup.rs
-assertion_line: 658
+assertion_line: 679
expression: "format!(\"{:#?}\", config)"
---
Config {
@@ -2737,6 +2737,11 @@ Config {
None,
),
],
+ Char(
+ 'p',
+ ): [
+ MovePaneBackwards,
+ ],
Alt(
Char(