aboutsummaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authordenis <denismaximov98@gmail.com>2021-01-29 06:24:59 +0200
committerdenis <denismaximov98@gmail.com>2021-01-29 06:24:59 +0200
commit6a3481f54f0ee789ceeb994d8f302e3ce119c031 (patch)
tree60d4ad8d08c2349571d29d68c357ac07c6acce63 /src/client
parentwip: oops shouldn't forget that (diff)
parentfeat(statusbar): max status bar height (#156) (diff)
downloadsl0ppij-6a3481f54f0ee789ceeb994d8f302e3ce119c031.tar.gz
sl0ppij-6a3481f54f0ee789ceeb994d8f302e3ce119c031.tar.xz
sl0ppij-6a3481f54f0ee789ceeb994d8f302e3ce119c031.zip
Merge branch 'main' into restructure
Diffstat (limited to 'src/client')
-rw-r--r--src/client/panes/plugin_pane.rs8
-rw-r--r--src/client/panes/terminal_pane.rs8
-rw-r--r--src/client/tab.rs259
3 files changed, 241 insertions, 34 deletions
diff --git a/src/client/panes/plugin_pane.rs b/src/client/panes/plugin_pane.rs
index a93ff8c0..aeda170a 100644
--- a/src/client/panes/plugin_pane.rs
+++ b/src/client/panes/plugin_pane.rs
@@ -13,6 +13,7 @@ pub struct PluginPane {
pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>,
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
+ pub max_height: Option<usize>,
}
impl PluginPane {
@@ -28,6 +29,7 @@ impl PluginPane {
position_and_size,
position_and_size_override: None,
send_plugin_instructions,
+ max_height: None,
}
}
}
@@ -100,6 +102,9 @@ impl Pane for PluginPane {
fn set_selectable(&mut self, selectable: bool) {
self.selectable = selectable;
}
+ fn set_max_height(&mut self, max_height: usize) {
+ self.max_height = Some(max_height);
+ }
fn render(&mut self) -> Option<String> {
// if self.should_render {
if true {
@@ -172,4 +177,7 @@ impl Pane for PluginPane {
fn clear_scroll(&mut self) {
unimplemented!()
}
+ fn max_height(&self) -> Option<usize> {
+ self.max_height
+ }
}
diff --git a/src/client/panes/terminal_pane.rs b/src/client/panes/terminal_pane.rs
index 853ae064..fe7fb585 100644
--- a/src/client/panes/terminal_pane.rs
+++ b/src/client/panes/terminal_pane.rs
@@ -46,6 +46,7 @@ pub struct TerminalPane {
pub position_and_size: PositionAndSize,
pub position_and_size_override: Option<PositionAndSize>,
pub cursor_key_mode: bool, // DECCKM - when set, cursor keys should send ANSI direction codes (eg. "OD") instead of the arrow keys (eg. "")
+ pub max_height: Option<usize>,
pending_styles: CharacterStyles,
clear_viewport_before_rendering: bool,
}
@@ -177,6 +178,12 @@ impl Pane for TerminalPane {
fn set_selectable(&mut self, selectable: bool) {
self.selectable = selectable;
}
+ fn set_max_height(&mut self, max_height: usize) {
+ self.max_height = Some(max_height);
+ }
+ fn max_height(&self) -> Option<usize> {
+ self.max_height
+ }
fn render(&mut self) -> Option<String> {
// if self.should_render {
if true {
@@ -309,6 +316,7 @@ impl TerminalPane {
position_and_size_override: None,
cursor_key_mode: false,
clear_viewport_before_rendering: false,
+ max_height: None,
}
}
pub fn mark_for_rerender(&mut self) {
diff --git a/src/client/tab.rs b/src/client/tab.rs
index 6c65958f..190292a0 100644
--- a/src/client/tab.rs
+++ b/src/client/tab.rs
@@ -21,6 +21,8 @@ use std::{io::Write, sync::mpsc::channel};
*/
const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this
+const MIN_TERMINAL_HEIGHT: usize = 2;
+const MIN_TERMINAL_WIDTH: usize = 4;
type BorderAndPaneIds = (usize, Vec<PaneId>);
@@ -84,6 +86,7 @@ pub trait Pane {
fn set_should_render(&mut self, should_render: bool);
fn selectable(&self) -> bool;
fn set_selectable(&mut self, selectable: bool);
+ fn set_max_height(&mut self, max_height: usize);
fn render(&mut self) -> Option<String>;
fn pid(&self) -> PaneId;
fn reduce_height_down(&mut self, count: usize);
@@ -140,6 +143,18 @@ pub trait Pane {
std::cmp::min(self.x() + self.columns(), other.x() + other.columns())
- std::cmp::max(self.x(), other.x())
}
+ fn min_width(&self) -> usize {
+ MIN_TERMINAL_WIDTH
+ }
+ fn min_height(&self) -> usize {
+ MIN_TERMINAL_HEIGHT
+ }
+ fn max_width(&self) -> Option<usize> {
+ None
+ }
+ fn max_height(&self) -> Option<usize> {
+ None
+ }
}
impl Tab {
@@ -273,19 +288,32 @@ impl Tab {
} else {
// TODO: check minimum size of active terminal
- let (_longest_edge, terminal_id_to_split) = self.get_panes().fold(
- (0, PaneId::Terminal(0)), // FIXME: This is a bit hacky, try to use a maximum method?
- |(current_longest_edge, current_terminal_id_to_split), id_and_terminal_to_check| {
+ let (_largest_terminal_size, terminal_id_to_split) = self.get_panes().fold(
+ (0, None),
+ |(current_largest_terminal_size, current_terminal_id_to_split),
+ id_and_terminal_to_check| {
let (id_of_terminal_to_check, terminal_to_check) = id_and_terminal_to_check;
let terminal_size = (terminal_to_check.rows() * CURSOR_HEIGHT_WIDTH_RATIO)
* terminal_to_check.columns();
- if terminal_size > current_longest_edge {
- (terminal_size, *id_of_terminal_to_check)
+ let terminal_can_be_split = terminal_to_check.columns() >= MIN_TERMINAL_WIDTH
+ && terminal_to_check.rows() >= MIN_TERMINAL_HEIGHT
+ && ((terminal_to_check.columns() >= terminal_to_check.min_width() * 2 + 1)
+ || (terminal_to_check.rows()
+ >= terminal_to_check.min_height() * 2 + 1));
+ if terminal_can_be_split && terminal_size > current_largest_terminal_size {
+ (terminal_size, Some(*id_of_terminal_to_check))
} else {
- (current_longest_edge, current_terminal_id_to_split)
+ (current_largest_terminal_size, current_terminal_id_to_split)
}
},
);
+ if terminal_id_to_split.is_none() {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return; // likely no terminal large enough to split
+ }
+ let terminal_id_to_split = terminal_id_to_split.unwrap();
let terminal_to_split = self.panes.get_mut(&terminal_id_to_split).unwrap();
let terminal_ws = PositionAndSize {
rows: terminal_to_split.rows(),
@@ -293,7 +321,9 @@ impl Tab {
x: terminal_to_split.x(),
y: terminal_to_split.y(),
};
- if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns() {
+ if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns()
+ && terminal_to_split.rows() >= terminal_to_split.min_height() * 2 + 1
+ {
// FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
@@ -314,23 +344,23 @@ impl Tab {
}
self.active_terminal = Some(pid);
}
- } else {
+ } else if terminal_to_split.columns() >= terminal_to_split.min_width() * 2 + 1 {
// FIXME: This could use a second look
if let PaneId::Terminal(term_pid) = pid {
- let (left_winszie, right_winsize) = split_vertically_with_gap(&terminal_ws);
+ let (left_winsize, right_winsize) = split_vertically_with_gap(&terminal_ws);
let new_terminal = TerminalPane::new(term_pid, right_winsize);
self.os_api.set_terminal_size_using_fd(
new_terminal.pid,
right_winsize.columns as u16,
right_winsize.rows as u16,
);
- terminal_to_split.change_pos_and_size(&left_winszie);
+ terminal_to_split.change_pos_and_size(&left_winsize);
self.panes.insert(pid, Box::new(new_terminal));
if let PaneId::Terminal(terminal_id_to_split) = terminal_id_to_split {
self.os_api.set_terminal_size_using_fd(
terminal_id_to_split,
- left_winszie.columns as u16,
- left_winszie.rows as u16,
+ left_winsize.columns as u16,
+ left_winsize.rows as u16,
);
}
}
@@ -362,6 +392,12 @@ impl Tab {
// TODO: check minimum size of active terminal
let active_pane_id = &self.get_active_pane_id().unwrap();
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.rows() < MIN_TERMINAL_HEIGHT * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
let terminal_ws = PositionAndSize {
x: active_pane.x(),
y: active_pane.y(),
@@ -416,6 +452,12 @@ impl Tab {
// TODO: check minimum size of active terminal
let active_pane_id = &self.get_active_pane_id().unwrap();
let active_pane = self.panes.get_mut(active_pane_id).unwrap();
+ if active_pane.columns() < MIN_TERMINAL_WIDTH * 2 + 1 {
+ self.send_pty_instructions
+ .send(PtyInstruction::ClosePane(pid)) // we can't open this pane, close the pty
+ .unwrap();
+ return;
+ }
let terminal_ws = PositionAndSize {
x: active_pane.x(),
y: active_pane.y(),
@@ -1373,29 +1415,173 @@ impl Tab {
self.increase_pane_width_left(&terminal_id, count);
}
}
- fn panes_exist_above(&self, pane_id: &PaneId) -> bool {
- let pane = self.panes.get(pane_id).expect("pane does not exist");
- pane.y() > 0
+ fn can_increase_pane_and_surroundings_right(
+ &self,
+ pane_id: &PaneId,
+ increase_by: usize,
+ ) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let can_increase_pane_size = pane
+ .max_width()
+ .map(|max_width| pane.columns() + increase_by <= max_width)
+ .unwrap_or(true); // no max width, increase to your heart's content
+ if !can_increase_pane_size {
+ return false;
+ }
+ if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) {
+ return panes_to_the_right.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.columns() > increase_by && p.columns() - increase_by >= p.min_width()
+ });
+ } else {
+ return false;
+ }
+ }
+ fn can_increase_pane_and_surroundings_left(
+ &self,
+ pane_id: &PaneId,
+ increase_by: usize,
+ ) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let can_increase_pane_size = pane
+ .max_width()
+ .map(|max_width| pane.columns() + increase_by <= max_width)
+ .unwrap_or(true); // no max width, increase to your heart's content
+ if !can_increase_pane_size {
+ return false;
+ }
+ if let Some(panes_to_the_left) = self.pane_ids_directly_left_of(&pane_id) {
+ return panes_to_the_left.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.columns() > increase_by && p.columns() - increase_by >= p.min_width()
+ });
+ } else {
+ return false;
+ }
+ }
+ fn can_increase_pane_and_surroundings_down(
+ &self,
+ pane_id: &PaneId,
+ increase_by: usize,
+ ) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let can_increase_pane_size = pane
+ .max_height()
+ .map(|max_height| pane.rows() + increase_by <= max_height)
+ .unwrap_or(true); // no max width, increase to your heart's content
+ if !can_increase_pane_size {
+ return false;
+ }
+ if let Some(panes_below) = self.pane_ids_directly_below(&pane_id) {
+ return panes_below.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.rows() > increase_by && p.rows() - increase_by >= p.min_height()
+ });
+ } else {
+ return false;
+ }
+ }
+ fn can_increase_pane_and_surroundings_up(&self, pane_id: &PaneId, increase_by: usize) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let can_increase_pane_size = pane
+ .max_height()
+ .map(|max_height| pane.rows() + increase_by <= max_height)
+ .unwrap_or(true); // no max width, increase to your heart's content
+ if !can_increase_pane_size {
+ return false;
+ }
+ if let Some(panes_above) = self.pane_ids_directly_above(&pane_id) {
+ return panes_above.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.rows() > increase_by && p.rows() - increase_by >= p.min_height()
+ });
+ } else {
+ return false;
+ }
}
- fn panes_exist_below(&self, pane_id: &PaneId) -> bool {
- let pane = self.panes.get(pane_id).expect("pane does not exist");
- pane.y() + pane.rows() < self.full_screen_ws.rows
+ fn can_reduce_pane_and_surroundings_right(&self, pane_id: &PaneId, reduce_by: usize) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let pane_columns = pane.columns();
+ let can_reduce_pane_size =
+ pane_columns > reduce_by && pane_columns - reduce_by >= pane.min_width();
+ if !can_reduce_pane_size {
+ return false;
+ }
+ if let Some(panes_to_the_left) = self.pane_ids_directly_left_of(&pane_id) {
+ return panes_to_the_left.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.max_width()
+ .map(|max_width| p.columns() + reduce_by <= max_width)
+ .unwrap_or(true) // no max width, increase to your heart's content
+ });
+ } else {
+ return false;
+ }
}
- fn panes_exist_to_the_right(&self, pane_id: &PaneId) -> bool {
- let pane = self.panes.get(pane_id).expect("pane does not exist");
- pane.x() + pane.columns() < self.full_screen_ws.columns
+ fn can_reduce_pane_and_surroundings_left(&self, pane_id: &PaneId, reduce_by: usize) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let pane_columns = pane.columns();
+ let can_reduce_pane_size =
+ pane_columns > reduce_by && pane_columns - reduce_by >= pane.min_width();
+ if !can_reduce_pane_size {
+ return false;
+ }
+ if let Some(panes_to_the_right) = self.pane_ids_directly_right_of(&pane_id) {
+ return panes_to_the_right.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.max_width()
+ .map(|max_width| p.columns() + reduce_by <= max_width)
+ .unwrap_or(true) // no max width, increase to your heart's content
+ });
+ } else {
+ return false;
+ }
}
- fn panes_exist_to_the_left(&self, pane_id: &PaneId) -> bool {
- let pane = self.panes.get(pane_id).expect("pane does not exist");
- pane.x() > 0
+ fn can_reduce_pane_and_surroundings_down(&self, pane_id: &PaneId, reduce_by: usize) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let pane_rows = pane.rows();
+ let can_reduce_pane_size =
+ pane_rows > reduce_by && pane_rows - reduce_by >= pane.min_height();
+ if !can_reduce_pane_size {
+ return false;
+ }
+ if let Some(panes_above) = self.pane_ids_directly_above(&pane_id) {
+ return panes_above.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.max_height()
+ .map(|max_height| p.rows() + reduce_by <= max_height)
+ .unwrap_or(true) // no max height, increase to your heart's content
+ });
+ } else {
+ return false;
+ }
+ }
+ fn can_reduce_pane_and_surroundings_up(&self, pane_id: &PaneId, reduce_by: usize) -> bool {
+ let pane = self.panes.get(pane_id).unwrap();
+ let pane_rows = pane.rows();
+ let can_reduce_pane_size =
+ pane_rows > reduce_by && pane_rows - reduce_by >= pane.min_height();
+ if !can_reduce_pane_size {
+ return false;
+ }
+ if let Some(panes_below) = self.pane_ids_directly_below(&pane_id) {
+ return panes_below.iter().all(|id| {
+ let p = self.panes.get(id).unwrap();
+ p.max_height()
+ .map(|max_height| p.rows() + reduce_by <= max_height)
+ .unwrap_or(true) // no max height, increase to your heart's content
+ });
+ } else {
+ return false;
+ }
}
pub fn resize_right(&mut self) {
// TODO: find out by how much we actually reduced and only reduce by that much
let count = 10;
if let Some(active_pane_id) = self.get_active_pane_id() {
- if self.panes_exist_to_the_right(&active_pane_id) {
+ if self.can_increase_pane_and_surroundings_right(&active_pane_id, count) {
self.increase_pane_and_surroundings_right(&active_pane_id, count);
- } else if self.panes_exist_to_the_left(&active_pane_id) {
+ } else if self.can_reduce_pane_and_surroundings_right(&active_pane_id, count) {
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
}
self.render();
@@ -1405,10 +1591,10 @@ impl Tab {
// TODO: find out by how much we actually reduced and only reduce by that much
let count = 10;
if let Some(active_pane_id) = self.get_active_pane_id() {
- if self.panes_exist_to_the_right(&active_pane_id) {
- self.reduce_pane_and_surroundings_left(&active_pane_id, count);
- } else if self.panes_exist_to_the_left(&active_pane_id) {
+ if self.can_increase_pane_and_surroundings_left(&active_pane_id, count) {
self.increase_pane_and_surroundings_left(&active_pane_id, count);
+ } else if self.can_reduce_pane_and_surroundings_left(&active_pane_id, count) {
+ self.reduce_pane_and_surroundings_left(&active_pane_id, count);
}
self.render();
}
@@ -1417,10 +1603,10 @@ impl Tab {
// TODO: find out by how much we actually reduced and only reduce by that much
let count = 2;
if let Some(active_pane_id) = self.get_active_pane_id() {
- if self.panes_exist_above(&active_pane_id) {
- self.reduce_pane_and_surroundings_down(&active_pane_id, count);
- } else if self.panes_exist_below(&active_pane_id) {
+ if self.can_increase_pane_and_surroundings_down(&active_pane_id, count) {
self.increase_pane_and_surroundings_down(&active_pane_id, count);
+ } else if self.can_reduce_pane_and_surroundings_down(&active_pane_id, count) {
+ self.reduce_pane_and_surroundings_down(&active_pane_id, count);
}
self.render();
}
@@ -1429,9 +1615,9 @@ impl Tab {
// TODO: find out by how much we actually reduced and only reduce by that much
let count = 2;
if let Some(active_pane_id) = self.get_active_pane_id() {
- if self.panes_exist_above(&active_pane_id) {
+ if self.can_increase_pane_and_surroundings_up(&active_pane_id, count) {
self.increase_pane_and_surroundings_up(&active_pane_id, count);
- } else if self.panes_exist_below(&active_pane_id) {
+ } else if self.can_reduce_pane_and_surroundings_up(&active_pane_id, count) {
self.reduce_pane_and_surroundings_up(&active_pane_id, count);
}
self.render();
@@ -1709,6 +1895,11 @@ impl Tab {
}
}
}
+ pub fn set_pane_max_height(&mut self, id: PaneId, max_height: usize) {
+ if let Some(pane) = self.panes.get_mut(&id) {
+ pane.set_max_height(max_height);
+ }
+ }
pub fn close_pane(&mut self, id: PaneId) {
if self.panes.get(&id).is_some() {
self.close_pane_without_rerender(id);