mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-27 19:21:52 +03:00
fix(infra): make panes BTreeMap value Pane trait in preparation for the status bar (#124)
This commit is contained in:
parent
581e06bf8b
commit
f196726dab
@ -1,3 +1,4 @@
|
|||||||
|
use crate::tab::Pane;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub mod boundary_type {
|
pub mod boundary_type {
|
||||||
@ -371,7 +372,7 @@ impl Boundaries {
|
|||||||
boundary_characters: HashMap::new(),
|
boundary_characters: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn add_rect<R: Rect>(&mut self, rect: &R) {
|
pub fn add_rect(&mut self, rect: &Box<dyn Pane>) {
|
||||||
if self.rect_right_boundary_is_before_screen_edge(rect) {
|
if self.rect_right_boundary_is_before_screen_edge(rect) {
|
||||||
// let boundary_x_coords = self.rect_right_boundary_x_coords(rect);
|
// let boundary_x_coords = self.rect_right_boundary_x_coords(rect);
|
||||||
let boundary_x_coords = rect.right_boundary_x_coords();
|
let boundary_x_coords = rect.right_boundary_x_coords();
|
||||||
@ -428,20 +429,20 @@ impl Boundaries {
|
|||||||
}
|
}
|
||||||
vte_output
|
vte_output
|
||||||
}
|
}
|
||||||
fn rect_right_boundary_is_before_screen_edge<R: Rect>(&self, rect: &R) -> bool {
|
fn rect_right_boundary_is_before_screen_edge(&self, rect: &Box<dyn Pane>) -> bool {
|
||||||
rect.x() + rect.columns() < self.columns
|
rect.x() + rect.columns() < self.columns
|
||||||
}
|
}
|
||||||
fn rect_bottom_boundary_is_before_screen_edge<R: Rect>(&self, rect: &R) -> bool {
|
fn rect_bottom_boundary_is_before_screen_edge(&self, rect: &Box<dyn Pane>) -> bool {
|
||||||
rect.y() + rect.rows() < self.rows
|
rect.y() + rect.rows() < self.rows
|
||||||
}
|
}
|
||||||
fn rect_right_boundary_row_start<R: Rect>(&self, rect: &R) -> usize {
|
fn rect_right_boundary_row_start(&self, rect: &Box<dyn Pane>) -> usize {
|
||||||
if rect.y() == 0 {
|
if rect.y() == 0 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
rect.y() - 1
|
rect.y() - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn rect_right_boundary_row_end<R: Rect>(&self, rect: &R) -> usize {
|
fn rect_right_boundary_row_end(&self, rect: &Box<dyn Pane>) -> usize {
|
||||||
let rect_bottom_row = rect.y() + rect.rows();
|
let rect_bottom_row = rect.y() + rect.rows();
|
||||||
// we do this because unless we're on the screen edge, we'd like to go one extra row to
|
// we do this because unless we're on the screen edge, we'd like to go one extra row to
|
||||||
// connect to whatever boundary is beneath us
|
// connect to whatever boundary is beneath us
|
||||||
@ -451,14 +452,14 @@ impl Boundaries {
|
|||||||
rect_bottom_row + 1
|
rect_bottom_row + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn rect_bottom_boundary_col_start<R: Rect>(&self, rect: &R) -> usize {
|
fn rect_bottom_boundary_col_start(&self, rect: &Box<dyn Pane>) -> usize {
|
||||||
if rect.x() == 0 {
|
if rect.x() == 0 {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
rect.x() - 1
|
rect.x() - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn rect_bottom_boundary_col_end<R: Rect>(&self, rect: &R) -> usize {
|
fn rect_bottom_boundary_col_end(&self, rect: &Box<dyn Pane>) -> usize {
|
||||||
let rect_right_col = rect.x() + rect.columns();
|
let rect_right_col = rect.x() + rect.columns();
|
||||||
// we do this because unless we're on the screen edge, we'd like to go one extra column to
|
// we do this because unless we're on the screen edge, we'd like to go one extra column to
|
||||||
// connect to whatever boundary is right of us
|
// connect to whatever boundary is right of us
|
||||||
|
239
src/main.rs
239
src/main.rs
@ -163,14 +163,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||||||
) = sync_channel(0);
|
) = sync_channel(0);
|
||||||
let send_app_instructions =
|
let send_app_instructions =
|
||||||
SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions));
|
SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions));
|
||||||
let mut screen = Screen::new(
|
|
||||||
receive_screen_instructions,
|
|
||||||
send_pty_instructions.clone(),
|
|
||||||
send_app_instructions.clone(),
|
|
||||||
&full_screen_ws,
|
|
||||||
os_input.clone(),
|
|
||||||
opts.max_panes,
|
|
||||||
);
|
|
||||||
let mut pty_bus = PtyBus::new(
|
let mut pty_bus = PtyBus::new(
|
||||||
receive_pty_instructions,
|
receive_pty_instructions,
|
||||||
send_screen_instructions.clone(),
|
send_screen_instructions.clone(),
|
||||||
@ -193,6 +186,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||||||
.name("pty".to_string())
|
.name("pty".to_string())
|
||||||
.spawn({
|
.spawn({
|
||||||
let mut command_is_executing = command_is_executing.clone();
|
let mut command_is_executing = command_is_executing.clone();
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
if let Some(layout) = maybe_layout {
|
if let Some(layout) = maybe_layout {
|
||||||
pty_bus.spawn_terminals_for_layout(layout);
|
pty_bus.spawn_terminals_for_layout(layout);
|
||||||
@ -263,113 +257,128 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||||||
.name("screen".to_string())
|
.name("screen".to_string())
|
||||||
.spawn({
|
.spawn({
|
||||||
let mut command_is_executing = command_is_executing.clone();
|
let mut command_is_executing = command_is_executing.clone();
|
||||||
move || loop {
|
let os_input = os_input.clone();
|
||||||
let (event, mut err_ctx) = screen
|
let send_pty_instructions = send_pty_instructions.clone();
|
||||||
.receiver
|
let send_app_instructions = send_app_instructions.clone();
|
||||||
.recv()
|
let max_panes = opts.max_panes;
|
||||||
.expect("failed to receive event on channel");
|
|
||||||
err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event)));
|
move || {
|
||||||
screen.send_app_instructions.update(err_ctx);
|
let mut screen = Screen::new(
|
||||||
screen.send_pty_instructions.update(err_ctx);
|
receive_screen_instructions,
|
||||||
match event {
|
send_pty_instructions,
|
||||||
ScreenInstruction::Pty(pid, vte_event) => {
|
send_app_instructions,
|
||||||
screen
|
&full_screen_ws,
|
||||||
.get_active_tab_mut()
|
os_input,
|
||||||
.unwrap()
|
max_panes,
|
||||||
.handle_pty_event(pid, vte_event);
|
);
|
||||||
}
|
loop {
|
||||||
ScreenInstruction::Render => {
|
let (event, mut err_ctx) = screen
|
||||||
screen.render();
|
.receiver
|
||||||
}
|
.recv()
|
||||||
ScreenInstruction::NewPane(pid) => {
|
.expect("failed to receive event on channel");
|
||||||
screen.get_active_tab_mut().unwrap().new_pane(pid);
|
err_ctx.add_call(ContextType::Screen(ScreenContext::from(&event)));
|
||||||
command_is_executing.done_opening_new_pane();
|
screen.send_app_instructions.update(err_ctx);
|
||||||
}
|
screen.send_pty_instructions.update(err_ctx);
|
||||||
ScreenInstruction::HorizontalSplit(pid) => {
|
match event {
|
||||||
screen.get_active_tab_mut().unwrap().horizontal_split(pid);
|
ScreenInstruction::Pty(pid, vte_event) => {
|
||||||
command_is_executing.done_opening_new_pane();
|
screen
|
||||||
}
|
.get_active_tab_mut()
|
||||||
ScreenInstruction::VerticalSplit(pid) => {
|
.unwrap()
|
||||||
screen.get_active_tab_mut().unwrap().vertical_split(pid);
|
.handle_pty_event(pid, vte_event);
|
||||||
command_is_executing.done_opening_new_pane();
|
}
|
||||||
}
|
ScreenInstruction::Render => {
|
||||||
ScreenInstruction::WriteCharacter(bytes) => {
|
screen.render();
|
||||||
screen
|
}
|
||||||
.get_active_tab_mut()
|
ScreenInstruction::NewPane(pid) => {
|
||||||
.unwrap()
|
screen.get_active_tab_mut().unwrap().new_pane(pid);
|
||||||
.write_to_active_terminal(bytes);
|
command_is_executing.done_opening_new_pane();
|
||||||
}
|
}
|
||||||
ScreenInstruction::ResizeLeft => {
|
ScreenInstruction::HorizontalSplit(pid) => {
|
||||||
screen.get_active_tab_mut().unwrap().resize_left();
|
screen.get_active_tab_mut().unwrap().horizontal_split(pid);
|
||||||
}
|
command_is_executing.done_opening_new_pane();
|
||||||
ScreenInstruction::ResizeRight => {
|
}
|
||||||
screen.get_active_tab_mut().unwrap().resize_right();
|
ScreenInstruction::VerticalSplit(pid) => {
|
||||||
}
|
screen.get_active_tab_mut().unwrap().vertical_split(pid);
|
||||||
ScreenInstruction::ResizeDown => {
|
command_is_executing.done_opening_new_pane();
|
||||||
screen.get_active_tab_mut().unwrap().resize_down();
|
}
|
||||||
}
|
ScreenInstruction::WriteCharacter(bytes) => {
|
||||||
ScreenInstruction::ResizeUp => {
|
screen
|
||||||
screen.get_active_tab_mut().unwrap().resize_up();
|
.get_active_tab_mut()
|
||||||
}
|
.unwrap()
|
||||||
ScreenInstruction::MoveFocus => {
|
.write_to_active_terminal(bytes);
|
||||||
screen.get_active_tab_mut().unwrap().move_focus();
|
}
|
||||||
}
|
ScreenInstruction::ResizeLeft => {
|
||||||
ScreenInstruction::MoveFocusLeft => {
|
screen.get_active_tab_mut().unwrap().resize_left();
|
||||||
screen.get_active_tab_mut().unwrap().move_focus_left();
|
}
|
||||||
}
|
ScreenInstruction::ResizeRight => {
|
||||||
ScreenInstruction::MoveFocusDown => {
|
screen.get_active_tab_mut().unwrap().resize_right();
|
||||||
screen.get_active_tab_mut().unwrap().move_focus_down();
|
}
|
||||||
}
|
ScreenInstruction::ResizeDown => {
|
||||||
ScreenInstruction::MoveFocusRight => {
|
screen.get_active_tab_mut().unwrap().resize_down();
|
||||||
screen.get_active_tab_mut().unwrap().move_focus_right();
|
}
|
||||||
}
|
ScreenInstruction::ResizeUp => {
|
||||||
ScreenInstruction::MoveFocusUp => {
|
screen.get_active_tab_mut().unwrap().resize_up();
|
||||||
screen.get_active_tab_mut().unwrap().move_focus_up();
|
}
|
||||||
}
|
ScreenInstruction::MoveFocus => {
|
||||||
ScreenInstruction::ScrollUp => {
|
screen.get_active_tab_mut().unwrap().move_focus();
|
||||||
screen
|
}
|
||||||
.get_active_tab_mut()
|
ScreenInstruction::MoveFocusLeft => {
|
||||||
.unwrap()
|
screen.get_active_tab_mut().unwrap().move_focus_left();
|
||||||
.scroll_active_terminal_up();
|
}
|
||||||
}
|
ScreenInstruction::MoveFocusDown => {
|
||||||
ScreenInstruction::ScrollDown => {
|
screen.get_active_tab_mut().unwrap().move_focus_down();
|
||||||
screen
|
}
|
||||||
.get_active_tab_mut()
|
ScreenInstruction::MoveFocusRight => {
|
||||||
.unwrap()
|
screen.get_active_tab_mut().unwrap().move_focus_right();
|
||||||
.scroll_active_terminal_down();
|
}
|
||||||
}
|
ScreenInstruction::MoveFocusUp => {
|
||||||
ScreenInstruction::ClearScroll => {
|
screen.get_active_tab_mut().unwrap().move_focus_up();
|
||||||
screen
|
}
|
||||||
.get_active_tab_mut()
|
ScreenInstruction::ScrollUp => {
|
||||||
.unwrap()
|
screen
|
||||||
.clear_active_terminal_scroll();
|
.get_active_tab_mut()
|
||||||
}
|
.unwrap()
|
||||||
ScreenInstruction::CloseFocusedPane => {
|
.scroll_active_terminal_up();
|
||||||
screen.get_active_tab_mut().unwrap().close_focused_pane();
|
}
|
||||||
screen.render();
|
ScreenInstruction::ScrollDown => {
|
||||||
}
|
screen
|
||||||
ScreenInstruction::ClosePane(id) => {
|
.get_active_tab_mut()
|
||||||
screen.get_active_tab_mut().unwrap().close_pane(id);
|
.unwrap()
|
||||||
screen.render();
|
.scroll_active_terminal_down();
|
||||||
}
|
}
|
||||||
ScreenInstruction::ToggleActiveTerminalFullscreen => {
|
ScreenInstruction::ClearScroll => {
|
||||||
screen
|
screen
|
||||||
.get_active_tab_mut()
|
.get_active_tab_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.toggle_active_terminal_fullscreen();
|
.clear_active_terminal_scroll();
|
||||||
}
|
}
|
||||||
ScreenInstruction::NewTab(pane_id) => {
|
ScreenInstruction::CloseFocusedPane => {
|
||||||
screen.new_tab(pane_id);
|
screen.get_active_tab_mut().unwrap().close_focused_pane();
|
||||||
command_is_executing.done_opening_new_pane();
|
screen.render();
|
||||||
}
|
}
|
||||||
ScreenInstruction::SwitchTabNext => screen.switch_tab_next(),
|
ScreenInstruction::ClosePane(id) => {
|
||||||
ScreenInstruction::SwitchTabPrev => screen.switch_tab_prev(),
|
screen.get_active_tab_mut().unwrap().close_pane(id);
|
||||||
ScreenInstruction::CloseTab => screen.close_tab(),
|
screen.render();
|
||||||
ScreenInstruction::ApplyLayout((layout, new_pane_pids)) => {
|
}
|
||||||
screen.apply_layout(layout, new_pane_pids)
|
ScreenInstruction::ToggleActiveTerminalFullscreen => {
|
||||||
}
|
screen
|
||||||
ScreenInstruction::Quit => {
|
.get_active_tab_mut()
|
||||||
break;
|
.unwrap()
|
||||||
|
.toggle_active_terminal_fullscreen();
|
||||||
|
}
|
||||||
|
ScreenInstruction::NewTab(pane_id) => {
|
||||||
|
screen.new_tab(pane_id);
|
||||||
|
command_is_executing.done_opening_new_pane();
|
||||||
|
}
|
||||||
|
ScreenInstruction::SwitchTabNext => screen.switch_tab_next(),
|
||||||
|
ScreenInstruction::SwitchTabPrev => screen.switch_tab_prev(),
|
||||||
|
ScreenInstruction::CloseTab => screen.close_tab(),
|
||||||
|
ScreenInstruction::ApplyLayout((layout, new_pane_pids)) => {
|
||||||
|
screen.apply_layout(layout, new_pane_pids)
|
||||||
|
}
|
||||||
|
ScreenInstruction::Quit => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
354
src/tab.rs
354
src/tab.rs
@ -3,7 +3,6 @@ use std::io::Write;
|
|||||||
use std::os::unix::io::RawFd;
|
use std::os::unix::io::RawFd;
|
||||||
|
|
||||||
use crate::boundaries::Boundaries;
|
use crate::boundaries::Boundaries;
|
||||||
use crate::boundaries::Rect;
|
|
||||||
use crate::layout::Layout;
|
use crate::layout::Layout;
|
||||||
use crate::os_input_output::OsApi;
|
use crate::os_input_output::OsApi;
|
||||||
use crate::pty_bus::{PtyInstruction, VteEvent};
|
use crate::pty_bus::{PtyInstruction, VteEvent};
|
||||||
@ -56,7 +55,7 @@ enum PaneKind {
|
|||||||
}
|
}
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
panes: BTreeMap<PaneKind, TerminalPane>,
|
panes: BTreeMap<PaneKind, Box<dyn Pane>>,
|
||||||
panes_to_hide: HashSet<RawFd>,
|
panes_to_hide: HashSet<RawFd>,
|
||||||
active_terminal: Option<RawFd>,
|
active_terminal: Option<RawFd>,
|
||||||
max_panes: Option<usize>,
|
max_panes: Option<usize>,
|
||||||
@ -67,6 +66,82 @@ pub struct Tab {
|
|||||||
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Pane {
|
||||||
|
fn x(&self) -> usize;
|
||||||
|
fn y(&self) -> usize;
|
||||||
|
fn rows(&self) -> usize;
|
||||||
|
fn columns(&self) -> usize;
|
||||||
|
fn reset_size_and_position_override(&mut self);
|
||||||
|
fn change_size_p(&mut self, position_and_size: &PositionAndSize);
|
||||||
|
fn get_rows(&self) -> usize;
|
||||||
|
fn get_columns(&self) -> usize;
|
||||||
|
fn change_size(&mut self, ws: &PositionAndSize);
|
||||||
|
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize);
|
||||||
|
fn handle_event(&mut self, event: VteEvent);
|
||||||
|
fn cursor_coordinates(&self) -> Option<(usize, usize)>;
|
||||||
|
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8>;
|
||||||
|
|
||||||
|
fn position_and_size_override(&self) -> Option<PositionAndSize>;
|
||||||
|
fn should_render(&self) -> bool;
|
||||||
|
fn set_should_render(&mut self, should_render: bool);
|
||||||
|
fn buffer_as_vte_output(&mut self) -> Option<String>;
|
||||||
|
fn pid(&self) -> RawFd;
|
||||||
|
fn reduce_height_down(&mut self, count: usize);
|
||||||
|
fn increase_height_down(&mut self, count: usize);
|
||||||
|
fn increase_height_up(&mut self, count: usize);
|
||||||
|
fn reduce_height_up(&mut self, count: usize);
|
||||||
|
fn increase_width_right(&mut self, count: usize);
|
||||||
|
fn reduce_width_right(&mut self, count: usize);
|
||||||
|
fn reduce_width_left(&mut self, count: usize);
|
||||||
|
fn increase_width_left(&mut self, count: usize);
|
||||||
|
fn scroll_up(&mut self, count: usize);
|
||||||
|
fn scroll_down(&mut self, count: usize);
|
||||||
|
fn clear_scroll(&mut self);
|
||||||
|
|
||||||
|
fn right_boundary_x_coords(&self) -> usize {
|
||||||
|
self.x() + self.columns()
|
||||||
|
}
|
||||||
|
fn bottom_boundary_y_coords(&self) -> usize {
|
||||||
|
self.y() + self.rows()
|
||||||
|
}
|
||||||
|
fn is_directly_right_of(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
self.x() == other.x() + other.columns() + 1
|
||||||
|
}
|
||||||
|
fn is_directly_left_of(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
self.x() + self.columns() + 1 == other.x()
|
||||||
|
}
|
||||||
|
fn is_directly_below(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
self.y() == other.y() + other.rows() + 1
|
||||||
|
}
|
||||||
|
fn is_directly_above(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
self.y() + self.rows() + 1 == other.y()
|
||||||
|
}
|
||||||
|
fn horizontally_overlaps_with(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
(self.y() >= other.y() && self.y() <= (other.y() + other.rows()))
|
||||||
|
|| ((self.y() + self.rows()) <= (other.y() + other.rows())
|
||||||
|
&& (self.y() + self.rows()) > other.y())
|
||||||
|
|| (self.y() <= other.y() && (self.y() + self.rows() >= (other.y() + other.rows())))
|
||||||
|
|| (other.y() <= self.y() && (other.y() + other.rows() >= (self.y() + self.rows())))
|
||||||
|
}
|
||||||
|
fn get_horizontal_overlap_with(&self, other: &Box<dyn Pane>) -> usize {
|
||||||
|
std::cmp::min(self.y() + self.rows(), other.y() + other.rows())
|
||||||
|
- std::cmp::max(self.y(), other.y())
|
||||||
|
}
|
||||||
|
fn vertically_overlaps_with(&self, other: &Box<dyn Pane>) -> bool {
|
||||||
|
(self.x() >= other.x() && self.x() <= (other.x() + other.columns()))
|
||||||
|
|| ((self.x() + self.columns()) <= (other.x() + other.columns())
|
||||||
|
&& (self.x() + self.columns()) > other.x())
|
||||||
|
|| (self.x() <= other.x()
|
||||||
|
&& (self.x() + self.columns() >= (other.x() + other.columns())))
|
||||||
|
|| (other.x() <= self.x()
|
||||||
|
&& (other.x() + other.columns() >= (self.x() + self.columns())))
|
||||||
|
}
|
||||||
|
fn get_vertical_overlap_with(&self, other: &Box<dyn Pane>) -> usize {
|
||||||
|
std::cmp::min(self.x() + self.columns(), other.x() + other.columns())
|
||||||
|
- std::cmp::max(self.x(), other.x())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Tab {
|
impl Tab {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
index: usize,
|
index: usize,
|
||||||
@ -84,8 +159,8 @@ impl Tab {
|
|||||||
new_terminal.get_columns() as u16,
|
new_terminal.get_columns() as u16,
|
||||||
new_terminal.get_rows() as u16,
|
new_terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
let mut panes = BTreeMap::new();
|
let mut panes: BTreeMap<PaneKind, Box<dyn Pane>> = BTreeMap::new();
|
||||||
panes.insert(PaneKind::Terminal(pid), new_terminal);
|
panes.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
panes
|
panes
|
||||||
} else {
|
} else {
|
||||||
BTreeMap::new()
|
BTreeMap::new()
|
||||||
@ -152,7 +227,8 @@ impl Tab {
|
|||||||
new_terminal.get_columns() as u16,
|
new_terminal.get_columns() as u16,
|
||||||
new_terminal.get_rows() as u16,
|
new_terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
self.panes.insert(PaneKind::Terminal(*pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(*pid), Box::new(new_terminal));
|
||||||
}
|
}
|
||||||
for unused_pid in new_pids {
|
for unused_pid in new_pids {
|
||||||
// this is a bit of a hack and happens because we don't have any central location that
|
// this is a bit of a hack and happens because we don't have any central location that
|
||||||
@ -186,7 +262,8 @@ impl Tab {
|
|||||||
new_terminal.get_columns() as u16,
|
new_terminal.get_columns() as u16,
|
||||||
new_terminal.get_rows() as u16,
|
new_terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
} else {
|
} else {
|
||||||
// TODO: check minimum size of active terminal
|
// TODO: check minimum size of active terminal
|
||||||
@ -211,8 +288,8 @@ impl Tab {
|
|||||||
let terminal_ws = PositionAndSize {
|
let terminal_ws = PositionAndSize {
|
||||||
rows: terminal_to_split.get_rows(),
|
rows: terminal_to_split.get_rows(),
|
||||||
columns: terminal_to_split.get_columns(),
|
columns: terminal_to_split.get_columns(),
|
||||||
x: terminal_to_split.get_x(),
|
x: terminal_to_split.x(),
|
||||||
y: terminal_to_split.get_y(),
|
y: terminal_to_split.y(),
|
||||||
};
|
};
|
||||||
if terminal_to_split.get_rows() * CURSOR_HEIGHT_WIDTH_RATIO
|
if terminal_to_split.get_rows() * CURSOR_HEIGHT_WIDTH_RATIO
|
||||||
> terminal_to_split.get_columns()
|
> terminal_to_split.get_columns()
|
||||||
@ -227,7 +304,8 @@ impl Tab {
|
|||||||
bottom_winsize.rows as u16,
|
bottom_winsize.rows as u16,
|
||||||
);
|
);
|
||||||
terminal_to_split.change_size(&top_winsize);
|
terminal_to_split.change_size(&top_winsize);
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal_id_to_split,
|
terminal_id_to_split,
|
||||||
top_winsize.columns as u16,
|
top_winsize.columns as u16,
|
||||||
@ -245,7 +323,8 @@ impl Tab {
|
|||||||
right_winsize.rows as u16,
|
right_winsize.rows as u16,
|
||||||
);
|
);
|
||||||
terminal_to_split.change_size(&left_winszie);
|
terminal_to_split.change_size(&left_winszie);
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal_id_to_split,
|
terminal_id_to_split,
|
||||||
left_winszie.columns as u16,
|
left_winszie.columns as u16,
|
||||||
@ -270,7 +349,8 @@ impl Tab {
|
|||||||
new_terminal.get_columns() as u16,
|
new_terminal.get_columns() as u16,
|
||||||
new_terminal.get_rows() as u16,
|
new_terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
} else {
|
} else {
|
||||||
// TODO: check minimum size of active terminal
|
// TODO: check minimum size of active terminal
|
||||||
@ -283,8 +363,8 @@ impl Tab {
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
},
|
},
|
||||||
active_terminal.get_x(),
|
active_terminal.x(),
|
||||||
active_terminal.get_y(),
|
active_terminal.y(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&active_terminal_ws);
|
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&active_terminal_ws);
|
||||||
@ -306,7 +386,8 @@ impl Tab {
|
|||||||
active_terminal.change_size(&top_winsize);
|
active_terminal.change_size(&top_winsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
active_terminal_pid,
|
active_terminal_pid,
|
||||||
@ -331,7 +412,8 @@ impl Tab {
|
|||||||
new_terminal.get_columns() as u16,
|
new_terminal.get_columns() as u16,
|
||||||
new_terminal.get_rows() as u16,
|
new_terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
self.active_terminal = Some(pid);
|
self.active_terminal = Some(pid);
|
||||||
} else {
|
} else {
|
||||||
// TODO: check minimum size of active terminal
|
// TODO: check minimum size of active terminal
|
||||||
@ -344,8 +426,8 @@ impl Tab {
|
|||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
},
|
},
|
||||||
active_terminal.get_x(),
|
active_terminal.x(),
|
||||||
active_terminal.get_y(),
|
active_terminal.y(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let (left_winszie, right_winsize) = split_vertically_with_gap(&active_terminal_ws);
|
let (left_winszie, right_winsize) = split_vertically_with_gap(&active_terminal_ws);
|
||||||
@ -367,7 +449,8 @@ impl Tab {
|
|||||||
active_terminal.change_size(&left_winszie);
|
active_terminal.change_size(&left_winszie);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.panes.insert(PaneKind::Terminal(pid), new_terminal);
|
self.panes
|
||||||
|
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||||
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
let active_terminal_pid = self.get_active_terminal_id().unwrap();
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
active_terminal_pid,
|
active_terminal_pid,
|
||||||
@ -378,22 +461,14 @@ impl Tab {
|
|||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_active_terminal(&self) -> Option<&TerminalPane> {
|
pub fn get_active_terminal(&self) -> Option<&Box<dyn Pane>> {
|
||||||
match self.active_terminal {
|
match self.active_terminal {
|
||||||
Some(active_terminal) => self.panes.get(&PaneKind::Terminal(active_terminal)),
|
Some(active_terminal) => self.panes.get(&PaneKind::Terminal(active_terminal)),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_active_terminal_id(&self) -> Option<RawFd> {
|
fn get_active_terminal_id(&self) -> Option<RawFd> {
|
||||||
match self.active_terminal {
|
self.active_terminal
|
||||||
Some(active_terminal) => Some(
|
|
||||||
self.panes
|
|
||||||
.get(&PaneKind::Terminal(active_terminal))
|
|
||||||
.unwrap()
|
|
||||||
.pid,
|
|
||||||
),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn handle_pty_event(&mut self, pid: RawFd, event: VteEvent) {
|
pub fn handle_pty_event(&mut self, pid: RawFd, event: VteEvent) {
|
||||||
// if we don't have the terminal in self.terminals it's probably because
|
// if we don't have the terminal in self.terminals it's probably because
|
||||||
@ -423,8 +498,8 @@ impl Tab {
|
|||||||
active_terminal
|
active_terminal
|
||||||
.cursor_coordinates()
|
.cursor_coordinates()
|
||||||
.map(|(x_in_terminal, y_in_terminal)| {
|
.map(|(x_in_terminal, y_in_terminal)| {
|
||||||
let x = active_terminal.get_x() + x_in_terminal;
|
let x = active_terminal.x() + x_in_terminal;
|
||||||
let y = active_terminal.get_y() + y_in_terminal;
|
let y = active_terminal.y() + y_in_terminal;
|
||||||
(x, y)
|
(x, y)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -433,14 +508,14 @@ impl Tab {
|
|||||||
if self
|
if self
|
||||||
.get_active_terminal()
|
.get_active_terminal()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.position_and_size_override
|
.position_and_size_override()
|
||||||
.is_some()
|
.is_some()
|
||||||
{
|
{
|
||||||
for terminal_id in self.panes_to_hide.iter() {
|
for terminal_id in self.panes_to_hide.iter() {
|
||||||
self.panes
|
self.panes
|
||||||
.get_mut(&PaneKind::Terminal(*terminal_id))
|
.get_mut(&PaneKind::Terminal(*terminal_id))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.should_render = true;
|
.set_should_render(true);
|
||||||
}
|
}
|
||||||
self.panes_to_hide.clear();
|
self.panes_to_hide.clear();
|
||||||
let active_terminal = self
|
let active_terminal = self
|
||||||
@ -540,7 +615,7 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_terminals(&self) -> impl Iterator<Item = (RawFd, &TerminalPane)> {
|
fn get_terminals(&self) -> impl Iterator<Item = (RawFd, &Box<dyn Pane>)> {
|
||||||
self.panes
|
self.panes
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(pane_kind, terminal_pane)| match pane_kind {
|
.filter_map(|(pane_kind, terminal_pane)| match pane_kind {
|
||||||
@ -555,11 +630,11 @@ impl Tab {
|
|||||||
fn terminal_ids_directly_left_of(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
fn terminal_ids_directly_left_of(&self, id: &RawFd) -> Option<Vec<RawFd>> {
|
||||||
let mut ids = vec![];
|
let mut ids = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||||
if terminal_to_check.get_x() == 0 {
|
if terminal_to_check.x() == 0 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
for (pid, terminal) in self.get_terminals() {
|
for (pid, terminal) in self.get_terminals() {
|
||||||
if terminal.get_x() + terminal.get_columns() == terminal_to_check.get_x() - 1 {
|
if terminal.x() + terminal.get_columns() == terminal_to_check.x() - 1 {
|
||||||
ids.push(pid);
|
ids.push(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,7 +648,7 @@ impl Tab {
|
|||||||
let mut ids = vec![];
|
let mut ids = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||||
for (pid, terminal) in self.get_terminals() {
|
for (pid, terminal) in self.get_terminals() {
|
||||||
if terminal.get_x() == terminal_to_check.get_x() + terminal_to_check.get_columns() + 1 {
|
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||||
ids.push(pid);
|
ids.push(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,7 +662,7 @@ impl Tab {
|
|||||||
let mut ids = vec![];
|
let mut ids = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||||
for (pid, terminal) in self.get_terminals() {
|
for (pid, terminal) in self.get_terminals() {
|
||||||
if terminal.get_y() == terminal_to_check.get_y() + terminal_to_check.get_rows() + 1 {
|
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||||
ids.push(pid);
|
ids.push(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,7 +676,7 @@ impl Tab {
|
|||||||
let mut ids = vec![];
|
let mut ids = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||||
for (pid, terminal) in self.get_terminals() {
|
for (pid, terminal) in self.get_terminals() {
|
||||||
if terminal.get_y() + terminal.get_rows() + 1 == terminal_to_check.get_y() {
|
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||||
ids.push(pid);
|
ids.push(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -611,39 +686,38 @@ impl Tab {
|
|||||||
Some(ids)
|
Some(ids)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn panes_top_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
fn panes_top_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||||
self.panes
|
self.panes
|
||||||
.keys()
|
.keys()
|
||||||
.map(|t_id| self.panes.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())
|
.filter(|terminal| terminal.pid() != pane.pid() && terminal.y() == pane.y())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
fn panes_bottom_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
fn panes_bottom_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||||
self.panes
|
self.panes
|
||||||
.keys()
|
.keys()
|
||||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||||
.filter(|terminal| {
|
.filter(|terminal| {
|
||||||
terminal.pid != pane.pid
|
terminal.pid() != pane.pid()
|
||||||
&& terminal.get_y() + terminal.get_rows() == pane.get_y() + pane.get_rows()
|
&& terminal.y() + terminal.get_rows() == pane.y() + pane.get_rows()
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
fn panes_right_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
fn panes_right_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||||
self.panes
|
self.panes
|
||||||
.keys()
|
.keys()
|
||||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||||
.filter(|terminal| {
|
.filter(|terminal| {
|
||||||
terminal.pid != pane.pid
|
terminal.pid() != pane.pid()
|
||||||
&& terminal.get_x() + terminal.get_columns()
|
&& terminal.x() + terminal.get_columns() == pane.x() + pane.get_columns()
|
||||||
== pane.get_x() + pane.get_columns()
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
fn panes_left_aligned_with_pane(&self, pane: &TerminalPane) -> Vec<&TerminalPane> {
|
fn panes_left_aligned_with_pane(&self, pane: &&Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||||
self.panes
|
self.panes
|
||||||
.keys()
|
.keys()
|
||||||
.map(|t_id| self.panes.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())
|
.filter(|terminal| terminal.pid() != pane.pid() && terminal.x() == pane.x())
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
fn right_aligned_contiguous_panes_above(
|
fn right_aligned_contiguous_panes_above(
|
||||||
@ -658,17 +732,17 @@ impl Tab {
|
|||||||
.expect("terminal id does not exist");
|
.expect("terminal id does not exist");
|
||||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
right_aligned_terminals.sort_by(|a, b| b.get_y().cmp(&a.get_y()));
|
right_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||||
for terminal in right_aligned_terminals {
|
for terminal in right_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_y() + terminal.get_rows() + 1 == terminal_to_check.get_y() {
|
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// top-most border aligned with a pane border to the right
|
// top-most border aligned with a pane border to the right
|
||||||
let mut top_resize_border = 0;
|
let mut top_resize_border = 0;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let bottom_terminal_boundary = terminal.get_y() + terminal.get_rows();
|
let bottom_terminal_boundary = terminal.y() + terminal.get_rows();
|
||||||
if terminal_borders_to_the_right
|
if terminal_borders_to_the_right
|
||||||
.get(&(bottom_terminal_boundary + 1))
|
.get(&(bottom_terminal_boundary + 1))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -677,15 +751,15 @@ impl Tab {
|
|||||||
top_resize_border = bottom_terminal_boundary + 1;
|
top_resize_border = bottom_terminal_boundary + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| terminal.get_y() >= top_resize_border);
|
terminals.retain(|terminal| terminal.y() >= top_resize_border);
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let top_resize_border = if terminals.is_empty() {
|
let top_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_y()
|
terminal_to_check.y()
|
||||||
} else {
|
} else {
|
||||||
top_resize_border
|
top_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(top_resize_border, terminal_ids)
|
(top_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn right_aligned_contiguous_panes_below(
|
fn right_aligned_contiguous_panes_below(
|
||||||
@ -700,17 +774,17 @@ impl Tab {
|
|||||||
.expect("terminal id does not exist");
|
.expect("terminal id does not exist");
|
||||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
right_aligned_terminals.sort_by(|a, b| a.get_y().cmp(&b.get_y()));
|
right_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||||
for terminal in right_aligned_terminals {
|
for terminal in right_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_y() == terminal_to_check.get_y() + terminal_to_check.get_rows() + 1 {
|
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// bottom-most border aligned with a pane border to the right
|
// bottom-most border aligned with a pane border to the right
|
||||||
let mut bottom_resize_border = self.full_screen_ws.rows;
|
let mut bottom_resize_border = self.full_screen_ws.rows;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let top_terminal_boundary = terminal.get_y();
|
let top_terminal_boundary = terminal.y();
|
||||||
if terminal_borders_to_the_right
|
if terminal_borders_to_the_right
|
||||||
.get(&(top_terminal_boundary))
|
.get(&(top_terminal_boundary))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -719,15 +793,15 @@ impl Tab {
|
|||||||
bottom_resize_border = top_terminal_boundary;
|
bottom_resize_border = top_terminal_boundary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| terminal.get_y() + terminal.get_rows() <= bottom_resize_border);
|
terminals.retain(|terminal| terminal.y() + terminal.get_rows() <= bottom_resize_border);
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let bottom_resize_border = if terminals.is_empty() {
|
let bottom_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_y() + terminal_to_check.get_rows()
|
terminal_to_check.y() + terminal_to_check.get_rows()
|
||||||
} else {
|
} else {
|
||||||
bottom_resize_border
|
bottom_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(bottom_resize_border, terminal_ids)
|
(bottom_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn left_aligned_contiguous_panes_above(
|
fn left_aligned_contiguous_panes_above(
|
||||||
@ -742,17 +816,17 @@ impl Tab {
|
|||||||
.expect("terminal id does not exist");
|
.expect("terminal id does not exist");
|
||||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
left_aligned_terminals.sort_by(|a, b| b.get_y().cmp(&a.get_y()));
|
left_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||||
for terminal in left_aligned_terminals {
|
for terminal in left_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_y() + terminal.get_rows() + 1 == terminal_to_check.get_y() {
|
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// top-most border aligned with a pane border to the right
|
// top-most border aligned with a pane border to the right
|
||||||
let mut top_resize_border = 0;
|
let mut top_resize_border = 0;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let bottom_terminal_boundary = terminal.get_y() + terminal.get_rows();
|
let bottom_terminal_boundary = terminal.y() + terminal.get_rows();
|
||||||
if terminal_borders_to_the_left
|
if terminal_borders_to_the_left
|
||||||
.get(&(bottom_terminal_boundary + 1))
|
.get(&(bottom_terminal_boundary + 1))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -761,15 +835,15 @@ impl Tab {
|
|||||||
top_resize_border = bottom_terminal_boundary + 1;
|
top_resize_border = bottom_terminal_boundary + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| terminal.get_y() >= top_resize_border);
|
terminals.retain(|terminal| terminal.y() >= top_resize_border);
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let top_resize_border = if terminals.is_empty() {
|
let top_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_y()
|
terminal_to_check.y()
|
||||||
} else {
|
} else {
|
||||||
top_resize_border
|
top_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(top_resize_border, terminal_ids)
|
(top_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn left_aligned_contiguous_panes_below(
|
fn left_aligned_contiguous_panes_below(
|
||||||
@ -784,17 +858,17 @@ impl Tab {
|
|||||||
.expect("terminal id does not exist");
|
.expect("terminal id does not exist");
|
||||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
left_aligned_terminals.sort_by(|a, b| a.get_y().cmp(&b.get_y()));
|
left_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||||
for terminal in left_aligned_terminals {
|
for terminal in left_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_y() == terminal_to_check.get_y() + terminal_to_check.get_rows() + 1 {
|
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// bottom-most border aligned with a pane border to the left
|
// bottom-most border aligned with a pane border to the left
|
||||||
let mut bottom_resize_border = self.full_screen_ws.rows;
|
let mut bottom_resize_border = self.full_screen_ws.rows;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let top_terminal_boundary = terminal.get_y();
|
let top_terminal_boundary = terminal.y();
|
||||||
if terminal_borders_to_the_left
|
if terminal_borders_to_the_left
|
||||||
.get(&(top_terminal_boundary))
|
.get(&(top_terminal_boundary))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -804,17 +878,17 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| {
|
terminals.retain(|terminal| {
|
||||||
// terminal.get_y() + terminal.get_rows() < bottom_resize_border
|
// terminal.y() + terminal.get_rows() < bottom_resize_border
|
||||||
terminal.get_y() + terminal.get_rows() <= bottom_resize_border
|
terminal.y() + terminal.get_rows() <= bottom_resize_border
|
||||||
});
|
});
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let bottom_resize_border = if terminals.is_empty() {
|
let bottom_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_y() + terminal_to_check.get_rows()
|
terminal_to_check.y() + terminal_to_check.get_rows()
|
||||||
} else {
|
} else {
|
||||||
bottom_resize_border
|
bottom_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(bottom_resize_border, terminal_ids)
|
(bottom_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn top_aligned_contiguous_panes_to_the_left(
|
fn top_aligned_contiguous_panes_to_the_left(
|
||||||
@ -829,17 +903,17 @@ impl Tab {
|
|||||||
.expect("terminal id does not exist");
|
.expect("terminal id does not exist");
|
||||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
top_aligned_terminals.sort_by(|a, b| b.get_x().cmp(&a.get_x()));
|
top_aligned_terminals.sort_by(|a, b| b.x().cmp(&a.x()));
|
||||||
for terminal in top_aligned_terminals {
|
for terminal in top_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_x() + terminal.get_columns() + 1 == terminal_to_check.get_x() {
|
if terminal.x() + terminal.get_columns() + 1 == terminal_to_check.x() {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// leftmost border aligned with a pane border above
|
// leftmost border aligned with a pane border above
|
||||||
let mut left_resize_border = 0;
|
let mut left_resize_border = 0;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let right_terminal_boundary = terminal.get_x() + terminal.get_columns();
|
let right_terminal_boundary = terminal.x() + terminal.get_columns();
|
||||||
if terminal_borders_above
|
if terminal_borders_above
|
||||||
.get(&(right_terminal_boundary + 1))
|
.get(&(right_terminal_boundary + 1))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -848,15 +922,15 @@ impl Tab {
|
|||||||
left_resize_border = right_terminal_boundary + 1;
|
left_resize_border = right_terminal_boundary + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| terminal.get_x() >= left_resize_border);
|
terminals.retain(|terminal| terminal.x() >= left_resize_border);
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let left_resize_border = if terminals.is_empty() {
|
let left_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_x()
|
terminal_to_check.x()
|
||||||
} else {
|
} else {
|
||||||
left_resize_border
|
left_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(left_resize_border, terminal_ids)
|
(left_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn top_aligned_contiguous_panes_to_the_right(
|
fn top_aligned_contiguous_panes_to_the_right(
|
||||||
@ -868,17 +942,17 @@ impl Tab {
|
|||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*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);
|
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
top_aligned_terminals.sort_by(|a, b| a.get_x().cmp(&b.get_x()));
|
top_aligned_terminals.sort_by(|a, b| a.x().cmp(&b.x()));
|
||||||
for terminal in top_aligned_terminals {
|
for terminal in top_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_x() == terminal_to_check.get_x() + terminal_to_check.get_columns() + 1 {
|
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// rightmost border aligned with a pane border above
|
// rightmost border aligned with a pane border above
|
||||||
let mut right_resize_border = self.full_screen_ws.columns;
|
let mut right_resize_border = self.full_screen_ws.columns;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let left_terminal_boundary = terminal.get_x();
|
let left_terminal_boundary = terminal.x();
|
||||||
if terminal_borders_above
|
if terminal_borders_above
|
||||||
.get(&left_terminal_boundary)
|
.get(&left_terminal_boundary)
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -887,16 +961,15 @@ impl Tab {
|
|||||||
right_resize_border = left_terminal_boundary;
|
right_resize_border = left_terminal_boundary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals
|
terminals.retain(|terminal| terminal.x() + terminal.get_columns() <= right_resize_border);
|
||||||
.retain(|terminal| terminal.get_x() + terminal.get_columns() <= right_resize_border);
|
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let right_resize_border = if terminals.is_empty() {
|
let right_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_x() + terminal_to_check.get_columns()
|
terminal_to_check.x() + terminal_to_check.get_columns()
|
||||||
} else {
|
} else {
|
||||||
right_resize_border
|
right_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(right_resize_border, terminal_ids)
|
(right_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn bottom_aligned_contiguous_panes_to_the_left(
|
fn bottom_aligned_contiguous_panes_to_the_left(
|
||||||
@ -907,18 +980,18 @@ impl Tab {
|
|||||||
let mut terminals = vec![];
|
let mut terminals = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*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);
|
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()));
|
bottom_aligned_terminals.sort_by(|a, b| b.x().cmp(&a.x()));
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
for terminal in bottom_aligned_terminals {
|
for terminal in bottom_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_x() + terminal.get_columns() + 1 == terminal_to_check.get_x() {
|
if terminal.x() + terminal.get_columns() + 1 == terminal_to_check.x() {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// leftmost border aligned with a pane border above
|
// leftmost border aligned with a pane border above
|
||||||
let mut left_resize_border = 0;
|
let mut left_resize_border = 0;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let right_terminal_boundary = terminal.get_x() + terminal.get_columns();
|
let right_terminal_boundary = terminal.x() + terminal.get_columns();
|
||||||
if terminal_borders_below
|
if terminal_borders_below
|
||||||
.get(&(right_terminal_boundary + 1))
|
.get(&(right_terminal_boundary + 1))
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -927,15 +1000,15 @@ impl Tab {
|
|||||||
left_resize_border = right_terminal_boundary + 1;
|
left_resize_border = right_terminal_boundary + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals.retain(|terminal| terminal.get_x() >= left_resize_border);
|
terminals.retain(|terminal| terminal.x() >= left_resize_border);
|
||||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||||
// resizing
|
// resizing
|
||||||
let left_resize_border = if terminals.is_empty() {
|
let left_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_x()
|
terminal_to_check.x()
|
||||||
} else {
|
} else {
|
||||||
left_resize_border
|
left_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(left_resize_border, terminal_ids)
|
(left_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn bottom_aligned_contiguous_panes_to_the_right(
|
fn bottom_aligned_contiguous_panes_to_the_right(
|
||||||
@ -946,18 +1019,18 @@ impl Tab {
|
|||||||
let mut terminals = vec![];
|
let mut terminals = vec![];
|
||||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*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);
|
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()));
|
bottom_aligned_terminals.sort_by(|a, b| a.x().cmp(&b.x()));
|
||||||
// terminals that are next to each other up to current
|
// terminals that are next to each other up to current
|
||||||
for terminal in bottom_aligned_terminals {
|
for terminal in bottom_aligned_terminals {
|
||||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||||
if terminal.get_x() == terminal_to_check.get_x() + terminal_to_check.get_columns() + 1 {
|
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||||
terminals.push(terminal);
|
terminals.push(terminal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// leftmost border aligned with a pane border above
|
// leftmost border aligned with a pane border above
|
||||||
let mut right_resize_border = self.full_screen_ws.columns;
|
let mut right_resize_border = self.full_screen_ws.columns;
|
||||||
for terminal in &terminals {
|
for terminal in &terminals {
|
||||||
let left_terminal_boundary = terminal.get_x();
|
let left_terminal_boundary = terminal.x();
|
||||||
if terminal_borders_below
|
if terminal_borders_below
|
||||||
.get(&left_terminal_boundary)
|
.get(&left_terminal_boundary)
|
||||||
.is_some()
|
.is_some()
|
||||||
@ -966,14 +1039,13 @@ impl Tab {
|
|||||||
right_resize_border = left_terminal_boundary;
|
right_resize_border = left_terminal_boundary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminals
|
terminals.retain(|terminal| terminal.x() + terminal.get_columns() <= right_resize_border);
|
||||||
.retain(|terminal| terminal.get_x() + terminal.get_columns() <= right_resize_border);
|
|
||||||
let right_resize_border = if terminals.is_empty() {
|
let right_resize_border = if terminals.is_empty() {
|
||||||
terminal_to_check.get_x() + terminal_to_check.get_columns()
|
terminal_to_check.x() + terminal_to_check.get_columns()
|
||||||
} else {
|
} else {
|
||||||
right_resize_border
|
right_resize_border
|
||||||
};
|
};
|
||||||
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid).collect();
|
let terminal_ids: Vec<RawFd> = terminals.iter().map(|t| t.pid()).collect();
|
||||||
(right_resize_border, terminal_ids)
|
(right_resize_border, terminal_ids)
|
||||||
}
|
}
|
||||||
fn reduce_pane_height_down(&mut self, id: &RawFd, count: usize) {
|
fn reduce_pane_height_down(&mut self, id: &RawFd, count: usize) {
|
||||||
@ -998,7 +1070,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.increase_height_down(count);
|
terminal.increase_height_down(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1007,7 +1079,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.increase_height_up(count);
|
terminal.increase_height_up(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1016,7 +1088,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.increase_width_right(count);
|
terminal.increase_width_right(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1025,7 +1097,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.increase_width_left(count);
|
terminal.increase_width_left(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1034,7 +1106,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.reduce_width_right(count);
|
terminal.reduce_width_right(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1043,7 +1115,7 @@ impl Tab {
|
|||||||
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
let terminal = self.panes.get_mut(&PaneKind::Terminal(*id)).unwrap();
|
||||||
terminal.reduce_width_left(count);
|
terminal.reduce_width_left(count);
|
||||||
self.os_api.set_terminal_size_using_fd(
|
self.os_api.set_terminal_size_using_fd(
|
||||||
terminal.pid,
|
terminal.pid(),
|
||||||
terminal.get_columns() as u16,
|
terminal.get_columns() as u16,
|
||||||
terminal.get_rows() as u16,
|
terminal.get_rows() as u16,
|
||||||
);
|
);
|
||||||
@ -1058,8 +1130,7 @@ impl Tab {
|
|||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*id))
|
.get(&PaneKind::Terminal(*id))
|
||||||
.expect("could not find terminal to check between borders");
|
.expect("could not find terminal to check between borders");
|
||||||
terminal.get_x() >= left_border_x
|
terminal.x() >= left_border_x && terminal.x() + terminal.get_columns() <= right_border_x
|
||||||
&& terminal.get_x() + terminal.get_columns() <= right_border_x
|
|
||||||
}
|
}
|
||||||
fn pane_is_between_horizontal_borders(
|
fn pane_is_between_horizontal_borders(
|
||||||
&self,
|
&self,
|
||||||
@ -1071,8 +1142,7 @@ impl Tab {
|
|||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*id))
|
.get(&PaneKind::Terminal(*id))
|
||||||
.expect("could not find terminal to check between borders");
|
.expect("could not find terminal to check between borders");
|
||||||
terminal.get_y() >= top_border_y
|
terminal.y() >= top_border_y && terminal.y() + terminal.get_rows() <= bottom_border_y
|
||||||
&& terminal.get_y() + terminal.get_rows() <= bottom_border_y
|
|
||||||
}
|
}
|
||||||
fn reduce_pane_and_surroundings_up(&mut self, id: &RawFd, count: usize) {
|
fn reduce_pane_and_surroundings_up(&mut self, id: &RawFd, count: usize) {
|
||||||
let mut terminals_below = self
|
let mut terminals_below = self
|
||||||
@ -1080,7 +1150,7 @@ impl Tab {
|
|||||||
.expect("can't reduce pane size up if there are no terminals below");
|
.expect("can't reduce pane size up if there are no terminals below");
|
||||||
let terminal_borders_below: HashSet<usize> = terminals_below
|
let terminal_borders_below: HashSet<usize> = terminals_below
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().x())
|
||||||
.collect();
|
.collect();
|
||||||
let (left_resize_border, terminals_to_the_left) =
|
let (left_resize_border, terminals_to_the_left) =
|
||||||
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
||||||
@ -1106,7 +1176,7 @@ impl Tab {
|
|||||||
.expect("can't reduce pane size down if there are no terminals above");
|
.expect("can't reduce pane size down if there are no terminals above");
|
||||||
let terminal_borders_above: HashSet<usize> = terminals_above
|
let terminal_borders_above: HashSet<usize> = terminals_above
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().x())
|
||||||
.collect();
|
.collect();
|
||||||
let (left_resize_border, terminals_to_the_left) =
|
let (left_resize_border, terminals_to_the_left) =
|
||||||
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
||||||
@ -1132,7 +1202,7 @@ impl Tab {
|
|||||||
.expect("can't reduce pane size right if there are no terminals to the left");
|
.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
|
let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().y())
|
||||||
.collect();
|
.collect();
|
||||||
let (top_resize_border, terminals_above) =
|
let (top_resize_border, terminals_above) =
|
||||||
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
||||||
@ -1155,7 +1225,7 @@ impl Tab {
|
|||||||
.expect("can't reduce pane size left if there are no terminals to the right");
|
.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
|
let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().y())
|
||||||
.collect();
|
.collect();
|
||||||
let (top_resize_border, terminals_above) =
|
let (top_resize_border, terminals_above) =
|
||||||
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
||||||
@ -1178,7 +1248,7 @@ impl Tab {
|
|||||||
.expect("can't increase pane size up if there are no terminals above");
|
.expect("can't increase pane size up if there are no terminals above");
|
||||||
let terminal_borders_above: HashSet<usize> = terminals_above
|
let terminal_borders_above: HashSet<usize> = terminals_above
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().x())
|
||||||
.collect();
|
.collect();
|
||||||
let (left_resize_border, terminals_to_the_left) =
|
let (left_resize_border, terminals_to_the_left) =
|
||||||
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
self.top_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_above);
|
||||||
@ -1204,7 +1274,7 @@ impl Tab {
|
|||||||
.expect("can't increase pane size down if there are no terminals below");
|
.expect("can't increase pane size down if there are no terminals below");
|
||||||
let terminal_borders_below: HashSet<usize> = terminals_below
|
let terminal_borders_below: HashSet<usize> = terminals_below
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_x())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().x())
|
||||||
.collect();
|
.collect();
|
||||||
let (left_resize_border, terminals_to_the_left) =
|
let (left_resize_border, terminals_to_the_left) =
|
||||||
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
self.bottom_aligned_contiguous_panes_to_the_left(&id, &terminal_borders_below);
|
||||||
@ -1230,7 +1300,7 @@ impl Tab {
|
|||||||
.expect("can't increase pane size right if there are no terminals to the right");
|
.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
|
let terminal_borders_to_the_right: HashSet<usize> = terminals_to_the_right
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().y())
|
||||||
.collect();
|
.collect();
|
||||||
let (top_resize_border, terminals_above) =
|
let (top_resize_border, terminals_above) =
|
||||||
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
self.right_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_right);
|
||||||
@ -1253,7 +1323,7 @@ impl Tab {
|
|||||||
.expect("can't increase pane size right if there are no terminals to the right");
|
.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
|
let terminal_borders_to_the_left: HashSet<usize> = terminals_to_the_left
|
||||||
.iter()
|
.iter()
|
||||||
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().get_y())
|
.map(|t| self.panes.get(&PaneKind::Terminal(*t)).unwrap().y())
|
||||||
.collect();
|
.collect();
|
||||||
let (top_resize_border, terminals_above) =
|
let (top_resize_border, terminals_above) =
|
||||||
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
self.left_aligned_contiguous_panes_above(&id, &terminal_borders_to_the_left);
|
||||||
@ -1275,28 +1345,28 @@ impl Tab {
|
|||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*pane_id))
|
.get(&PaneKind::Terminal(*pane_id))
|
||||||
.expect("pane does not exist");
|
.expect("pane does not exist");
|
||||||
pane.get_y() > 0
|
pane.y() > 0
|
||||||
}
|
}
|
||||||
fn panes_exist_below(&self, pane_id: &RawFd) -> bool {
|
fn panes_exist_below(&self, pane_id: &RawFd) -> bool {
|
||||||
let pane = self
|
let pane = self
|
||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*pane_id))
|
.get(&PaneKind::Terminal(*pane_id))
|
||||||
.expect("pane does not exist");
|
.expect("pane does not exist");
|
||||||
pane.get_y() + pane.get_rows() < self.full_screen_ws.rows
|
pane.y() + pane.get_rows() < self.full_screen_ws.rows
|
||||||
}
|
}
|
||||||
fn panes_exist_to_the_right(&self, pane_id: &RawFd) -> bool {
|
fn panes_exist_to_the_right(&self, pane_id: &RawFd) -> bool {
|
||||||
let pane = self
|
let pane = self
|
||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*pane_id))
|
.get(&PaneKind::Terminal(*pane_id))
|
||||||
.expect("pane does not exist");
|
.expect("pane does not exist");
|
||||||
pane.get_x() + pane.get_columns() < self.full_screen_ws.columns
|
pane.x() + pane.get_columns() < self.full_screen_ws.columns
|
||||||
}
|
}
|
||||||
fn panes_exist_to_the_left(&self, pane_id: &RawFd) -> bool {
|
fn panes_exist_to_the_left(&self, pane_id: &RawFd) -> bool {
|
||||||
let pane = self
|
let pane = self
|
||||||
.panes
|
.panes
|
||||||
.get(&PaneKind::Terminal(*pane_id))
|
.get(&PaneKind::Terminal(*pane_id))
|
||||||
.expect("pane does not exist");
|
.expect("pane does not exist");
|
||||||
pane.get_x() > 0
|
pane.x() > 0
|
||||||
}
|
}
|
||||||
pub fn resize_right(&mut self) {
|
pub fn resize_right(&mut self) {
|
||||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||||
@ -1392,11 +1462,11 @@ impl Tab {
|
|||||||
self.active_terminal = Some(p);
|
self.active_terminal = Some(p);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.active_terminal = Some(active.pid);
|
self.active_terminal = Some(active.pid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.active_terminal = Some(active_terminal.unwrap().pid);
|
self.active_terminal = Some(active_terminal.unwrap().pid());
|
||||||
}
|
}
|
||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
@ -1422,11 +1492,11 @@ impl Tab {
|
|||||||
self.active_terminal = Some(p);
|
self.active_terminal = Some(p);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.active_terminal = Some(active.pid);
|
self.active_terminal = Some(active.pid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.active_terminal = Some(active_terminal.unwrap().pid);
|
self.active_terminal = Some(active_terminal.unwrap().pid());
|
||||||
}
|
}
|
||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
@ -1452,11 +1522,11 @@ impl Tab {
|
|||||||
self.active_terminal = Some(p);
|
self.active_terminal = Some(p);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.active_terminal = Some(active.pid);
|
self.active_terminal = Some(active.pid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.active_terminal = Some(active_terminal.unwrap().pid);
|
self.active_terminal = Some(active_terminal.unwrap().pid());
|
||||||
}
|
}
|
||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
@ -1482,34 +1552,34 @@ impl Tab {
|
|||||||
self.active_terminal = Some(p);
|
self.active_terminal = Some(p);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.active_terminal = Some(active.pid);
|
self.active_terminal = Some(active.pid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.active_terminal = Some(active_terminal.unwrap().pid);
|
self.active_terminal = Some(active_terminal.unwrap().pid());
|
||||||
}
|
}
|
||||||
self.render();
|
self.render();
|
||||||
}
|
}
|
||||||
fn horizontal_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
fn horizontal_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
||||||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||||
borders.insert(terminal.get_y());
|
borders.insert(terminal.y());
|
||||||
borders.insert(terminal.get_y() + terminal.get_rows() + 1); // 1 for the border width
|
borders.insert(terminal.y() + terminal.get_rows() + 1); // 1 for the border width
|
||||||
borders
|
borders
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn vertical_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
fn vertical_borders(&self, terminals: &[RawFd]) -> HashSet<usize> {
|
||||||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||||
borders.insert(terminal.get_x());
|
borders.insert(terminal.x());
|
||||||
borders.insert(terminal.get_x() + terminal.get_columns() + 1); // 1 for the border width
|
borders.insert(terminal.x() + terminal.get_columns() + 1); // 1 for the border width
|
||||||
borders
|
borders
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn terminals_to_the_left_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
fn terminals_to_the_left_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||||
let upper_close_border = terminal.get_y();
|
let upper_close_border = terminal.y();
|
||||||
let lower_close_border = terminal.get_y() + terminal.get_rows() + 1;
|
let lower_close_border = terminal.y() + terminal.get_rows() + 1;
|
||||||
|
|
||||||
if let Some(mut terminals_to_the_left) = self.terminal_ids_directly_left_of(&id) {
|
if let Some(mut terminals_to_the_left) = self.terminal_ids_directly_left_of(&id) {
|
||||||
let terminal_borders_to_the_left = self.horizontal_borders(&terminals_to_the_left);
|
let terminal_borders_to_the_left = self.horizontal_borders(&terminals_to_the_left);
|
||||||
@ -1531,8 +1601,8 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
fn terminals_to_the_right_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
fn terminals_to_the_right_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||||
let upper_close_border = terminal.get_y();
|
let upper_close_border = terminal.y();
|
||||||
let lower_close_border = terminal.get_y() + terminal.get_rows() + 1;
|
let lower_close_border = terminal.y() + terminal.get_rows() + 1;
|
||||||
|
|
||||||
if let Some(mut terminals_to_the_right) = self.terminal_ids_directly_right_of(&id) {
|
if let Some(mut terminals_to_the_right) = self.terminal_ids_directly_right_of(&id) {
|
||||||
let terminal_borders_to_the_right =
|
let terminal_borders_to_the_right =
|
||||||
@ -1555,8 +1625,8 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
fn terminals_above_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
fn terminals_above_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||||
let left_close_border = terminal.get_x();
|
let left_close_border = terminal.x();
|
||||||
let right_close_border = terminal.get_x() + terminal.get_columns() + 1;
|
let right_close_border = terminal.x() + terminal.get_columns() + 1;
|
||||||
|
|
||||||
if let Some(mut terminals_above) = self.terminal_ids_directly_above(&id) {
|
if let Some(mut terminals_above) = self.terminal_ids_directly_above(&id) {
|
||||||
let terminal_borders_above = self.vertical_borders(&terminals_above);
|
let terminal_borders_above = self.vertical_borders(&terminals_above);
|
||||||
@ -1578,8 +1648,8 @@ impl Tab {
|
|||||||
}
|
}
|
||||||
fn terminals_below_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
fn terminals_below_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||||
let left_close_border = terminal.get_x();
|
let left_close_border = terminal.x();
|
||||||
let right_close_border = terminal.get_x() + terminal.get_columns() + 1;
|
let right_close_border = terminal.x() + terminal.get_columns() + 1;
|
||||||
|
|
||||||
if let Some(mut terminals_below) = self.terminal_ids_directly_below(&id) {
|
if let Some(mut terminals_below) = self.terminal_ids_directly_below(&id) {
|
||||||
let terminal_borders_below = self.vertical_borders(&terminals_below);
|
let terminal_borders_below = self.vertical_borders(&terminals_below);
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#![allow(clippy::clippy::if_same_then_else)]
|
#![allow(clippy::clippy::if_same_then_else)]
|
||||||
|
|
||||||
|
use crate::tab::Pane;
|
||||||
use ::nix::pty::Winsize;
|
use ::nix::pty::Winsize;
|
||||||
use ::std::os::unix::io::RawFd;
|
use ::std::os::unix::io::RawFd;
|
||||||
use ::vte::Perform;
|
use ::vte::Perform;
|
||||||
|
|
||||||
use crate::boundaries::Rect;
|
use crate::terminal_pane::terminal_character::{CharacterStyles, NamedColor, TerminalCharacter};
|
||||||
use crate::terminal_pane::terminal_character::{
|
|
||||||
AnsiCode, CharacterStyles, NamedColor, TerminalCharacter,
|
|
||||||
};
|
|
||||||
use crate::terminal_pane::Scroll;
|
use crate::terminal_pane::Scroll;
|
||||||
use crate::utils::logging::debug_log_to_file;
|
use crate::utils::logging::debug_log_to_file;
|
||||||
use crate::VteEvent;
|
use crate::VteEvent;
|
||||||
@ -42,7 +40,7 @@ pub struct TerminalPane {
|
|||||||
pending_styles: CharacterStyles,
|
pending_styles: CharacterStyles,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect for TerminalPane {
|
impl Pane for TerminalPane {
|
||||||
fn x(&self) -> usize {
|
fn x(&self) -> usize {
|
||||||
self.get_x()
|
self.get_x()
|
||||||
}
|
}
|
||||||
@ -55,9 +53,234 @@ impl Rect for TerminalPane {
|
|||||||
fn columns(&self) -> usize {
|
fn columns(&self) -> usize {
|
||||||
self.get_columns()
|
self.get_columns()
|
||||||
}
|
}
|
||||||
|
fn reset_size_and_position_override(&mut self) {
|
||||||
|
self.position_and_size_override = None;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn change_size_p(&mut self, position_and_size: &PositionAndSize) {
|
||||||
|
self.position_and_size = *position_and_size;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn get_rows(&self) -> usize {
|
||||||
|
match &self.position_and_size_override.as_ref() {
|
||||||
|
Some(position_and_size_override) => position_and_size_override.rows,
|
||||||
|
None => self.position_and_size.rows as usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_columns(&self) -> usize {
|
||||||
|
match &self.position_and_size_override.as_ref() {
|
||||||
|
Some(position_and_size_override) => position_and_size_override.columns,
|
||||||
|
None => self.position_and_size.columns as usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn change_size(&mut self, ws: &PositionAndSize) {
|
||||||
|
self.position_and_size.columns = ws.columns;
|
||||||
|
self.position_and_size.rows = ws.rows;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
|
||||||
|
let position_and_size_override = PositionAndSize {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
rows: size.rows,
|
||||||
|
columns: size.columns,
|
||||||
|
};
|
||||||
|
self.position_and_size_override = Some(position_and_size_override);
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn handle_event(&mut self, event: VteEvent) {
|
||||||
|
match event {
|
||||||
|
VteEvent::Print(c) => {
|
||||||
|
self.print(c);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
VteEvent::Execute(byte) => {
|
||||||
|
self.execute(byte);
|
||||||
|
}
|
||||||
|
VteEvent::Hook(params, intermediates, ignore, c) => {
|
||||||
|
self.hook(¶ms, &intermediates, ignore, c);
|
||||||
|
}
|
||||||
|
VteEvent::Put(byte) => {
|
||||||
|
self.put(byte);
|
||||||
|
}
|
||||||
|
VteEvent::Unhook => {
|
||||||
|
self.unhook();
|
||||||
|
}
|
||||||
|
VteEvent::OscDispatch(params, bell_terminated) => {
|
||||||
|
let params: Vec<&[u8]> = params.iter().map(|p| &p[..]).collect();
|
||||||
|
self.osc_dispatch(¶ms[..], bell_terminated);
|
||||||
|
}
|
||||||
|
VteEvent::CsiDispatch(params, intermediates, ignore, c) => {
|
||||||
|
self.csi_dispatch(¶ms, &intermediates, ignore, c);
|
||||||
|
}
|
||||||
|
VteEvent::EscDispatch(intermediates, ignore, byte) => {
|
||||||
|
self.esc_dispatch(&intermediates, ignore, byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn cursor_coordinates(&self) -> Option<(usize, usize)> {
|
||||||
|
// (x, y)
|
||||||
|
self.scroll.cursor_coordinates_on_screen()
|
||||||
|
}
|
||||||
|
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8> {
|
||||||
|
// there are some cases in which the terminal state means that input sent to it
|
||||||
|
// needs to be adjusted.
|
||||||
|
// here we match against those cases - if need be, we adjust the input and if not
|
||||||
|
// we send back the original input
|
||||||
|
match input_bytes.as_slice() {
|
||||||
|
[27, 91, 68] => {
|
||||||
|
// left arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OD".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 67] => {
|
||||||
|
// right arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OC".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 65] => {
|
||||||
|
// up arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OA".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 66] => {
|
||||||
|
// down arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OB".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
input_bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
||||||
|
self.position_and_size_override
|
||||||
|
}
|
||||||
|
fn should_render(&self) -> bool {
|
||||||
|
self.should_render
|
||||||
|
}
|
||||||
|
fn set_should_render(&mut self, should_render: bool) {
|
||||||
|
self.should_render = should_render;
|
||||||
|
}
|
||||||
|
fn buffer_as_vte_output(&mut self) -> Option<String> {
|
||||||
|
// TODO: rename to render
|
||||||
|
// if self.should_render {
|
||||||
|
if true {
|
||||||
|
// while checking should_render rather than rendering each pane every time
|
||||||
|
// is more performant, it causes some problems when the pane to the left should be
|
||||||
|
// rendered and has wide characters (eg. Chinese characters or emoji)
|
||||||
|
// as a (hopefully) temporary hack, we render all panes until we find a better solution
|
||||||
|
let mut vte_output = String::new();
|
||||||
|
let buffer_lines = &self.read_buffer_as_lines();
|
||||||
|
let display_cols = self.get_columns();
|
||||||
|
let mut character_styles = CharacterStyles::new();
|
||||||
|
for (row, line) in buffer_lines.iter().enumerate() {
|
||||||
|
let x = self.get_x();
|
||||||
|
let y = self.get_y();
|
||||||
|
vte_output = format!("{}\u{1b}[{};{}H\u{1b}[m", vte_output, y + row + 1, x + 1); // goto row/col and reset styles
|
||||||
|
for (col, t_character) in line.iter().enumerate() {
|
||||||
|
if col < display_cols {
|
||||||
|
// in some cases (eg. while resizing) some characters will spill over
|
||||||
|
// before they are corrected by the shell (for the prompt) or by reflowing
|
||||||
|
// lines
|
||||||
|
if let Some(new_styles) =
|
||||||
|
character_styles.update_and_return_diff(&t_character.styles)
|
||||||
|
{
|
||||||
|
// the terminal keeps the previous styles as long as we're in the same
|
||||||
|
// line, so we only want to update the new styles here (this also
|
||||||
|
// includes resetting previous styles as needed)
|
||||||
|
vte_output = format!("{}{}", vte_output, new_styles);
|
||||||
|
}
|
||||||
|
vte_output.push(t_character.character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
character_styles.clear();
|
||||||
|
}
|
||||||
|
self.mark_for_rerender();
|
||||||
|
Some(vte_output)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pid(&self) -> RawFd {
|
||||||
|
self.pid
|
||||||
|
}
|
||||||
|
fn reduce_height_down(&mut self, count: usize) {
|
||||||
|
self.position_and_size.y += count;
|
||||||
|
self.position_and_size.rows -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_height_down(&mut self, count: usize) {
|
||||||
|
self.position_and_size.rows += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_height_up(&mut self, count: usize) {
|
||||||
|
self.position_and_size.y -= count;
|
||||||
|
self.position_and_size.rows += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_height_up(&mut self, count: usize) {
|
||||||
|
self.position_and_size.rows -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_width_right(&mut self, count: usize) {
|
||||||
|
self.position_and_size.x += count;
|
||||||
|
self.position_and_size.columns -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_width_left(&mut self, count: usize) {
|
||||||
|
self.position_and_size.columns -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_width_left(&mut self, count: usize) {
|
||||||
|
self.position_and_size.x -= count;
|
||||||
|
self.position_and_size.columns += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_width_right(&mut self, count: usize) {
|
||||||
|
self.position_and_size.columns += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn scroll_up(&mut self, count: usize) {
|
||||||
|
self.scroll.move_viewport_up(count);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn scroll_down(&mut self, count: usize) {
|
||||||
|
self.scroll.move_viewport_down(count);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn clear_scroll(&mut self) {
|
||||||
|
self.scroll.reset_viewport();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rect for &mut TerminalPane {
|
impl Pane for &mut TerminalPane {
|
||||||
fn x(&self) -> usize {
|
fn x(&self) -> usize {
|
||||||
self.get_x()
|
self.get_x()
|
||||||
}
|
}
|
||||||
@ -70,6 +293,231 @@ impl Rect for &mut TerminalPane {
|
|||||||
fn columns(&self) -> usize {
|
fn columns(&self) -> usize {
|
||||||
self.get_columns()
|
self.get_columns()
|
||||||
}
|
}
|
||||||
|
fn reset_size_and_position_override(&mut self) {
|
||||||
|
self.position_and_size_override = None;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn change_size_p(&mut self, position_and_size: &PositionAndSize) {
|
||||||
|
self.position_and_size = *position_and_size;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn get_rows(&self) -> usize {
|
||||||
|
match &self.position_and_size_override.as_ref() {
|
||||||
|
Some(position_and_size_override) => position_and_size_override.rows,
|
||||||
|
None => self.position_and_size.rows as usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_columns(&self) -> usize {
|
||||||
|
match &self.position_and_size_override.as_ref() {
|
||||||
|
Some(position_and_size_override) => position_and_size_override.columns,
|
||||||
|
None => self.position_and_size.columns as usize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn change_size(&mut self, ws: &PositionAndSize) {
|
||||||
|
self.position_and_size.columns = ws.columns;
|
||||||
|
self.position_and_size.rows = ws.rows;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
|
||||||
|
let position_and_size_override = PositionAndSize {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
rows: size.rows,
|
||||||
|
columns: size.columns,
|
||||||
|
};
|
||||||
|
self.position_and_size_override = Some(position_and_size_override);
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn handle_event(&mut self, event: VteEvent) {
|
||||||
|
match event {
|
||||||
|
VteEvent::Print(c) => {
|
||||||
|
self.print(c);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
VteEvent::Execute(byte) => {
|
||||||
|
self.execute(byte);
|
||||||
|
}
|
||||||
|
VteEvent::Hook(params, intermediates, ignore, c) => {
|
||||||
|
self.hook(¶ms, &intermediates, ignore, c);
|
||||||
|
}
|
||||||
|
VteEvent::Put(byte) => {
|
||||||
|
self.put(byte);
|
||||||
|
}
|
||||||
|
VteEvent::Unhook => {
|
||||||
|
self.unhook();
|
||||||
|
}
|
||||||
|
VteEvent::OscDispatch(params, bell_terminated) => {
|
||||||
|
let params: Vec<&[u8]> = params.iter().map(|p| &p[..]).collect();
|
||||||
|
self.osc_dispatch(¶ms[..], bell_terminated);
|
||||||
|
}
|
||||||
|
VteEvent::CsiDispatch(params, intermediates, ignore, c) => {
|
||||||
|
self.csi_dispatch(¶ms, &intermediates, ignore, c);
|
||||||
|
}
|
||||||
|
VteEvent::EscDispatch(intermediates, ignore, byte) => {
|
||||||
|
self.esc_dispatch(&intermediates, ignore, byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn cursor_coordinates(&self) -> Option<(usize, usize)> {
|
||||||
|
// (x, y)
|
||||||
|
self.scroll.cursor_coordinates_on_screen()
|
||||||
|
}
|
||||||
|
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8> {
|
||||||
|
// there are some cases in which the terminal state means that input sent to it
|
||||||
|
// needs to be adjusted.
|
||||||
|
// here we match against those cases - if need be, we adjust the input and if not
|
||||||
|
// we send back the original input
|
||||||
|
match input_bytes.as_slice() {
|
||||||
|
[27, 91, 68] => {
|
||||||
|
// left arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OD".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 67] => {
|
||||||
|
// right arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OC".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 65] => {
|
||||||
|
// up arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OA".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[27, 91, 66] => {
|
||||||
|
// down arrow
|
||||||
|
if self.cursor_key_mode {
|
||||||
|
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
||||||
|
// some editors will not show this
|
||||||
|
return "OB".as_bytes().to_vec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
input_bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
||||||
|
self.position_and_size_override
|
||||||
|
}
|
||||||
|
fn should_render(&self) -> bool {
|
||||||
|
self.should_render
|
||||||
|
}
|
||||||
|
fn set_should_render(&mut self, should_render: bool) {
|
||||||
|
self.should_render = should_render;
|
||||||
|
}
|
||||||
|
fn buffer_as_vte_output(&mut self) -> Option<String> {
|
||||||
|
// TODO: rename to render
|
||||||
|
// if self.should_render {
|
||||||
|
if true {
|
||||||
|
// while checking should_render rather than rendering each pane every time
|
||||||
|
// is more performant, it causes some problems when the pane to the left should be
|
||||||
|
// rendered and has wide characters (eg. Chinese characters or emoji)
|
||||||
|
// as a (hopefully) temporary hack, we render all panes until we find a better solution
|
||||||
|
let mut vte_output = String::new();
|
||||||
|
let buffer_lines = &self.read_buffer_as_lines();
|
||||||
|
let display_cols = self.get_columns();
|
||||||
|
let mut character_styles = CharacterStyles::new();
|
||||||
|
for (row, line) in buffer_lines.iter().enumerate() {
|
||||||
|
let x = self.get_x();
|
||||||
|
let y = self.get_y();
|
||||||
|
vte_output = format!("{}\u{1b}[{};{}H\u{1b}[m", vte_output, y + row + 1, x + 1); // goto row/col and reset styles
|
||||||
|
for (col, t_character) in line.iter().enumerate() {
|
||||||
|
if col < display_cols {
|
||||||
|
// in some cases (eg. while resizing) some characters will spill over
|
||||||
|
// before they are corrected by the shell (for the prompt) or by reflowing
|
||||||
|
// lines
|
||||||
|
if let Some(new_styles) =
|
||||||
|
character_styles.update_and_return_diff(&t_character.styles)
|
||||||
|
{
|
||||||
|
// the terminal keeps the previous styles as long as we're in the same
|
||||||
|
// line, so we only want to update the new styles here (this also
|
||||||
|
// includes resetting previous styles as needed)
|
||||||
|
vte_output = format!("{}{}", vte_output, new_styles);
|
||||||
|
}
|
||||||
|
vte_output.push(t_character.character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
character_styles.clear();
|
||||||
|
}
|
||||||
|
self.mark_for_rerender();
|
||||||
|
Some(vte_output)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn pid(&self) -> RawFd {
|
||||||
|
self.pid
|
||||||
|
}
|
||||||
|
fn reduce_height_down(&mut self, count: usize) {
|
||||||
|
self.position_and_size.y += count;
|
||||||
|
self.position_and_size.rows -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_height_down(&mut self, count: usize) {
|
||||||
|
self.position_and_size.rows += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_height_up(&mut self, count: usize) {
|
||||||
|
self.position_and_size.y -= count;
|
||||||
|
self.position_and_size.rows += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_height_up(&mut self, count: usize) {
|
||||||
|
self.position_and_size.rows -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_width_right(&mut self, count: usize) {
|
||||||
|
self.position_and_size.x += count;
|
||||||
|
self.position_and_size.columns -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn reduce_width_left(&mut self, count: usize) {
|
||||||
|
self.position_and_size.columns -= count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_width_left(&mut self, count: usize) {
|
||||||
|
self.position_and_size.x -= count;
|
||||||
|
self.position_and_size.columns += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn increase_width_right(&mut self, count: usize) {
|
||||||
|
self.position_and_size.columns += count;
|
||||||
|
self.reflow_lines();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn scroll_up(&mut self, count: usize) {
|
||||||
|
self.scroll.move_viewport_up(count);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn scroll_down(&mut self, count: usize) {
|
||||||
|
self.scroll.move_viewport_down(count);
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
|
fn clear_scroll(&mut self) {
|
||||||
|
self.scroll.reset_viewport();
|
||||||
|
self.mark_for_rerender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalPane {
|
impl TerminalPane {
|
||||||
@ -125,55 +573,6 @@ impl TerminalPane {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn reduce_width_right(&mut self, count: usize) {
|
|
||||||
self.position_and_size.x += count;
|
|
||||||
self.position_and_size.columns -= count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn reduce_width_left(&mut self, count: usize) {
|
|
||||||
self.position_and_size.columns -= count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn increase_width_left(&mut self, count: usize) {
|
|
||||||
self.position_and_size.x -= count;
|
|
||||||
self.position_and_size.columns += count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn increase_width_right(&mut self, count: usize) {
|
|
||||||
self.position_and_size.columns += count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn reduce_height_down(&mut self, count: usize) {
|
|
||||||
self.position_and_size.y += count;
|
|
||||||
self.position_and_size.rows -= count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn increase_height_down(&mut self, count: usize) {
|
|
||||||
self.position_and_size.rows += count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn increase_height_up(&mut self, count: usize) {
|
|
||||||
self.position_and_size.y -= count;
|
|
||||||
self.position_and_size.rows += count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn reduce_height_up(&mut self, count: usize) {
|
|
||||||
self.position_and_size.rows -= count;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn change_size_p(&mut self, position_and_size: &PositionAndSize) {
|
|
||||||
self.position_and_size = *position_and_size;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
// TODO: merge these two methods
|
// TODO: merge these two methods
|
||||||
pub fn change_size(&mut self, ws: &PositionAndSize) {
|
pub fn change_size(&mut self, ws: &PositionAndSize) {
|
||||||
self.position_and_size.columns = ws.columns;
|
self.position_and_size.columns = ws.columns;
|
||||||
@ -288,53 +687,7 @@ impl TerminalPane {
|
|||||||
self.reflow_lines();
|
self.reflow_lines();
|
||||||
self.mark_for_rerender();
|
self.mark_for_rerender();
|
||||||
}
|
}
|
||||||
pub fn reset_size_and_position_override(&mut self) {
|
|
||||||
self.position_and_size_override = None;
|
|
||||||
self.reflow_lines();
|
|
||||||
self.mark_for_rerender();
|
|
||||||
}
|
|
||||||
pub fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8> {
|
|
||||||
// there are some cases in which the terminal state means that input sent to it
|
|
||||||
// needs to be adjusted.
|
|
||||||
// here we match against those cases - if need be, we adjust the input and if not
|
|
||||||
// we send back the original input
|
|
||||||
match input_bytes.as_slice() {
|
|
||||||
[27, 91, 68] => {
|
|
||||||
// left arrow
|
|
||||||
if self.cursor_key_mode {
|
|
||||||
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
|
||||||
// some editors will not show this
|
|
||||||
return "OD".as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[27, 91, 67] => {
|
|
||||||
// right arrow
|
|
||||||
if self.cursor_key_mode {
|
|
||||||
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
|
||||||
// some editors will not show this
|
|
||||||
return "OC".as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[27, 91, 65] => {
|
|
||||||
// up arrow
|
|
||||||
if self.cursor_key_mode {
|
|
||||||
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
|
||||||
// some editors will not show this
|
|
||||||
return "OA".as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[27, 91, 66] => {
|
|
||||||
// down arrow
|
|
||||||
if self.cursor_key_mode {
|
|
||||||
// please note that in the line below, there is an ANSI escape code (27) at the beginning of the string,
|
|
||||||
// some editors will not show this
|
|
||||||
return "OB".as_bytes().to_vec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
input_bytes
|
|
||||||
}
|
|
||||||
fn add_newline(&mut self) {
|
fn add_newline(&mut self) {
|
||||||
self.scroll.add_canonical_line();
|
self.scroll.add_canonical_line();
|
||||||
// self.reset_all_ansi_codes(); // TODO: find out if we should be resetting here or not
|
// self.reset_all_ansi_codes(); // TODO: find out if we should be resetting here or not
|
||||||
|
Loading…
Reference in New Issue
Block a user