Get clipped, fool
This commit is contained in:
parent
4a176669fa
commit
1fa23e6fa4
11 changed files with 139 additions and 117 deletions
|
|
@ -372,7 +372,7 @@ impl Boundaries {
|
|||
boundary_characters: HashMap::new(),
|
||||
}
|
||||
}
|
||||
pub fn add_rect(&mut self, rect: &Box<dyn Pane>) {
|
||||
pub fn add_rect(&mut self, rect: &dyn Pane) {
|
||||
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 = rect.right_boundary_x_coords();
|
||||
|
|
@ -429,20 +429,20 @@ impl Boundaries {
|
|||
}
|
||||
vte_output
|
||||
}
|
||||
fn rect_right_boundary_is_before_screen_edge(&self, rect: &Box<dyn Pane>) -> bool {
|
||||
fn rect_right_boundary_is_before_screen_edge(&self, rect: &dyn Pane) -> bool {
|
||||
rect.x() + rect.columns() < self.columns
|
||||
}
|
||||
fn rect_bottom_boundary_is_before_screen_edge(&self, rect: &Box<dyn Pane>) -> bool {
|
||||
fn rect_bottom_boundary_is_before_screen_edge(&self, rect: &dyn Pane) -> bool {
|
||||
rect.y() + rect.rows() < self.rows
|
||||
}
|
||||
fn rect_right_boundary_row_start(&self, rect: &Box<dyn Pane>) -> usize {
|
||||
fn rect_right_boundary_row_start(&self, rect: &dyn Pane) -> usize {
|
||||
if rect.y() == 0 {
|
||||
0
|
||||
} else {
|
||||
rect.y() - 1
|
||||
}
|
||||
}
|
||||
fn rect_right_boundary_row_end(&self, rect: &Box<dyn Pane>) -> usize {
|
||||
fn rect_right_boundary_row_end(&self, rect: &dyn Pane) -> usize {
|
||||
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
|
||||
// connect to whatever boundary is beneath us
|
||||
|
|
@ -452,14 +452,14 @@ impl Boundaries {
|
|||
rect_bottom_row + 1
|
||||
}
|
||||
}
|
||||
fn rect_bottom_boundary_col_start(&self, rect: &Box<dyn Pane>) -> usize {
|
||||
fn rect_bottom_boundary_col_start(&self, rect: &dyn Pane) -> usize {
|
||||
if rect.x() == 0 {
|
||||
0
|
||||
} else {
|
||||
rect.x() - 1
|
||||
}
|
||||
}
|
||||
fn rect_bottom_boundary_col_end(&self, rect: &Box<dyn Pane>) -> usize {
|
||||
fn rect_bottom_boundary_col_end(&self, rect: &dyn Pane) -> usize {
|
||||
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
|
||||
// connect to whatever boundary is right of us
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::mutex_atomic)]
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
|
|||
|
|
@ -89,6 +89,12 @@ impl ErrorContext {
|
|||
}
|
||||
}
|
||||
|
||||
impl Default for ErrorContext {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ErrorContext {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
writeln!(f, "Originating Thread(s):")?;
|
||||
|
|
|
|||
38
src/main.rs
38
src/main.rs
|
|
@ -24,6 +24,7 @@ use std::thread;
|
|||
use panes::PaneId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use structopt::StructOpt;
|
||||
use wasm_vm::PluginInstruction;
|
||||
|
||||
use crate::command_is_executing::CommandIsExecuting;
|
||||
use crate::errors::{AppContext, ContextType, ErrorContext, PtyContext, ScreenContext};
|
||||
|
|
@ -38,7 +39,7 @@ use crate::utils::{
|
|||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
thread_local!(static OPENCALLS: RefCell<ErrorContext> = RefCell::new(ErrorContext::new()));
|
||||
thread_local!(static OPENCALLS: RefCell<ErrorContext> = RefCell::default());
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
enum ApiCommand {
|
||||
|
|
@ -48,6 +49,9 @@ enum ApiCommand {
|
|||
MoveFocus,
|
||||
}
|
||||
|
||||
pub type ChannelWithContext<T> = (Sender<(T, ErrorContext)>, Receiver<(T, ErrorContext)>);
|
||||
pub type SyncChannelWithContext<T> = (SyncSender<(T, ErrorContext)>, Receiver<(T, ErrorContext)>);
|
||||
|
||||
#[derive(Clone)]
|
||||
enum SenderType<T: Clone> {
|
||||
Sender(Sender<(T, ErrorContext)>),
|
||||
|
|
@ -146,35 +150,27 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let command_is_executing = CommandIsExecuting::new();
|
||||
|
||||
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
|
||||
os_input.into_raw_mode(0);
|
||||
let (send_screen_instructions, receive_screen_instructions): (
|
||||
Sender<(ScreenInstruction, ErrorContext)>,
|
||||
Receiver<(ScreenInstruction, ErrorContext)>,
|
||||
) = channel();
|
||||
os_input.set_raw_mode(0);
|
||||
let (send_screen_instructions, receive_screen_instructions): ChannelWithContext<
|
||||
ScreenInstruction,
|
||||
> = channel();
|
||||
let err_ctx = OPENCALLS.with(|ctx| *ctx.borrow());
|
||||
let mut send_screen_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::Sender(send_screen_instructions));
|
||||
let (send_pty_instructions, receive_pty_instructions): (
|
||||
Sender<(PtyInstruction, ErrorContext)>,
|
||||
Receiver<(PtyInstruction, ErrorContext)>,
|
||||
) = channel();
|
||||
|
||||
let (send_pty_instructions, receive_pty_instructions): ChannelWithContext<PtyInstruction> =
|
||||
channel();
|
||||
let mut send_pty_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::Sender(send_pty_instructions));
|
||||
|
||||
use crate::wasm_vm::PluginInstruction;
|
||||
|
||||
let (send_plugin_instructions, receive_plugin_instructions): (
|
||||
Sender<(PluginInstruction, ErrorContext)>,
|
||||
Receiver<(PluginInstruction, ErrorContext)>,
|
||||
) = channel();
|
||||
|
||||
let (send_plugin_instructions, receive_plugin_instructions): ChannelWithContext<
|
||||
PluginInstruction,
|
||||
> = channel();
|
||||
let send_plugin_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::Sender(send_plugin_instructions));
|
||||
|
||||
let (send_app_instructions, receive_app_instructions): (
|
||||
SyncSender<(AppInstruction, ErrorContext)>,
|
||||
Receiver<(AppInstruction, ErrorContext)>,
|
||||
) = sync_channel(0);
|
||||
let (send_app_instructions, receive_app_instructions): SyncChannelWithContext<AppInstruction> =
|
||||
sync_channel(0);
|
||||
let send_app_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::SyncSender(send_app_instructions));
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ fn handle_command_exit(mut child: Child) {
|
|||
}
|
||||
|
||||
for signal in signals.pending() {
|
||||
// FIXME: We need to handle more signals here!
|
||||
match signal {
|
||||
signal_hook::SIGINT => {
|
||||
child.kill().unwrap();
|
||||
|
|
@ -141,7 +142,7 @@ pub struct OsInputOutput {
|
|||
pub trait OsApi: Send + Sync {
|
||||
fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize;
|
||||
fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16);
|
||||
fn into_raw_mode(&mut self, pid: RawFd);
|
||||
fn set_raw_mode(&mut self, pid: RawFd);
|
||||
fn unset_raw_mode(&mut self, pid: RawFd);
|
||||
fn spawn_terminal(&mut self, file_to_open: Option<PathBuf>) -> (RawFd, RawFd);
|
||||
fn read_from_tty_stdout(&mut self, pid: RawFd, buf: &mut [u8]) -> Result<usize, nix::Error>;
|
||||
|
|
@ -160,7 +161,7 @@ impl OsApi for OsInputOutput {
|
|||
fn set_terminal_size_using_fd(&mut self, pid: RawFd, cols: u16, rows: u16) {
|
||||
set_terminal_size_using_fd(pid, cols, rows);
|
||||
}
|
||||
fn into_raw_mode(&mut self, pid: RawFd) {
|
||||
fn set_raw_mode(&mut self, pid: RawFd) {
|
||||
into_raw_mode(pid);
|
||||
}
|
||||
fn unset_raw_mode(&mut self, pid: RawFd) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::{
|
||||
cmp::max,
|
||||
fmt::{self, Debug, Formatter},
|
||||
};
|
||||
|
||||
use crate::panes::terminal_character::{
|
||||
CharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER,
|
||||
|
|
@ -341,10 +344,8 @@ impl Scroll {
|
|||
if lines_to_skip > 0 {
|
||||
lines_to_skip -= 1;
|
||||
} else {
|
||||
for _ in line.len()..self.total_columns {
|
||||
// pad line if needed
|
||||
line.push(EMPTY_TERMINAL_CHARACTER);
|
||||
}
|
||||
// pad line if needed
|
||||
line.resize(self.total_columns, EMPTY_TERMINAL_CHARACTER);
|
||||
lines.push_front(line);
|
||||
}
|
||||
if lines.len() == self.lines_in_view {
|
||||
|
|
@ -477,9 +478,14 @@ impl Scroll {
|
|||
count
|
||||
};
|
||||
|
||||
for _ in current_fragment.characters.len()..current_cursor_column_position + move_count {
|
||||
current_fragment.characters.push(EMPTY_TERMINAL_CHARACTER);
|
||||
}
|
||||
current_fragment.characters.resize(
|
||||
max(
|
||||
current_fragment.characters.len(),
|
||||
current_cursor_column_position + move_count,
|
||||
),
|
||||
EMPTY_TERMINAL_CHARACTER,
|
||||
);
|
||||
|
||||
self.cursor_position.move_forward(move_count);
|
||||
}
|
||||
pub fn move_cursor_back(&mut self, count: usize) {
|
||||
|
|
@ -645,9 +651,10 @@ impl Scroll {
|
|||
.get_mut(current_line_wrap_position)
|
||||
.expect("cursor out of bounds");
|
||||
|
||||
for _ in current_fragment.characters.len()..col {
|
||||
current_fragment.characters.push(EMPTY_TERMINAL_CHARACTER);
|
||||
}
|
||||
current_fragment.characters.resize(
|
||||
max(current_fragment.characters.len(), col),
|
||||
EMPTY_TERMINAL_CHARACTER,
|
||||
);
|
||||
self.cursor_position.move_to_column(col);
|
||||
}
|
||||
pub fn move_cursor_to_column(&mut self, col: usize) {
|
||||
|
|
@ -680,9 +687,7 @@ impl Scroll {
|
|||
self.scroll_region = None;
|
||||
}
|
||||
fn scroll_region_absolute_indices(&mut self) -> Option<(usize, usize)> {
|
||||
if self.scroll_region.is_none() {
|
||||
return None;
|
||||
};
|
||||
self.scroll_region?;
|
||||
if self.canonical_lines.len() > self.lines_in_view {
|
||||
let absolute_top = self.canonical_lines.len() - 1 - self.lines_in_view;
|
||||
let absolute_bottom = self.canonical_lines.len() - 1;
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ impl CharacterStyles {
|
|||
}
|
||||
}
|
||||
if let Some(next_params) = ansi_params.get(params_used..) {
|
||||
if next_params.len() > 0 {
|
||||
if !next_params.is_empty() {
|
||||
self.add_style_from_ansi_params(next_params);
|
||||
}
|
||||
}
|
||||
|
|
@ -536,14 +536,9 @@ impl Display for CharacterStyles {
|
|||
write!(f, "\u{1b}[2m")?;
|
||||
}
|
||||
AnsiCode::Reset => {
|
||||
if let Some(bold) = self.bold {
|
||||
if let Some(AnsiCode::Reset) = self.bold {
|
||||
// we only reset dim if both dim and bold should be reset
|
||||
match bold {
|
||||
AnsiCode::Reset => {
|
||||
write!(f, "\u{1b}[22m")?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
write!(f, "\u{1b}[22m")?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -442,12 +442,10 @@ impl vte::Perform for TerminalPane {
|
|||
} else {
|
||||
(params[0] as usize - 1, params[0] as usize)
|
||||
}
|
||||
} else if params[0] == 0 {
|
||||
(0, params[1] as usize - 1)
|
||||
} else {
|
||||
if params[0] == 0 {
|
||||
(0, params[1] as usize - 1)
|
||||
} else {
|
||||
(params[0] as usize - 1, params[1] as usize - 1)
|
||||
}
|
||||
(params[0] as usize - 1, params[1] as usize - 1)
|
||||
};
|
||||
self.scroll.move_cursor_to(row, col);
|
||||
} else if c == 'A' {
|
||||
|
|
@ -607,11 +605,8 @@ impl vte::Perform for TerminalPane {
|
|||
}
|
||||
|
||||
fn esc_dispatch(&mut self, intermediates: &[u8], _ignore: bool, byte: u8) {
|
||||
match (byte, intermediates.get(0)) {
|
||||
(b'M', None) => {
|
||||
self.scroll.move_cursor_up_in_scroll_region(1);
|
||||
}
|
||||
_ => {}
|
||||
if let (b'M', None) = (byte, intermediates.get(0)) {
|
||||
self.scroll.move_cursor_up_in_scroll_region(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ impl Screen {
|
|||
let active_tab_id = self.get_active_tab().unwrap().index;
|
||||
let tab_ids: Vec<usize> = self.tabs.keys().copied().collect();
|
||||
let first_tab = tab_ids.get(0).unwrap();
|
||||
let last_tab = tab_ids.get(tab_ids.len() - 1).unwrap();
|
||||
let last_tab = tab_ids.last().unwrap();
|
||||
|
||||
let active_tab_id_position = tab_ids.iter().position(|id| id == &active_tab_id).unwrap();
|
||||
if active_tab_id == *first_tab {
|
||||
|
|
@ -143,7 +143,7 @@ impl Screen {
|
|||
self.send_pty_instructions
|
||||
.send(PtyInstruction::CloseTab(pane_ids))
|
||||
.unwrap();
|
||||
if self.tabs.len() == 0 {
|
||||
if self.tabs.is_empty() {
|
||||
self.active_tab_index = None;
|
||||
self.render();
|
||||
}
|
||||
|
|
|
|||
127
src/tab.rs
127
src/tab.rs
|
|
@ -4,8 +4,11 @@ use crate::{boundaries::Boundaries, panes::PluginPane};
|
|||
use crate::{layout::Layout, wasm_vm::PluginInstruction};
|
||||
use crate::{os_input_output::OsApi, utils::shared::pad_to_size};
|
||||
use crate::{AppInstruction, SenderWithContext};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
collections::{BTreeMap, HashSet},
|
||||
};
|
||||
use std::{io::Write, sync::mpsc::channel};
|
||||
|
||||
/*
|
||||
|
|
@ -98,30 +101,30 @@ pub trait Pane {
|
|||
fn bottom_boundary_y_coords(&self) -> usize {
|
||||
self.y() + self.rows()
|
||||
}
|
||||
fn is_directly_right_of(&self, other: &Box<dyn Pane>) -> bool {
|
||||
fn is_directly_right_of(&self, other: &dyn Pane) -> bool {
|
||||
self.x() == other.x() + other.columns() + 1
|
||||
}
|
||||
fn is_directly_left_of(&self, other: &Box<dyn Pane>) -> bool {
|
||||
fn is_directly_left_of(&self, other: &dyn Pane) -> bool {
|
||||
self.x() + self.columns() + 1 == other.x()
|
||||
}
|
||||
fn is_directly_below(&self, other: &Box<dyn Pane>) -> bool {
|
||||
fn is_directly_below(&self, other: &dyn Pane) -> bool {
|
||||
self.y() == other.y() + other.rows() + 1
|
||||
}
|
||||
fn is_directly_above(&self, other: &Box<dyn Pane>) -> bool {
|
||||
fn is_directly_above(&self, other: &dyn Pane) -> bool {
|
||||
self.y() + self.rows() + 1 == other.y()
|
||||
}
|
||||
fn horizontally_overlaps_with(&self, other: &Box<dyn Pane>) -> bool {
|
||||
fn horizontally_overlaps_with(&self, other: &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 {
|
||||
fn get_horizontal_overlap_with(&self, other: &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 {
|
||||
fn vertically_overlaps_with(&self, other: &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())
|
||||
|
|
@ -130,7 +133,7 @@ pub trait Pane {
|
|||
|| (other.x() <= self.x()
|
||||
&& (other.x() + other.columns() >= (self.x() + self.columns())))
|
||||
}
|
||||
fn get_vertical_overlap_with(&self, other: &Box<dyn Pane>) -> usize {
|
||||
fn get_vertical_overlap_with(&self, other: &dyn Pane) -> usize {
|
||||
std::cmp::min(self.x() + self.columns(), other.x() + other.columns())
|
||||
- std::cmp::max(self.x(), other.x())
|
||||
}
|
||||
|
|
@ -440,9 +443,9 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
}
|
||||
pub fn get_active_pane(&self) -> Option<&Box<dyn Pane>> {
|
||||
pub fn get_active_pane(&self) -> Option<&dyn Pane> {
|
||||
match self.get_active_pane_id() {
|
||||
Some(active_pane) => self.panes.get(&active_pane),
|
||||
Some(active_pane) => self.panes.get(&active_pane).map(Box::as_ref),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -551,7 +554,7 @@ impl Tab {
|
|||
);
|
||||
for (kind, terminal) in self.panes.iter_mut() {
|
||||
if !self.panes_to_hide.contains(&terminal.pid()) {
|
||||
boundaries.add_rect(&terminal);
|
||||
boundaries.add_rect(terminal.as_ref());
|
||||
if let Some(vte_output) = terminal.render() {
|
||||
let vte_output = if let PaneId::Terminal(_) = kind {
|
||||
vte_output
|
||||
|
|
@ -668,37 +671,37 @@ impl Tab {
|
|||
Some(ids)
|
||||
}
|
||||
}
|
||||
fn panes_top_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||
fn panes_top_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> {
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap().as_ref())
|
||||
.filter(|terminal| terminal.pid() != pane.pid() && terminal.y() == pane.y())
|
||||
.collect()
|
||||
}
|
||||
fn panes_bottom_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||
fn panes_bottom_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> {
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap().as_ref())
|
||||
.filter(|terminal| {
|
||||
terminal.pid() != pane.pid()
|
||||
&& terminal.y() + terminal.rows() == pane.y() + pane.rows()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
fn panes_right_aligned_with_pane(&self, pane: &Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||
fn panes_right_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> {
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap().as_ref())
|
||||
.filter(|terminal| {
|
||||
terminal.pid() != pane.pid()
|
||||
&& terminal.x() + terminal.columns() == pane.x() + pane.columns()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
fn panes_left_aligned_with_pane(&self, pane: &&Box<dyn Pane>) -> Vec<&Box<dyn Pane>> {
|
||||
fn panes_left_aligned_with_pane(&self, pane: &dyn Pane) -> Vec<&dyn Pane> {
|
||||
self.panes
|
||||
.keys()
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.map(|t_id| self.panes.get(&t_id).unwrap().as_ref())
|
||||
.filter(|terminal| terminal.pid() != pane.pid() && terminal.x() == pane.x())
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -708,10 +711,14 @@ impl Tab {
|
|||
terminal_borders_to_the_right: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).expect("terminal id does not exist");
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(id)
|
||||
.expect("terminal id does not exist")
|
||||
.as_ref();
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
right_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||
right_aligned_terminals.sort_by_key(|a| Reverse(a.y()));
|
||||
for terminal in right_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() {
|
||||
|
|
@ -747,10 +754,14 @@ impl Tab {
|
|||
terminal_borders_to_the_right: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).expect("terminal id does not exist");
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(id)
|
||||
.expect("terminal id does not exist")
|
||||
.as_ref();
|
||||
let mut right_aligned_terminals = self.panes_right_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
right_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||
right_aligned_terminals.sort_by_key(|a| a.y());
|
||||
for terminal in right_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 {
|
||||
|
|
@ -786,10 +797,14 @@ impl Tab {
|
|||
terminal_borders_to_the_left: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).expect("terminal id does not exist");
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(id)
|
||||
.expect("terminal id does not exist")
|
||||
.as_ref();
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
left_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||
left_aligned_terminals.sort_by_key(|a| Reverse(a.y()));
|
||||
for terminal in left_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() {
|
||||
|
|
@ -825,10 +840,14 @@ impl Tab {
|
|||
terminal_borders_to_the_left: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).expect("terminal id does not exist");
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(id)
|
||||
.expect("terminal id does not exist")
|
||||
.as_ref();
|
||||
let mut left_aligned_terminals = self.panes_left_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
left_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||
left_aligned_terminals.sort_by_key(|a| a.y());
|
||||
for terminal in left_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 {
|
||||
|
|
@ -867,10 +886,14 @@ impl Tab {
|
|||
terminal_borders_above: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).expect("terminal id does not exist");
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self
|
||||
.panes
|
||||
.get(id)
|
||||
.expect("terminal id does not exist")
|
||||
.as_ref();
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
top_aligned_terminals.sort_by(|a, b| b.x().cmp(&a.x()));
|
||||
top_aligned_terminals.sort_by_key(|a| Reverse(a.x()));
|
||||
for terminal in top_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() + terminal.columns() + 1 == terminal_to_check.x() {
|
||||
|
|
@ -906,10 +929,10 @@ impl Tab {
|
|||
terminal_borders_above: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).unwrap();
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(&terminal_to_check);
|
||||
let terminal_to_check = self.panes.get(id).unwrap().as_ref();
|
||||
let mut top_aligned_terminals = self.panes_top_aligned_with_pane(terminal_to_check);
|
||||
// terminals that are next to each other up to current
|
||||
top_aligned_terminals.sort_by(|a, b| a.x().cmp(&b.x()));
|
||||
top_aligned_terminals.sort_by_key(|a| a.x());
|
||||
for terminal in top_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 {
|
||||
|
|
@ -945,9 +968,9 @@ impl Tab {
|
|||
terminal_borders_below: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).unwrap();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(&terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by(|a, b| b.x().cmp(&a.x()));
|
||||
let terminal_to_check = self.panes.get(id).unwrap().as_ref();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by_key(|a| Reverse(a.x()));
|
||||
// terminals that are next to each other up to current
|
||||
for terminal in bottom_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
|
|
@ -984,9 +1007,9 @@ impl Tab {
|
|||
terminal_borders_below: &HashSet<usize>,
|
||||
) -> BorderAndPaneIds {
|
||||
let mut terminals = vec![];
|
||||
let terminal_to_check = self.panes.get(id).unwrap();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(&terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by(|a, b| a.x().cmp(&b.x()));
|
||||
let terminal_to_check = self.panes.get(id).unwrap().as_ref();
|
||||
let mut bottom_aligned_terminals = self.panes_bottom_aligned_with_pane(terminal_to_check);
|
||||
bottom_aligned_terminals.sort_by_key(|a| a.x());
|
||||
// terminals that are next to each other up to current
|
||||
for terminal in bottom_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
|
|
@ -1421,9 +1444,9 @@ impl Tab {
|
|||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_left_of(&active) && c.horizontally_overlaps_with(&active)
|
||||
c.is_directly_left_of(active) && c.horizontally_overlaps_with(active)
|
||||
})
|
||||
.max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(&active))
|
||||
.max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(active))
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(&p) => {
|
||||
|
|
@ -1451,9 +1474,9 @@ impl Tab {
|
|||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_below(&active) && c.vertically_overlaps_with(&active)
|
||||
c.is_directly_below(active) && c.vertically_overlaps_with(active)
|
||||
})
|
||||
.max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(&active))
|
||||
.max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(active))
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(&p) => {
|
||||
|
|
@ -1481,9 +1504,9 @@ impl Tab {
|
|||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_above(&active) && c.vertically_overlaps_with(&active)
|
||||
c.is_directly_above(active) && c.vertically_overlaps_with(active)
|
||||
})
|
||||
.max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(&active))
|
||||
.max_by_key(|(_, (_, c))| c.get_vertical_overlap_with(active))
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(&p) => {
|
||||
|
|
@ -1511,9 +1534,9 @@ impl Tab {
|
|||
let next_index = terminals
|
||||
.enumerate()
|
||||
.filter(|(_, (_, c))| {
|
||||
c.is_directly_right_of(&active) && c.horizontally_overlaps_with(&active)
|
||||
c.is_directly_right_of(active) && c.horizontally_overlaps_with(active)
|
||||
})
|
||||
.max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(&active))
|
||||
.max_by_key(|(_, (_, c))| c.get_horizontal_overlap_with(active))
|
||||
.map(|(_, (pid, _))| pid);
|
||||
match next_index {
|
||||
Some(&p) => {
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ impl OsApi for FakeInputOutput {
|
|||
.unwrap()
|
||||
.push(IoEvent::SetTerminalSizeUsingFd(pid, cols, rows));
|
||||
}
|
||||
fn into_raw_mode(&mut self, pid: RawFd) {
|
||||
fn set_raw_mode(&mut self, pid: RawFd) {
|
||||
self.io_events
|
||||
.lock()
|
||||
.unwrap()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue