diff options
-rw-r--r-- | default-plugins/status-bar/src/second_line.rs | 67 | ||||
-rw-r--r-- | zellij-server/src/route.rs | 12 | ||||
-rw-r--r-- | zellij-server/src/screen.rs | 20 | ||||
-rw-r--r-- | zellij-server/src/tab.rs | 370 | ||||
-rw-r--r-- | zellij-server/src/unit/tab_tests.rs | 264 | ||||
-rw-r--r-- | zellij-utils/assets/config/default.yaml | 12 | ||||
-rw-r--r-- | zellij-utils/src/errors.rs | 2 | ||||
-rw-r--r-- | zellij-utils/src/input/actions.rs | 12 | ||||
-rw-r--r-- | zellij-utils/src/input/mod.rs | 5 |
9 files changed, 743 insertions, 21 deletions
diff --git a/default-plugins/status-bar/src/second_line.rs b/default-plugins/status-bar/src/second_line.rs index 0e59fcb8e..1b90443c0 100644 --- a/default-plugins/status-bar/src/second_line.rs +++ b/default-plugins/status-bar/src/second_line.rs @@ -90,14 +90,18 @@ fn quicknav_full(palette: Palette) -> LinePart { let text_first_part = " Tip: "; let alt = "Alt"; let text_second_part = " + "; - let new_pane_shortcut = "n"; + let new_pane_shortcut = "<n>"; let text_third_part = " => open new pane. "; let second_alt = "Alt"; let text_fourth_part = " + "; - let brackets_navigation = "[]"; + let brackets_navigation = "<[]"; let text_fifth_part = " or "; - let hjkl_navigation = "hjkl"; - let text_sixths_part = " => navigate between panes."; + let hjkl_navigation = "hjkl>"; + let text_sixths_part = " => navigate between panes. "; + let third_alt = "Alt"; + let text_seventh_parth = " + "; + let increase_decrease_parth = "<+->"; + let text_eighth_parth = " => increase/decrease pane size."; let len = text_first_part.chars().count() + alt.chars().count() + text_second_part.chars().count() @@ -108,7 +112,11 @@ fn quicknav_full(palette: Palette) -> LinePart { + brackets_navigation.chars().count() + text_fifth_part.chars().count() + hjkl_navigation.chars().count() - + text_sixths_part.chars().count(); + + text_sixths_part.chars().count() + + third_alt.chars().count() + + text_seventh_parth.chars().count() + + increase_decrease_parth.chars().count() + + text_eighth_parth.chars().count(); let green_color = match palette.green { PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), PaletteColor::EightBit(color) => Fixed(color), @@ -119,7 +127,7 @@ fn quicknav_full(palette: Palette) -> LinePart { }; LinePart { part: format!( - "{}{}{}{}{}{}{}{}{}{}{}", + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", text_first_part, Style::new().fg(orange_color).bold().paint(alt), text_second_part, @@ -134,6 +142,13 @@ fn quicknav_full(palette: Palette) -> LinePart { text_fifth_part, Style::new().fg(green_color).bold().paint(hjkl_navigation), text_sixths_part, + Style::new().fg(orange_color).bold().paint(third_alt), + text_seventh_parth, + Style::new() + .fg(green_color) + .bold() + .paint(increase_decrease_parth), + text_eighth_parth, ), len, } @@ -143,14 +158,18 @@ fn quicknav_medium(palette: Palette) -> LinePart { let text_first_part = " Tip: "; let alt = "Alt"; let text_second_part = " + "; - let new_pane_shortcut = "n"; + let new_pane_shortcut = "<n>"; let text_third_part = " => new pane. "; let second_alt = "Alt"; let text_fourth_part = " + "; - let brackets_navigation = "[]"; + let brackets_navigation = "<[]"; let text_fifth_part = " or "; - let hjkl_navigation = "hjkl"; - let text_sixths_part = " => navigate."; + let hjkl_navigation = "hjkl>"; + let text_sixths_part = " => navigate. "; + let third_alt = "Alt"; + let text_seventh_parth = " + "; + let increase_decrease_parth = "<+->"; + let text_eighth_parth = " => resize pane. "; let len = text_first_part.chars().count() + alt.chars().count() + text_second_part.chars().count() @@ -161,7 +180,11 @@ fn quicknav_medium(palette: Palette) -> LinePart { + brackets_navigation.chars().count() + text_fifth_part.chars().count() + hjkl_navigation.chars().count() - + text_sixths_part.chars().count(); + + text_sixths_part.chars().count() + + third_alt.chars().count() + + text_seventh_parth.chars().count() + + increase_decrease_parth.chars().count() + + text_eighth_parth.chars().count(); let green_color = match palette.green { PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), PaletteColor::EightBit(color) => Fixed(color), @@ -172,7 +195,7 @@ fn quicknav_medium(palette: Palette) -> LinePart { }; LinePart { part: format!( - "{}{}{}{}{}{}{}{}{}{}{}", + "{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}", text_first_part, Style::new().fg(orange_color).bold().paint(alt), text_second_part, @@ -187,6 +210,13 @@ fn quicknav_medium(palette: Palette) -> LinePart { text_fifth_part, Style::new().fg(green_color).bold().paint(hjkl_navigation), text_sixths_part, + Style::new().fg(orange_color).bold().paint(third_alt), + text_seventh_parth, + Style::new() + .fg(green_color) + .bold() + .paint(increase_decrease_parth), + text_eighth_parth, ), len, } @@ -201,6 +231,8 @@ fn quicknav_short(palette: Palette) -> LinePart { let brackets_navigation = "[]"; let text_fifth_part = "/"; let hjkl_navigation = "hjkl"; + let text_sixth_part = "/"; + let increase_decrease_part = "+-"; let len = text_first_part.chars().count() + alt.chars().count() + text_second_part.chars().count() @@ -208,7 +240,9 @@ fn quicknav_short(palette: Palette) -> LinePart { + text_third_part.chars().count() + brackets_navigation.chars().count() + text_fifth_part.chars().count() - + hjkl_navigation.chars().count(); + + hjkl_navigation.chars().count() + + text_sixth_part.chars().count() + + increase_decrease_part.chars().count(); let green_color = match palette.green { PaletteColor::Rgb((r, g, b)) => RGB(r, g, b), PaletteColor::EightBit(color) => Fixed(color), @@ -219,7 +253,7 @@ fn quicknav_short(palette: Palette) -> LinePart { }; LinePart { part: format!( - "{}{}{}{}{}{}{}{}", + "{}{}{}{}{}{}{}{}{}{}", text_first_part, Style::new().fg(orange_color).bold().paint(alt), text_second_part, @@ -231,6 +265,11 @@ fn quicknav_short(palette: Palette) -> LinePart { .paint(brackets_navigation), text_fifth_part, Style::new().fg(green_color).bold().paint(hjkl_navigation), + text_sixth_part, + Style::new() + .fg(green_color) + .bold() + .paint(increase_decrease_part), ), len, } diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 57fea1247..444be5a08 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -12,7 +12,7 @@ use crate::{ use zellij_utils::{ channels::SenderWithContext, input::{ - actions::{Action, Direction}, + actions::{Action, Direction, ResizeDirection}, command::TerminalAction, get_mode_info, }, @@ -87,10 +87,12 @@ fn route_action( } Action::Resize(direction) => { let screen_instr = match direction { - Direction::Left => ScreenInstruction::ResizeLeft(client_id), - Direction::Right => ScreenInstruction::ResizeRight(client_id), - Direction::Up => ScreenInstruction::ResizeUp(client_id), - Direction::Down => ScreenInstruction::ResizeDown(client_id), + ResizeDirection::Left => ScreenInstruction::ResizeLeft(client_id), + ResizeDirection::Right => ScreenInstruction::ResizeRight(client_id), + ResizeDirection::Up => ScreenInstruction::ResizeUp(client_id), + ResizeDirection::Down => ScreenInstruction::ResizeDown(client_id), + ResizeDirection::Increase => ScreenInstruction::ResizeIncrease(client_id), + ResizeDirection::Decrease => ScreenInstruction::ResizeDecrease(client_id), }; session.senders.send_to_screen(screen_instr).unwrap(); } diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 4852b305b..2a8c54c6a 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -35,6 +35,8 @@ pub(crate) enum ScreenInstruction { ResizeRight(ClientId), ResizeDown(ClientId), ResizeUp(ClientId), + ResizeIncrease(ClientId), + ResizeDecrease(ClientId), SwitchFocus(ClientId), FocusNextPane(ClientId), FocusPreviousPane(ClientId), @@ -95,6 +97,8 @@ impl From<&ScreenInstruction> for ScreenContext { ScreenInstruction::ResizeRight(..) => ScreenContext::ResizeRight, ScreenInstruction::ResizeDown(..) => ScreenContext::ResizeDown, ScreenInstruction::ResizeUp(..) => ScreenContext::ResizeUp, + ScreenInstruction::ResizeIncrease(..) => ScreenContext::ResizeIncrease, + ScreenInstruction::ResizeDecrease(..) => ScreenContext::ResizeDecrease, ScreenInstruction::SwitchFocus(..) => ScreenContext::SwitchFocus, ScreenInstruction::FocusNextPane(..) => ScreenContext::FocusNextPane, ScreenInstruction::FocusPreviousPane(..) => ScreenContext::FocusPreviousPane, @@ -659,6 +663,22 @@ pub(crate) fn screen_thread_main( screen.render(); } + ScreenInstruction::ResizeIncrease(client_id) => { + screen + .get_active_tab_mut(client_id) + .unwrap() + .resize_increase(); + + screen.render(); + } + ScreenInstruction::ResizeDecrease(client_id) => { + screen + .get_active_tab_mut(client_id) + .unwrap() + .resize_decrease(); + + screen.render(); + } ScreenInstruction::SwitchFocus(client_id) => { screen.get_active_tab_mut(client_id).unwrap().move_focus(); diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index 4d774b603..ffdf7e647 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -1749,6 +1749,308 @@ impl Tab { false } } + fn try_increase_pane_and_surroundings_right( + &mut self, + pane_id: &PaneId, + reduce_by: f64, + ) -> bool { + if self.can_increase_pane_and_surroundings_right(pane_id, reduce_by) { + self.increase_pane_and_surroundings_right(pane_id, reduce_by); + self.relayout_tab(Direction::Horizontal); + return true; + } + false + } + fn try_increase_pane_and_surroundings_left( + &mut self, + pane_id: &PaneId, + reduce_by: f64, + ) -> bool { + if self.can_increase_pane_and_surroundings_left(pane_id, reduce_by) { + self.increase_pane_and_surroundings_left(pane_id, reduce_by); + self.relayout_tab(Direction::Horizontal); + return true; + } + false + } + fn try_increase_pane_and_surroundings_up(&mut self, pane_id: &PaneId, reduce_by: f64) -> bool { + if self.can_increase_pane_and_surroundings_up(pane_id, reduce_by) { + self.increase_pane_and_surroundings_up(pane_id, reduce_by); + self.relayout_tab(Direction::Vertical); + return true; + } + false + } + fn try_increase_pane_and_surroundings_down( + &mut self, + pane_id: &PaneId, + reduce_by: f64, + ) -> bool { + if self.can_increase_pane_and_surroundings_down(pane_id, reduce_by) { + self.increase_pane_and_surroundings_down(pane_id, reduce_by); + self.relayout_tab(Direction::Vertical); + return true; + } + false + } + fn try_increase_pane_and_surroundings_right_and_up(&mut self, pane_id: &PaneId) -> bool { + let can_increase_pane_right = + self.can_increase_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + let can_increase_pane_up = + self.can_increase_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if can_increase_pane_right && can_increase_pane_up { + let pane_above_with_right_aligned_border = self + .viewport_pane_ids_directly_above(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() + active_pane.cols() == pane.x() + }); + self.try_increase_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + self.try_increase_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if let Some(pane_above_with_right_aligned_border) = pane_above_with_right_aligned_border + { + self.try_reduce_pane_and_surroundings_right( + &pane_above_with_right_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_increase_pane_and_surroundings_left_and_up(&mut self, pane_id: &PaneId) -> bool { + let can_increase_pane_left = + self.can_increase_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + let can_increase_pane_up = + self.can_increase_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if can_increase_pane_left && can_increase_pane_up { + let pane_above_with_left_aligned_border = self + .viewport_pane_ids_directly_above(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() == pane.x() + pane.cols() + }); + self.try_increase_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + self.try_increase_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if let Some(pane_above_with_left_aligned_border) = pane_above_with_left_aligned_border { + self.try_reduce_pane_and_surroundings_left( + &pane_above_with_left_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_increase_pane_and_surroundings_right_and_down(&mut self, pane_id: &PaneId) -> bool { + let can_increase_pane_right = + self.can_increase_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + let can_increase_pane_down = + self.can_increase_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if can_increase_pane_right && can_increase_pane_down { + let pane_below_with_right_aligned_border = self + .viewport_pane_ids_directly_below(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() + active_pane.cols() == pane.x() + }); + self.try_increase_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + self.try_increase_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if let Some(pane_below_with_right_aligned_border) = pane_below_with_right_aligned_border + { + self.try_reduce_pane_and_surroundings_right( + &pane_below_with_right_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_increase_pane_and_surroundings_left_and_down(&mut self, pane_id: &PaneId) -> bool { + let can_increase_pane_left = + self.can_increase_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + let can_increase_pane_down = + self.can_increase_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if can_increase_pane_left && can_increase_pane_down { + let pane_below_with_left_aligned_border = self + .viewport_pane_ids_directly_below(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() == pane.x() + pane.cols() + }); + self.try_increase_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + self.try_increase_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if let Some(pane_below_with_left_aligned_border) = pane_below_with_left_aligned_border { + self.try_reduce_pane_and_surroundings_left( + &pane_below_with_left_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_reduce_pane_and_surroundings_right_and_up(&mut self, pane_id: &PaneId) -> bool { + let can_reduce_pane_right = + self.can_reduce_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + let can_reduce_pane_up = self.can_reduce_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if can_reduce_pane_right && can_reduce_pane_up { + let pane_below_with_left_aligned_border = self + .viewport_pane_ids_directly_below(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() == pane.x() + pane.cols() + }); + self.try_reduce_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + self.try_reduce_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if let Some(pane_below_with_left_aligned_border) = pane_below_with_left_aligned_border { + self.try_increase_pane_and_surroundings_right( + &pane_below_with_left_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_reduce_pane_and_surroundings_left_and_up(&mut self, pane_id: &PaneId) -> bool { + let can_reduce_pane_left = + self.can_reduce_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + let can_reduce_pane_up = self.can_reduce_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if can_reduce_pane_left && can_reduce_pane_up { + let pane_below_with_right_aligned_border = self + .viewport_pane_ids_directly_below(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() + active_pane.cols() == pane.x() + }); + self.try_reduce_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + self.try_reduce_pane_and_surroundings_up(pane_id, RESIZE_PERCENT); + if let Some(pane_below_with_right_aligned_border) = pane_below_with_right_aligned_border + { + self.try_increase_pane_and_surroundings_left( + &pane_below_with_right_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_reduce_pane_and_surroundings_right_and_down(&mut self, pane_id: &PaneId) -> bool { + let can_reduce_pane_right = + self.can_reduce_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + let can_reduce_pane_down = + self.can_reduce_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if can_reduce_pane_right && can_reduce_pane_down { + let pane_above_with_left_aligned_border = self + .viewport_pane_ids_directly_above(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() == pane.x() + pane.cols() + }); + self.try_reduce_pane_and_surroundings_right(pane_id, RESIZE_PERCENT); + self.try_reduce_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if let Some(pane_above_with_left_aligned_border) = pane_above_with_left_aligned_border { + self.try_increase_pane_and_surroundings_right( + &pane_above_with_left_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_reduce_pane_and_surroundings_left_and_down(&mut self, pane_id: &PaneId) -> bool { + let can_reduce_pane_left = + self.can_reduce_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + let can_reduce_pane_down = + self.can_reduce_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if can_reduce_pane_left && can_reduce_pane_down { + let pane_above_with_right_aligned_border = self + .viewport_pane_ids_directly_above(pane_id) + .iter() + .copied() + .find(|p_id| { + let pane = self.panes.get(p_id).unwrap(); + let active_pane = self.panes.get(pane_id).unwrap(); + active_pane.x() + active_pane.cols() == pane.x() + }); + self.try_reduce_pane_and_surroundings_left(pane_id, RESIZE_PERCENT); + self.try_reduce_pane_and_surroundings_down(pane_id, RESIZE_PERCENT); + if let Some(pane_above_with_right_aligned_border) = pane_above_with_right_aligned_border + { + self.try_increase_pane_and_surroundings_left( + &pane_above_with_right_aligned_border, + RESIZE_PERCENT, + ); + } + true + } else { + false + } + } + fn try_reduce_pane_and_surroundings_right(&mut self, pane_id: &PaneId, reduce_by: f64) -> bool { + if self.can_reduce_pane_and_surroundings_right(pane_id, reduce_by) { + self.reduce_pane_and_surroundings_right(pane_id, reduce_by); + self.relayout_tab(Direction::Horizontal); + return true; + } + false + } + fn try_reduce_pane_and_surroundings_left(&mut self, pane_id: &PaneId, reduce_by: f64) -> bool { + if self.can_reduce_pane_and_surroundings_left(pane_id, reduce_by) { + self.reduce_pane_and_surroundings_left(pane_id, reduce_by); + self.relayout_tab(Direction::Horizontal); + return true; + } + false + } + fn try_reduce_pane_and_surroundings_up(&mut self, pane_id: &PaneId, reduce_by: f64) -> bool { + if self.can_reduce_pane_and_surroundings_up(pane_id, reduce_by) { + self.reduce_pane_and_surroundings_up(pane_id, reduce_by); + self.relayout_tab(Direction::Vertical); + return true; + } + false + } + fn try_reduce_pane_and_surroundings_down(&mut self, pane_id: &PaneId, reduce_by: f64) -> bool { + if self.can_reduce_pane_and_surroundings_down(pane_id, reduce_by) { + self.reduce_pane_and_surroundings_down(pane_id, reduce_by); + self.relayout_tab(Direction::Vertical); + return true; + } + false + } fn ids_are_flexible(&self, direction: Direction, pane_ids: Option<Vec<PaneId>>) -> bool { pane_ids.is_some() && pane_ids.unwrap().iter().all(|id| { @@ -1840,6 +2142,60 @@ impl Tab { } self.relayout_tab(Direction::Vertical); } + pub fn resize_increase(&mut self) { + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.try_increase_pane_and_surroundings_right_and_down(&active_pane_id) { + return; + } + if self.try_increase_pane_and_surroundings_left_and_down(&active_pane_id) { + return; + } + if self.try_increase_pane_and_surroundings_right_and_up(&active_pane_id) { + return; + } + if self.try_increase_pane_and_surroundings_left_and_up(&active_pane_id) { + return; + } + + if self.try_increase_pane_and_surroundings_right(&active_pane_id, RESIZE_PERCENT) { + return; + } + if self.try_increase_pane_and_surroundings_down(&active_pane_id, RESIZE_PERCENT) { + return; + } + if self.try_increase_pane_and_surroundings_left(&active_pane_id, RESIZE_PERCENT) { + return; + } + self.try_increase_pane_and_surroundings_up(&active_pane_id, RESIZE_PERCENT); + } + } + pub fn resize_decrease(&mut self) { + if let Some(active_pane_id) = self.get_active_pane_id() { + if self.try_reduce_pane_and_surroundings_left_and_up(&active_pane_id) { + return; + } + if self.try_reduce_pane_and_surroundings_right_and_up(&active_pane_id) { + return; + } + if self.try_reduce_pane_and_surroundings_right_and_down(&active_pane_id) { + return; + } + if self.try_reduce_pane_and_surroundings_left_and_down(&active_pane_id) { + return; + } + if self.try_reduce_pane_and_surroundings_left(&active_pane_id, RESIZE_PERCENT) { + return; + } + if self.try_reduce_pane_and_surroundings_right(&active_pane_id, RESIZE_PERCENT) { + return; + } + if self.try_reduce_pane_and_surroundings_up(&active_pane_id, RESIZE_PERCENT) { + return; + } |