diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-04-03 18:04:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-03 18:04:06 +0200 |
commit | 3a428effed2327b8f82bd8cd328f385032e5bc06 (patch) | |
tree | b100fa9b9bb49583e8efee7567973ded1e8b87ae /zellij-server | |
parent | 63d6711a8dad531b3188b32fa19642c76cb7eec6 (diff) |
feat(panes): allow defining an expanded stacked pane (#2343)
* feat(panes): allow defining an expanded stacked pane
* style(fmt): rustfmt
Diffstat (limited to 'zellij-server')
9 files changed, 142 insertions, 15 deletions
diff --git a/zellij-server/src/panes/tiled_panes/mod.rs b/zellij-server/src/panes/tiled_panes/mod.rs index 89a329bb4..4cc7279d7 100644 --- a/zellij-server/src/panes/tiled_panes/mod.rs +++ b/zellij-server/src/panes/tiled_panes/mod.rs @@ -423,7 +423,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&pane_id); + .expand_pane(&pane_id); } self.active_panes .insert(client_id, pane_id, &mut self.panes); @@ -446,7 +446,7 @@ impl TiledPanes { { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&pane_id); + .expand_pane(&pane_id); } self.active_panes .insert(client_id, *pane_id, &mut self.panes); @@ -465,7 +465,7 @@ impl TiledPanes { &mut self.panes, &self.panes_to_hide, ) - .focus_pane(&pane_id); + .expand_pane(&pane_id); } self.active_panes .insert(client_id, pane_id, &mut self.panes); @@ -477,6 +477,33 @@ impl TiledPanes { self.set_force_render(); self.reapply_pane_frames(); } + pub fn expand_pane_in_stack(&mut self, pane_id: PaneId) -> Vec<PaneId> { + // returns all pane ids in stack + match StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) + .expand_pane(&pane_id) + { + Ok(all_panes_in_stack) => { + let connected_clients: Vec<ClientId> = + self.connected_clients.borrow().iter().copied().collect(); + for client_id in connected_clients { + if let Some(focused_pane_id_for_client) = self.active_panes.get(&client_id) { + if all_panes_in_stack.contains(focused_pane_id_for_client) { + self.active_panes + .insert(client_id, pane_id, &mut self.panes); + self.set_pane_active_at(pane_id); + } + } + } + self.set_force_render(); + self.reapply_pane_frames(); + all_panes_in_stack + }, + Err(e) => { + log::error!("Failed to expand pane in stack: {:?}", e); + vec![] + }, + } + } pub fn focus_pane(&mut self, pane_id: PaneId, client_id: ClientId) { if self .panes @@ -485,7 +512,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&pane_id); + .expand_pane(&pane_id); self.reapply_pane_frames(); } @@ -826,7 +853,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&next_active_pane_id); + .expand_pane(&next_active_pane_id); self.reapply_pane_frames(); } @@ -858,7 +885,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&next_active_pane_id); + .expand_pane(&next_active_pane_id); self.reapply_pane_frames(); } for client_id in connected_clients { @@ -1166,7 +1193,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&new_position_id); + .expand_pane(&new_position_id); self.reapply_pane_frames(); } @@ -1430,7 +1457,7 @@ impl TiledPanes { .unwrap_or(false) { let _ = StackedPanes::new_from_btreemap(&mut self.panes, &self.panes_to_hide) - .focus_pane(&next_active_pane_id); + .expand_pane(&next_active_pane_id); self.reapply_pane_frames(); } for (client_id, active_pane_id) in active_panes { diff --git a/zellij-server/src/panes/tiled_panes/stacked_panes.rs b/zellij-server/src/panes/tiled_panes/stacked_panes.rs index cc0b0f151..bc5057a5b 100644 --- a/zellij-server/src/panes/tiled_panes/stacked_panes.rs +++ b/zellij-server/src/panes/tiled_panes/stacked_panes.rs @@ -102,9 +102,8 @@ impl<'a> StackedPanes<'a> { } Ok(()) } - pub fn focus_pane(&mut self, pane_id: &PaneId) -> Result<()> { - // this function doesn't actually change the focus (since it is controlled elsewhere) - // but rather makes sure pane_id is flexible if it were a one-liner before + pub fn expand_pane(&mut self, pane_id: &PaneId) -> Result<Vec<PaneId>> { + // returns all the pane ids in the stack let err_context = || format!("Failed to focus stacked pane"); let all_stacked_pane_positions = self.positions_in_stack(pane_id).with_context(err_context)?; @@ -158,7 +157,10 @@ impl<'a> StackedPanes<'a> { } } } - Ok(()) + Ok(all_stacked_pane_positions + .iter() + .map(|(pane_id, _pane_position)| *pane_id) + .collect()) } pub fn flexible_pane_id_in_stack(&self, pane_id_in_stack: &PaneId) -> Option<PaneId> { let all_stacked_pane_positions = self.positions_in_stack(pane_id_in_stack).ok()?; diff --git a/zellij-server/src/tab/layout_applier.rs b/zellij-server/src/tab/layout_applier.rs index 04c22fe9a..ef475c07e 100644 --- a/zellij-server/src/tab/layout_applier.rs +++ b/zellij-server/src/tab/layout_applier.rs @@ -138,6 +138,8 @@ impl<'a> LayoutApplier<'a> { Some(position_and_size), ); pane_focuser.set_pane_id_in_focused_location(layout.focus, &pane); + pane_focuser + .set_expanded_stacked_pane(layout.is_expanded_in_stack, &pane); resize_pty!(pane, self.os_api, self.senders, self.character_cell_size)?; self.tiled_panes .add_pane_with_existing_geom(pane.pid(), pane); @@ -161,6 +163,7 @@ impl<'a> LayoutApplier<'a> { Some(position_and_size), ); pane_focuser.set_pane_id_in_focused_location(layout.focus, &pane); + pane_focuser.set_expanded_stacked_pane(layout.is_expanded_in_stack, &pane); resize_pty!(pane, self.os_api, self.senders, self.character_cell_size)?; self.tiled_panes .add_pane_with_existing_geom(pane.pid(), pane); @@ -744,6 +747,7 @@ impl ExistingTabState { struct PaneFocuser { refocus_pane: bool, pane_id_in_focused_location: Option<PaneId>, + expanded_stacked_pane_ids: Vec<PaneId>, } impl PaneFocuser { @@ -762,12 +766,24 @@ impl PaneFocuser { self.pane_id_in_focused_location = Some(pane.pid()); } } + pub fn set_expanded_stacked_pane(&mut self, is_expanded_in_stack: bool, pane: &Box<dyn Pane>) { + if is_expanded_in_stack && pane.selectable() { + self.expanded_stacked_pane_ids.push(pane.pid()); + } + } pub fn focus_tiled_pane(&self, tiled_panes: &mut TiledPanes) { + let mut panes_in_stack = vec![]; + for pane_id in &self.expanded_stacked_pane_ids { + panes_in_stack.append(&mut tiled_panes.expand_pane_in_stack(*pane_id)); + } match self.pane_id_in_focused_location { Some(pane_id_in_focused_location) => { if self.refocus_pane { tiled_panes.reapply_pane_focus(); - tiled_panes.switch_active_pane_with(pane_id_in_focused_location); + if !panes_in_stack.contains(&pane_id_in_focused_location) { + // we do not change stacked panes locations because this has already been done above + tiled_panes.switch_active_pane_with(pane_id_in_focused_location); + } } else { tiled_panes.reapply_pane_focus(); } @@ -776,6 +792,9 @@ impl PaneFocuser { tiled_panes.reapply_pane_focus(); }, } + for pane_id in &self.expanded_stacked_pane_ids { + tiled_panes.expand_pane_in_stack(*pane_id); + } } pub fn focus_floating_pane( &self, diff --git a/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_define_expanded_pane_in_stack.snap b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_define_expanded_pane_in_stack.snap new file mode 100644 index 000000000..f12ea2901 --- /dev/null +++ b/zellij-server/src/tab/unit/snapshots/zellij_server__tab__tab_integration_tests__can_define_expanded_pane_in_stack.snap @@ -0,0 +1,26 @@ +--- +source: zellij-server/src/tab/./unit/tab_integration_tests.rs +assertion_line: 6826 +expression: snapshot +--- +00 (C): ┌ Pane #1 ──────────────────────────────────────────────────┐┌ Pane #2 ─────────────────────────────────────────────────┐ +01 (C): │ │┌ Pane #3 ─────────────────────────────────────────────────┐ +02 (C): │ ││ │ +03 (C): │ ││ │ +04 (C): │ ││ │ +05 (C): │ ││ │ +06 (C): │ ││ │ +07 (C): │ ││ │ +08 (C): │ ││ │ +09 (C): │ ││ │ +10 (C): │ ││ │ +11 (C): │ ││ │ +12 (C): │ ││ │ +13 (C): │ ││ │ +14 (C): │ ││ │ +15 (C): │ ││ │ +16 (C): │ ││ │ +17 (C): │ │└──────────────────────────────────────────────────────────┘ +18 (C): │ │└ Pane #4 ─────────────────────────────────────────────────┘ +19 (C): └───────────────────────────────────────────────────────────┘└ Pane #5 ─────────────────────────────────────────────────┘ + diff --git a/zellij-server/src/tab/unit/tab_integration_tests.rs b/zellij-server/src/tab/unit/tab_integration_tests.rs index d7556eed4..24fa1b2f1 100644 --- a/zellij-server/src/tab/unit/tab_integration_tests.rs +++ b/zellij-server/src/tab/unit/tab_integration_tests.rs @@ -6793,3 +6793,35 @@ fn when_applying_a_truncated_swap_layout_child_attributes_are_not_ignored() { ); assert_snapshot!(snapshot); } + +#[test] +fn can_define_expanded_pane_in_stack() { + let layout = r#" + layout { + pane split_direction="Vertical" { + pane + pane stacked=true { + pane + pane expanded=true + pane + pane + } + } + } + "#; + let size = Size { + cols: 121, + rows: 20, + }; + let client_id = 1; + let mut tab = create_new_tab_with_layout(size, ModeInfo::default(), layout); + let mut output = Output::default(); + tab.render(&mut output, None).unwrap(); + let snapshot = take_snapshot( + output.serialize().unwrap().get(&client_id).unwrap(), + size.rows, + size.cols, + Palette::default(), + ); + assert_snapshot!(snapshot); +} diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap index 08168b960..45e58cf70 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_default_params.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2394 +assertion_line: 2397 expression: "format!(\"{:#?}\", new_tab_action)" --- Some( @@ -21,6 +21,7 @@ Some( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -32,6 +33,7 @@ Some( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -40,6 +42,7 @@ Some( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap index 195fc81ec..d09628ded 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_new_tab_action_with_name_and_layout.snap @@ -1,6 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs -assertion_line: 2445 +assertion_line: 2448 expression: "format!(\"{:#?}\", new_tab_instruction)" --- NewTab( @@ -24,6 +24,7 @@ NewTab( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -39,6 +40,7 @@ NewTab( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -54,6 +56,7 @@ NewTab( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -62,6 +65,7 @@ NewTab( focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_rename_tab.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_rename_tab.snap index 2423ce987..c0312eb7b 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_rename_tab.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_rename_tab.snap @@ -1,5 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs +assertion_line: 2632 expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" --- [ @@ -42,6 +43,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -53,6 +55,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -61,6 +64,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], @@ -196,6 +200,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -207,6 +212,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -215,6 +221,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], diff --git a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_undo_rename_tab.snap b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_undo_rename_tab.snap index 0b777a1ef..525bb97d3 100644 --- a/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_undo_rename_tab.snap +++ b/zellij-server/src/unit/snapshots/zellij_server__screen__screen_tests__send_cli_undo_rename_tab.snap @@ -1,5 +1,6 @@ --- source: zellij-server/src/./unit/screen_tests.rs +assertion_line: 2675 expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" --- [ @@ -42,6 +43,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -53,6 +55,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -61,6 +64,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], @@ -196,6 +200,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, TiledPaneLayout { children_split_direction: Horizontal, @@ -207,6 +212,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ], split_size: None, @@ -215,6 +221,7 @@ expression: "format!(\"{:#?}\", * received_plugin_instructions.lock().unwrap())" focus: None, external_children_index: None, children_are_stacked: false, + is_expanded_in_stack: false, }, ), [], |