mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-23 19:10:09 +03:00
refactor(tabs): lay down infrastructure for status bar (#116)
* resolves #76 * move private fun to bottom * refactor(tabs): do not allocate when filtering panes to terminals * style(formatting): make rustfmt happy Co-authored-by: Aram Drevekenin <aram@poor.dev>
This commit is contained in:
parent
83a830e4ab
commit
75b00b7932
@ -135,7 +135,7 @@ impl Screen {
|
||||
self.switch_tab_prev();
|
||||
}
|
||||
let mut active_tab = self.tabs.remove(&active_tab_index).unwrap();
|
||||
let pane_ids = active_tab.get_pane_ids();
|
||||
let pane_ids = active_tab.get_terminal_pane_ids();
|
||||
self.send_pty_instructions
|
||||
.send(PtyInstruction::CloseTab(pane_ids))
|
||||
.unwrap();
|
||||
|
407
src/tab.rs
407
src/tab.rs
@ -49,9 +49,14 @@ fn split_horizontally_with_gap(rect: &PositionAndSize) -> (PositionAndSize, Posi
|
||||
(first_rect, second_rect)
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||
enum PaneKind {
|
||||
Terminal(RawFd),
|
||||
BuiltInPane(u32),
|
||||
}
|
||||
pub struct Tab {
|
||||
pub index: usize,
|
||||
terminals: BTreeMap<RawFd, TerminalPane>,
|
||||
panes: BTreeMap<PaneKind, TerminalPane>,
|
||||
panes_to_hide: HashSet<RawFd>,
|
||||
active_terminal: Option<RawFd>,
|
||||
max_panes: Option<usize>,
|
||||
@ -72,22 +77,22 @@ impl Tab {
|
||||
max_panes: Option<usize>,
|
||||
pane_id: Option<RawFd>,
|
||||
) -> Self {
|
||||
let terminals = if let Some(pid) = pane_id {
|
||||
let panes = if let Some(pid) = pane_id {
|
||||
let new_terminal = TerminalPane::new(pid, *full_screen_ws, 0, 0);
|
||||
os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
);
|
||||
let mut terminals = BTreeMap::new();
|
||||
terminals.insert(pid, new_terminal);
|
||||
terminals
|
||||
let mut panes = BTreeMap::new();
|
||||
panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
panes
|
||||
} else {
|
||||
BTreeMap::new()
|
||||
};
|
||||
Tab {
|
||||
index: index,
|
||||
terminals,
|
||||
panes,
|
||||
max_panes,
|
||||
panes_to_hide: HashSet::new(),
|
||||
active_terminal: pane_id,
|
||||
@ -110,21 +115,24 @@ impl Tab {
|
||||
self.panes_to_hide.clear();
|
||||
let positions_in_layout = layout.position_panes_in_space(&free_space);
|
||||
let mut positions_and_size = positions_in_layout.iter();
|
||||
for (pid, terminal_pane) in self.terminals.iter_mut() {
|
||||
match positions_and_size.next() {
|
||||
Some(position_and_size) => {
|
||||
terminal_pane.reset_size_and_position_override();
|
||||
terminal_pane.change_size_p(&position_and_size);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*pid,
|
||||
position_and_size.columns as u16,
|
||||
position_and_size.rows as u16,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
// we filled the entire layout, no room for this pane
|
||||
// TODO: handle active terminal
|
||||
self.panes_to_hide.insert(*pid);
|
||||
for (pane_kind, terminal_pane) in self.panes.iter_mut() {
|
||||
// for now the layout only supports terminal panes
|
||||
if let PaneKind::Terminal(pid) = pane_kind {
|
||||
match positions_and_size.next() {
|
||||
Some(position_and_size) => {
|
||||
terminal_pane.reset_size_and_position_override();
|
||||
terminal_pane.change_size_p(&position_and_size);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*pid,
|
||||
position_and_size.columns as u16,
|
||||
position_and_size.rows as u16,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
// we filled the entire layout, no room for this pane
|
||||
// TODO: handle active terminal
|
||||
self.panes_to_hide.insert(*pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -144,7 +152,7 @@ impl Tab {
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
);
|
||||
self.terminals.insert(*pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(*pid), new_terminal);
|
||||
}
|
||||
for unused_pid in new_pids {
|
||||
// this is a bit of a hack and happens because we don't have any central location that
|
||||
@ -154,7 +162,14 @@ impl Tab {
|
||||
.send(PtyInstruction::ClosePane(*unused_pid))
|
||||
.unwrap();
|
||||
}
|
||||
self.active_terminal = Some(*self.terminals.iter().next().unwrap().0);
|
||||
self.active_terminal = self
|
||||
.panes
|
||||
.iter()
|
||||
.filter_map(|(pane_kind, _)| match pane_kind {
|
||||
PaneKind::Terminal(pid) => Some(*pid),
|
||||
_ => None,
|
||||
})
|
||||
.next();
|
||||
self.render();
|
||||
}
|
||||
pub fn new_pane(&mut self, pid: RawFd) {
|
||||
@ -162,7 +177,7 @@ impl Tab {
|
||||
if self.fullscreen_is_active {
|
||||
self.toggle_active_terminal_fullscreen();
|
||||
}
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
@ -171,25 +186,28 @@ impl Tab {
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
);
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
self.active_terminal = Some(pid);
|
||||
} else {
|
||||
// TODO: check minimum size of active terminal
|
||||
|
||||
let (_longest_edge, terminal_id_to_split) = self.terminals.iter().fold(
|
||||
let (_longest_edge, terminal_id_to_split) = self.get_terminals().fold(
|
||||
(0, 0),
|
||||
|(current_longest_edge, 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.get_rows() * CURSOR_HEIGHT_WIDTH_RATIO)
|
||||
* terminal_to_check.get_columns();
|
||||
if terminal_size > current_longest_edge {
|
||||
(terminal_size, *id_of_terminal_to_check)
|
||||
(terminal_size, id_of_terminal_to_check)
|
||||
} else {
|
||||
(current_longest_edge, current_terminal_id_to_split)
|
||||
}
|
||||
},
|
||||
);
|
||||
let terminal_to_split = self.terminals.get_mut(&terminal_id_to_split).unwrap();
|
||||
let terminal_to_split = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(terminal_id_to_split))
|
||||
.unwrap();
|
||||
let terminal_ws = PositionAndSize {
|
||||
rows: terminal_to_split.get_rows(),
|
||||
columns: terminal_to_split.get_columns(),
|
||||
@ -209,7 +227,7 @@ impl Tab {
|
||||
bottom_winsize.rows as u16,
|
||||
);
|
||||
terminal_to_split.change_size(&top_winsize);
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal_id_to_split,
|
||||
top_winsize.columns as u16,
|
||||
@ -227,7 +245,7 @@ impl Tab {
|
||||
right_winsize.rows as u16,
|
||||
);
|
||||
terminal_to_split.change_size(&left_winszie);
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal_id_to_split,
|
||||
left_winszie.columns as u16,
|
||||
@ -243,7 +261,7 @@ impl Tab {
|
||||
if self.fullscreen_is_active {
|
||||
self.toggle_active_terminal_fullscreen();
|
||||
}
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
@ -252,7 +270,7 @@ impl Tab {
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
);
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
self.active_terminal = Some(pid);
|
||||
} else {
|
||||
// TODO: check minimum size of active terminal
|
||||
@ -281,11 +299,14 @@ impl Tab {
|
||||
|
||||
{
|
||||
let active_terminal_id = &self.get_active_terminal_id().unwrap();
|
||||
let active_terminal = &mut self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = &mut self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(*active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.change_size(&top_winsize);
|
||||
}
|
||||
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
active_terminal_pid,
|
||||
@ -301,7 +322,7 @@ impl Tab {
|
||||
if self.fullscreen_is_active {
|
||||
self.toggle_active_terminal_fullscreen();
|
||||
}
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
@ -310,7 +331,7 @@ impl Tab {
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
);
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
self.active_terminal = Some(pid);
|
||||
} else {
|
||||
// TODO: check minimum size of active terminal
|
||||
@ -339,11 +360,14 @@ impl Tab {
|
||||
|
||||
{
|
||||
let active_terminal_id = &self.get_active_terminal_id().unwrap();
|
||||
let active_terminal = &mut self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = &mut self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(*active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.change_size(&left_winszie);
|
||||
}
|
||||
|
||||
self.terminals.insert(pid, new_terminal);
|
||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
||||
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
active_terminal_pid,
|
||||
@ -356,13 +380,18 @@ impl Tab {
|
||||
}
|
||||
pub fn get_active_terminal(&self) -> Option<&TerminalPane> {
|
||||
match self.active_terminal {
|
||||
Some(active_terminal) => self.terminals.get(&active_terminal),
|
||||
Some(active_terminal) => self.panes.get(&PaneKind::Terminal(active_terminal)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
fn get_active_terminal_id(&self) -> Option<RawFd> {
|
||||
match self.active_terminal {
|
||||
Some(active_terminal) => Some(self.terminals.get(&active_terminal).unwrap().pid),
|
||||
Some(active_terminal) => Some(
|
||||
self.panes
|
||||
.get(&PaneKind::Terminal(active_terminal))
|
||||
.unwrap()
|
||||
.pid,
|
||||
),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
@ -372,7 +401,7 @@ impl Tab {
|
||||
// yet been created in Screen. These events are currently not buffered, so
|
||||
// if you're debugging seemingly randomly missing stdout data, this is
|
||||
// the reason
|
||||
if let Some(terminal_output) = self.terminals.get_mut(&pid) {
|
||||
if let Some(terminal_output) = self.panes.get_mut(&PaneKind::Terminal(pid)) {
|
||||
terminal_output.handle_event(event);
|
||||
}
|
||||
}
|
||||
@ -408,21 +437,37 @@ impl Tab {
|
||||
.is_some()
|
||||
{
|
||||
for terminal_id in self.panes_to_hide.iter() {
|
||||
self.terminals.get_mut(terminal_id).unwrap().should_render = true;
|
||||
self.panes
|
||||
.get_mut(&PaneKind::Terminal(*terminal_id))
|
||||
.unwrap()
|
||||
.should_render = true;
|
||||
}
|
||||
self.panes_to_hide.clear();
|
||||
let active_terminal = self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.reset_size_and_position_override();
|
||||
} else {
|
||||
let all_ids_except_current = self
|
||||
.terminals
|
||||
.keys()
|
||||
.filter(|id| **id != active_terminal_id);
|
||||
self.panes_to_hide = all_ids_except_current.copied().collect();
|
||||
let active_terminal = self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let terminals = self.get_terminals();
|
||||
let all_ids_except_current = terminals.filter_map(|(id, _)| {
|
||||
if id != active_terminal_id {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
self.panes_to_hide = all_ids_except_current.collect();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.override_size_and_position(0, 0, &self.full_screen_ws);
|
||||
}
|
||||
let active_terminal = self.terminals.get(&active_terminal_id).unwrap();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
active_terminal_id,
|
||||
active_terminal.get_columns() as u16,
|
||||
@ -446,13 +491,20 @@ impl Tab {
|
||||
self.full_screen_ws.columns as u16,
|
||||
self.full_screen_ws.rows as u16,
|
||||
);
|
||||
for (pid, terminal) in self.terminals.iter_mut() {
|
||||
if !self.panes_to_hide.contains(pid) {
|
||||
boundaries.add_rect(&terminal);
|
||||
if let Some(vte_output) = terminal.buffer_as_vte_output() {
|
||||
stdout
|
||||
.write_all(&vte_output.as_bytes())
|
||||
.expect("cannot write to stdout");
|
||||
for (pane_kind, terminal) in self.panes.iter_mut() {
|
||||
match pane_kind {
|
||||
PaneKind::Terminal(pid) => {
|
||||
if !self.panes_to_hide.contains(pid) {
|
||||
boundaries.add_rect(&terminal);
|
||||
if let Some(vte_output) = terminal.buffer_as_vte_output() {
|
||||
stdout
|
||||
.write_all(&vte_output.as_bytes())
|
||||
.expect("cannot write to stdout");
|
||||
}
|
||||
}
|
||||
}
|
||||
PaneKind::BuiltInPane(builtin_id) => {
|
||||
// TBD
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -488,15 +540,27 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn get_terminals(&self) -> impl Iterator<Item = (RawFd, &TerminalPane)> {
|
||||
self.panes
|
||||
.iter()
|
||||
.filter_map(|(pane_kind, terminal_pane)| match pane_kind {
|
||||
PaneKind::Terminal(pid) => Some((*pid, terminal_pane)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
fn has_terminal_panes(&self) -> bool {
|
||||
let mut all_terminals = self.get_terminals();
|
||||
all_terminals.next().is_some()
|
||||
}
|
||||
fn terminal_ids_directly_left_of(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
||||
let mut ids = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
if terminal_to_check.get_x() == 0 {
|
||||
return None;
|
||||
}
|
||||
for (pid, terminal) in self.terminals.iter() {
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.get_x() + terminal.get_columns() == terminal_to_check.get_x() - 1 {
|
||||
ids.push(*pid);
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
if ids.is_empty() {
|
||||
@ -507,10 +571,10 @@ impl Tab {
|
||||
}
|
||||
fn terminal_ids_directly_right_of(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
||||
let mut ids = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
for (pid, terminal) in self.terminals.iter() {
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.get_x() == terminal_to_check.get_x() + terminal_to_check.get_columns() + 1 {
|
||||
ids.push(*pid);
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
if ids.is_empty() {
|
||||
@ -521,10 +585,10 @@ impl Tab {
|
||||
}
|
||||
fn terminal_ids_directly_below(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
||||
let mut ids = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
for (pid, terminal) in self.terminals.iter() {
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.get_y() == terminal_to_check.get_y() + terminal_to_check.get_rows() + 1 {
|
||||
ids.push(*pid);
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
if ids.is_empty() {
|
||||
@ -535,10 +599,10 @@ impl Tab {
|
||||
}
|
||||
fn terminal_ids_directly_above(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
||||
let mut ids = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
for (pid, terminal) in self.terminals.iter() {
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.get_y() + terminal.get_rows() + 1 == terminal_to_check.get_y() {
|
||||
ids.push(*pid);
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
if ids.is_empty() {
|
||||
@ -548,16 +612,16 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
fn panes_top_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
||||
self.terminals
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.terminals.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| terminal.pid != pane.pid && terminal.get_y() == pane.get_y())
|
||||
.collect()
|
||||
}
|
||||
fn panes_bottom_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
||||
self.terminals
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.terminals.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| {
|
||||
terminal.pid != pane.pid
|
||||
&& terminal.get_y() + terminal.get_rows() == pane.get_y() + pane.get_rows()
|
||||
@ -565,9 +629,9 @@ impl Tab {
|
||||
.collect()
|
||||
}
|
||||
fn panes_right_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
||||
self.terminals
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.terminals.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| {
|
||||
terminal.pid != pane.pid
|
||||
&& terminal.get_x() + terminal.get_columns()
|
||||
@ -576,9 +640,9 @@ impl Tab {
|
||||
.collect()
|
||||
}
|
||||
fn panes_left_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
||||
self.terminals
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.terminals.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| terminal.pid != pane.pid && terminal.get_x() == pane.get_x())
|
||||
.collect()
|
||||
}
|
||||
@ -588,7 +652,10 @@ impl Tab {
|
||||
terminal_borders_to_the_right: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).expect("terminal id does not exist");
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("terminal id does not exist");
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
right_aligned_terminals.sort_by(|a, b| b.get_y().cmp(&a.get_y()));
|
||||
@ -627,7 +694,10 @@ impl Tab {
|
||||
terminal_borders_to_the_right: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).expect("terminal id does not exist");
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("terminal id does not exist");
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
right_aligned_terminals.sort_by(|a, b| a.get_y().cmp(&b.get_y()));
|
||||
@ -666,7 +736,10 @@ impl Tab {
|
||||
terminal_borders_to_the_left: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).expect("terminal id does not exist");
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("terminal id does not exist");
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
left_aligned_terminals.sort_by(|a, b| b.get_y().cmp(&a.get_y()));
|
||||
@ -705,7 +778,10 @@ impl Tab {
|
||||
terminal_borders_to_the_left: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).expect("terminal id does not exist");
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("terminal id does not exist");
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
left_aligned_terminals.sort_by(|a, b| a.get_y().cmp(&b.get_y()));
|
||||
@ -747,7 +823,10 @@ impl Tab {
|
||||
terminal_borders_above: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).expect("terminal id does not exist");
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("terminal id does not exist");
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
top_aligned_terminals.sort_by(|a, b| b.get_x().cmp(&a.get_x()));
|
||||
@ -786,7 +865,7 @@ impl Tab {
|
||||
terminal_borders_above: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
top_aligned_terminals.sort_by(|a, b| a.get_x().cmp(&b.get_x()));
|
||||
@ -826,7 +905,7 @@ impl Tab {
|
||||
terminal_borders_below: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(&terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by(|a, b| b.get_x().cmp(&a.get_x()));
|
||||
// terminals that are next to each other up to current
|
||||
@ -865,7 +944,7 @@ impl Tab {
|
||||
terminal_borders_below: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.terminals.get(id).unwrap();
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(&terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by(|a, b| a.get_x().cmp(&b.get_x()));
|
||||
// terminals that are next to each other up to current
|
||||
@ -898,7 +977,7 @@ impl Tab {
|
||||
(right_resize_border, terminal_ids)
|
||||
}
|
||||
fn reduce_pane_height_down(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.reduce_height_down(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*id,
|
||||
@ -907,7 +986,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn reduce_pane_height_up(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.reduce_height_up(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*id,
|
||||
@ -916,7 +995,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn increase_pane_height_down(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.increase_height_down(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -925,7 +1004,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn increase_pane_height_up(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.increase_height_up(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -934,7 +1013,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn increase_pane_width_right(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.increase_width_right(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -943,7 +1022,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn increase_pane_width_left(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.increase_width_left(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -952,7 +1031,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn reduce_pane_width_right(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.reduce_width_right(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -961,7 +1040,7 @@ impl Tab {
|
||||
);
|
||||
}
|
||||
fn reduce_pane_width_left(&mut self, id: &RawFd, count: usize) {
|
||||
let terminal = self.terminals.get_mut(&id).unwrap();
|
||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||
terminal.reduce_width_left(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid,
|
||||
@ -976,8 +1055,8 @@ impl Tab {
|
||||
right_border_x: usize,
|
||||
) -> bool {
|
||||
let terminal = self
|
||||
.terminals
|
||||
.get(id)
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("could not find terminal to check between borders");
|
||||
terminal.get_x() >= left_border_x
|
||||
&& terminal.get_x() + terminal.get_columns() <= right_border_x
|
||||
@ -989,8 +1068,8 @@ impl Tab {
|
||||
bottom_border_y: usize,
|
||||
) -> bool {
|
||||
let terminal = self
|
||||
.terminals
|
||||
.get(id)
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("could not find terminal to check between borders");
|
||||
terminal.get_y() >= top_border_y
|
||||
&& terminal.get_y() + terminal.get_rows() <= bottom_border_y
|
||||
@ -1001,7 +1080,7 @@ impl Tab {
|
||||
.expect("can't reduce pane size up if there are no terminals below");
|
||||
let terminal_borders_below: HashSet<usize> = terminals_below
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_x())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
||||
.collect();
|
||||
let (left_resize_border, terminals_to_the_left) =
|
||||
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
||||
@ -1027,7 +1106,7 @@ impl Tab {
|
||||
.expect("can't reduce pane size down if there are no terminals above");
|
||||
let terminal_borders_above: HashSet<usize> = terminals_above
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_x())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
||||
.collect();
|
||||
let (left_resize_border, terminals_to_the_left) =
|
||||
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
||||
@ -1053,7 +1132,7 @@ impl Tab {
|
||||
.expect("can't reduce pane size right if there are no terminals to the left");
|
||||
let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_y())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
||||
.collect();
|
||||
let (top_resize_border, terminals_above) =
|
||||
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
||||
@ -1076,7 +1155,7 @@ impl Tab {
|
||||
.expect("can't reduce pane size left if there are no terminals to the right");
|
||||
let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_y())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
||||
.collect();
|
||||
let (top_resize_border, terminals_above) =
|
||||
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
||||
@ -1099,7 +1178,7 @@ impl Tab {
|
||||
.expect("can't increase pane size up if there are no terminals above");
|
||||
let terminal_borders_above: HashSet<usize> = terminals_above
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_x())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
||||
.collect();
|
||||
let (left_resize_border, terminals_to_the_left) =
|
||||
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
||||
@ -1125,7 +1204,7 @@ impl Tab {
|
||||
.expect("can't increase pane size down if there are no terminals below");
|
||||
let terminal_borders_below: HashSet<usize> = terminals_below
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_x())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
||||
.collect();
|
||||
let (left_resize_border, terminals_to_the_left) =
|
||||
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
||||
@ -1151,7 +1230,7 @@ impl Tab {
|
||||
.expect("can't increase pane size right if there are no terminals to the right");
|
||||
let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_y())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
||||
.collect();
|
||||
let (top_resize_border, terminals_above) =
|
||||
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
||||
@ -1174,7 +1253,7 @@ impl Tab {
|
||||
.expect("can't increase pane size right if there are no terminals to the right");
|
||||
let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left
|
||||
.iter()
|
||||
.map(|t| self.terminals.get(t).unwrap().get_y())
|
||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
||||
.collect();
|
||||
let (top_resize_border, terminals_above) =
|
||||
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
||||
@ -1192,19 +1271,31 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
fn panes_exist_above(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self.terminals.get(pane_id).expect("pane does not exist");
|
||||
let pane = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.get_y() > 0
|
||||
}
|
||||
fn panes_exist_below(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self.terminals.get(pane_id).expect("pane does not exist");
|
||||
let pane = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.get_y() + pane.get_rows() < self.full_screen_ws.rows
|
||||
}
|
||||
fn panes_exist_to_the_right(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self.terminals.get(pane_id).expect("pane does not exist");
|
||||
let pane = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.get_x() + pane.get_columns() < self.full_screen_ws.columns
|
||||
}
|
||||
fn panes_exist_to_the_left(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self.terminals.get(pane_id).expect("pane does not exist");
|
||||
let pane = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.get_x() > 0
|
||||
}
|
||||
pub fn resize_right(&mut self) {
|
||||
@ -1256,14 +1347,17 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
pub fn move_focus(&mut self) {
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
return;
|
||||
}
|
||||
let active_terminal_id = self.get_active_terminal_id().unwrap();
|
||||
let terminal_ids: Vec<RawFd> = self.terminals.keys().copied().collect(); // TODO: better, no allocations
|
||||
let terminal_ids: Vec<RawFd> = self
|
||||
.get_terminals()
|
||||
.filter_map(|(pid, _)| Some(pid))
|
||||
.collect(); // TODO: better, no allocations
|
||||
let first_terminal = terminal_ids.get(0).unwrap();
|
||||
let active_terminal_id_position = terminal_ids
|
||||
.iter()
|
||||
@ -1277,7 +1371,7 @@ impl Tab {
|
||||
self.render();
|
||||
}
|
||||
pub fn move_focus_left(&mut self) {
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
@ -1285,9 +1379,8 @@ impl Tab {
|
||||
}
|
||||
let active_terminal = self.get_active_terminal();
|
||||
if let Some(active) = active_terminal {
|
||||
let next_index = self
|
||||
.terminals
|
||||
.iter()
|
||||
let terminals = self.get_terminals();
|
||||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_left_of(&active) && c.horizontally_overlaps_with(&active)
|
||||
@ -1296,7 +1389,7 @@ impl Tab {
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(p) => {
|
||||
self.active_terminal = Some(*p);
|
||||
self.active_terminal = Some(p);
|
||||
}
|
||||
None => {
|
||||
self.active_terminal = Some(active.pid);
|
||||
@ -1308,7 +1401,7 @@ impl Tab {
|
||||
self.render();
|
||||
}
|
||||
pub fn move_focus_down(&mut self) {
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
@ -1316,9 +1409,8 @@ impl Tab {
|
||||
}
|
||||
let active_terminal = self.get_active_terminal();
|
||||
if let Some(active) = active_terminal {
|
||||
let next_index = self
|
||||
.terminals
|
||||
.iter()
|
||||
let terminals = self.get_terminals();
|
||||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_below(&active) && c.vertically_overlaps_with(&active)
|
||||
@ -1327,7 +1419,7 @@ impl Tab {
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(p) => {
|
||||
self.active_terminal = Some(*p);
|
||||
self.active_terminal = Some(p);
|
||||
}
|
||||
None => {
|
||||
self.active_terminal = Some(active.pid);
|
||||
@ -1339,7 +1431,7 @@ impl Tab {
|
||||
self.render();
|
||||
}
|
||||
pub fn move_focus_up(&mut self) {
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
@ -1347,9 +1439,8 @@ impl Tab {
|
||||
}
|
||||
let active_terminal = self.get_active_terminal();
|
||||
if let Some(active) = active_terminal {
|
||||
let next_index = self
|
||||
.terminals
|
||||
.iter()
|
||||
let terminals = self.get_terminals();
|
||||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_above(&active) && c.vertically_overlaps_with(&active)
|
||||
@ -1358,7 +1449,7 @@ impl Tab {
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(p) => {
|
||||
self.active_terminal = Some(*p);
|
||||
self.active_terminal = Some(p);
|
||||
}
|
||||
None => {
|
||||
self.active_terminal = Some(active.pid);
|
||||
@ -1370,7 +1461,7 @@ impl Tab {
|
||||
self.render();
|
||||
}
|
||||
pub fn move_focus_right(&mut self) {
|
||||
if self.terminals.is_empty() {
|
||||
if !self.has_terminal_panes() {
|
||||
return;
|
||||
}
|
||||
if self.fullscreen_is_active {
|
||||
@ -1378,9 +1469,8 @@ impl Tab {
|
||||
}
|
||||
let active_terminal = self.get_active_terminal();
|
||||
if let Some(active) = active_terminal {
|
||||
let next_index = self
|
||||
.terminals
|
||||
.iter()
|
||||
let terminals = self.get_terminals();
|
||||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_right_of(&active) && c.horizontally_overlaps_with(&active)
|
||||
@ -1389,7 +1479,7 @@ impl Tab {
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(p) => {
|
||||
self.active_terminal = Some(*p);
|
||||
self.active_terminal = Some(p);
|
||||
}
|
||||
None => {
|
||||
self.active_terminal = Some(active.pid);
|
||||
@ -1402,7 +1492,7 @@ impl Tab {
|
||||
}
|
||||
fn horizontal_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
||||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||
let terminal = self.terminals.get(t).unwrap();
|
||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||
borders.insert(terminal.get_y());
|
||||
borders.insert(terminal.get_y() + terminal.get_rows() + 1); // 1 for the border width
|
||||
borders
|
||||
@ -1410,14 +1500,14 @@ impl Tab {
|
||||
}
|
||||
fn vertical_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
||||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||
let terminal = self.terminals.get(t).unwrap();
|
||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||
borders.insert(terminal.get_x());
|
||||
borders.insert(terminal.get_x() + terminal.get_columns() + 1); // 1 for the border width
|
||||
borders
|
||||
})
|
||||
}
|
||||
fn terminals_to_the_left_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.terminals.get(&id) {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let upper_close_border = terminal.get_y();
|
||||
let lower_close_border = terminal.get_y() + terminal.get_rows() + 1;
|
||||
|
||||
@ -1440,7 +1530,7 @@ impl Tab {
|
||||
None
|
||||
}
|
||||
fn terminals_to_the_right_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.terminals.get(&id) {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let upper_close_border = terminal.get_y();
|
||||
let lower_close_border = terminal.get_y() + terminal.get_rows() + 1;
|
||||
|
||||
@ -1464,7 +1554,7 @@ impl Tab {
|
||||
None
|
||||
}
|
||||
fn terminals_above_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.terminals.get(&id) {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let left_close_border = terminal.get_x();
|
||||
let right_close_border = terminal.get_x() + terminal.get_columns() + 1;
|
||||
|
||||
@ -1487,7 +1577,7 @@ impl Tab {
|
||||
None
|
||||
}
|
||||
fn terminals_below_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.terminals.get(&id) {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let left_close_border = terminal.get_x();
|
||||
let right_close_border = terminal.get_x() + terminal.get_columns() + 1;
|
||||
|
||||
@ -1511,27 +1601,27 @@ impl Tab {
|
||||
}
|
||||
fn close_down_to_max_terminals(&mut self) {
|
||||
if let Some(max_panes) = self.max_panes {
|
||||
if self.terminals.len() >= max_panes {
|
||||
for _ in max_panes..=self.terminals.len() {
|
||||
let first_pid = *self.terminals.iter().next().unwrap().0;
|
||||
self.send_pty_instructions
|
||||
.send(PtyInstruction::ClosePane(first_pid))
|
||||
.unwrap();
|
||||
self.close_pane_without_rerender(first_pid); // TODO: do not render yet
|
||||
}
|
||||
let terminals = self.get_terminal_pane_ids();
|
||||
for pid in terminals.iter().skip(max_panes - 1) {
|
||||
self.send_pty_instructions
|
||||
.send(PtyInstruction::ClosePane(*pid))
|
||||
.unwrap();
|
||||
self.close_pane_without_rerender(*pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_pane_ids(&mut self) -> Vec<RawFd> {
|
||||
self.terminals.keys().copied().collect::<Vec<RawFd>>()
|
||||
pub fn get_terminal_pane_ids(&mut self) -> Vec<RawFd> {
|
||||
self.get_terminals()
|
||||
.filter_map(|(pid, _)| Some(pid))
|
||||
.collect()
|
||||
}
|
||||
pub fn close_pane(&mut self, id: RawFd) {
|
||||
if self.terminals.get(&id).is_some() {
|
||||
if self.panes.get(&PaneKind::Terminal(id)).is_some() {
|
||||
self.close_pane_without_rerender(id);
|
||||
}
|
||||
}
|
||||
pub fn close_pane_without_rerender(&mut self, id: RawFd) {
|
||||
if let Some(terminal_to_close) = &self.terminals.get(&id) {
|
||||
if let Some(terminal_to_close) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let terminal_to_close_width = terminal_to_close.get_columns();
|
||||
let terminal_to_close_height = terminal_to_close.get_rows();
|
||||
if let Some(terminals) = self.terminals_to_the_left_between_aligning_borders(id) {
|
||||
@ -1569,8 +1659,8 @@ impl Tab {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
self.terminals.remove(&id);
|
||||
if self.terminals.is_empty() {
|
||||
self.panes.remove(&PaneKind::Terminal(id));
|
||||
if !self.has_terminal_panes() {
|
||||
self.active_terminal = None;
|
||||
}
|
||||
}
|
||||
@ -1585,21 +1675,30 @@ impl Tab {
|
||||
}
|
||||
pub fn scroll_active_terminal_up(&mut self) {
|
||||
if let Some(active_terminal_id) = self.get_active_terminal_id() {
|
||||
let active_terminal = self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.scroll_up(1);
|
||||
self.render();
|
||||
}
|
||||
}
|
||||
pub fn scroll_active_terminal_down(&mut self) {
|
||||
if let Some(active_terminal_id) = self.get_active_terminal_id() {
|
||||
let active_terminal = self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.scroll_down(1);
|
||||
self.render();
|
||||
}
|
||||
}
|
||||
pub fn clear_active_terminal_scroll(&mut self) {
|
||||
if let Some(active_terminal_id) = self.get_active_terminal_id() {
|
||||
let active_terminal = self.terminals.get_mut(&active_terminal_id).unwrap();
|
||||
let active_terminal = self
|
||||
.panes
|
||||
.get_mut(&PaneKind::Terminal(active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.clear_scroll();
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,16 @@
|
||||
source: src/tests/integration/basic.rs
|
||||
expression: snapshot
|
||||
---
|
||||
line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $ █
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $
|
||||
────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
@ -21,4 +21,4 @@ line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbb
|
||||
line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $
|
||||
prompt $ │prompt $ █
|
||||
|
@ -2,14 +2,14 @@
|
||||
source: src/tests/integration/basic.rs
|
||||
expression: snapshot
|
||||
---
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $
|
||||
────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
|
@ -2,8 +2,18 @@
|
||||
source: src/tests/integration/basic.rs
|
||||
expression: snapshot
|
||||
---
|
||||
line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│█
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
a │line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $
|
||||
────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│█
|
||||
line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
@ -12,13 +22,3 @@ line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│
|
||||
prompt $ │
|
||||
────────────────────────────────────────────────────────────┼────────────────────────────────────────────────────────────
|
||||
line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb│line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
prompt $ │prompt $
|
||||
|
Loading…
Reference in New Issue
Block a user