mirror of
https://github.com/zellij-org/zellij.git
synced 2024-11-23 08:57:14 +03:00
wip: need to figure out how to clear lines
This commit is contained in:
commit
7774edd45a
92
Cargo.lock
generated
92
Cargo.lock
generated
@ -130,7 +130,7 @@ dependencies = [
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
"signal-hook 0.3.7",
|
||||
"signal-hook",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@ -524,9 +524,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dtoa"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
|
||||
checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
@ -824,9 +824,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.7.0"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1b6cf41e31a7e7b78055b548826da45c7dc74e6a13a3fa6b897a17a01322f26"
|
||||
checksum = "c4a1b21a2971cea49ca4613c0e9fe8225ecaf5de64090fddc6002284726e9244"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
@ -899,9 +899,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.49"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821"
|
||||
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -942,9 +942,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.91"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
|
||||
checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -964,9 +964,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
|
||||
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
@ -998,18 +998,18 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6"
|
||||
checksum = "397d1a6d6d0563c0f5462bbdae662cf6c784edf5e828e40c7257f85d82bf56dd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.2"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc14fc54a812b4472b4113facc3e44d099fbc0ea2ce0551fa5c703f8edfbfd38"
|
||||
checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@ -1194,9 +1194,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@ -1428,19 +1428,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.17"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e31d442c16f047a671b5a71e2161d6e68814012b7f5379d269ebd915fac2729"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6aa894ef3fade0ee7243422f4fbbd6c2b48e6de767e621d37ef65f2310f53cea"
|
||||
checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
@ -1587,9 +1577,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.65"
|
||||
version = "1.0.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663"
|
||||
checksum = "3ce15dd3ed8aa2f8eeac4716d6ef5ab58b6b9256db41d7e1a0224c2788e8fd87"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1894,9 +1884,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe"
|
||||
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
@ -1904,9 +1894,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3"
|
||||
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@ -1919,9 +1909,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.22"
|
||||
version = "0.4.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73157efb9af26fb564bb59a009afd1c7c334a44db171d280690d0c3faaec3468"
|
||||
checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
@ -1931,9 +1921,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b"
|
||||
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -1941,9 +1931,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
|
||||
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1954,9 +1944,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa"
|
||||
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
|
||||
|
||||
[[package]]
|
||||
name = "wasmer"
|
||||
@ -2169,18 +2159,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wat"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b0fa059022c5dabe129f02b429d67086400deb8277f89c975555dacc1dadbcc"
|
||||
checksum = "8ec280a739b69173e0ffd12c1658507996836ba4e992ed9bc1e5385a0bd72a02"
|
||||
dependencies = [
|
||||
"wast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.49"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310"
|
||||
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@ -2197,12 +2187,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.0.2"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87c14ef7e1b8b8ecfc75d5eca37949410046e66f15d185c01d70824f1f8111ef"
|
||||
checksum = "b55551e42cbdf2ce2bedd2203d0cc08dba002c27510f86dab6d0ce304cba3dfe"
|
||||
dependencies = [
|
||||
"either",
|
||||
"libc",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2292,7 +2282,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
"signal-hook 0.1.17",
|
||||
"signal-hook",
|
||||
"strip-ansi-escapes",
|
||||
"structopt",
|
||||
"strum",
|
||||
|
@ -24,7 +24,7 @@ nom = "6.0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_yaml = "0.8"
|
||||
signal-hook = "0.1.10"
|
||||
signal-hook = "0.3"
|
||||
strip-ansi-escapes = "0.1.0"
|
||||
structopt = "0.3"
|
||||
termion = "1.5.0"
|
||||
|
@ -26,3 +26,6 @@ Once the organization reaches 10 members, a reasonable and achievable process mu
|
||||
* Denis Maximov <denis_maxim0v@protonmail.com>
|
||||
* Kunal Mohan <kunalmohan99@gmail.com>
|
||||
* Henil Dedania <dedaniahenil@gmail.com>
|
||||
* Roee Shapira <ro33.sha@gmail.com>
|
||||
* Alex Kenji Berthold <aks.kenji@protonmail.com>
|
||||
* Kyle Sutherland-Cash <kyle.sutherlandcash@gmail.com>
|
||||
|
@ -105,7 +105,7 @@ fn unselected_mode_shortcut(letter: char, text: &str, palette: Palette) -> LineP
|
||||
suffix_separator,
|
||||
])
|
||||
.to_string(),
|
||||
len: text.chars().count() + 6, // 2 for the arrows, 3 for the char separators, 1 for the character
|
||||
len: text.chars().count() + 7, // 2 for the arrows, 3 for the char separators, 1 for the character, 1 for the text padding
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ fn selected_mode_shortcut(letter: char, text: &str, palette: Palette) -> LinePar
|
||||
suffix_separator,
|
||||
])
|
||||
.to_string(),
|
||||
len: text.chars().count() + 6, // 2 for the arrows, 3 for the char separators, 1 for the character
|
||||
len: text.chars().count() + 7, // 2 for the arrows, 3 for the char separators, 1 for the character, 1 for the text padding
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ mod first_line;
|
||||
mod second_line;
|
||||
|
||||
use std::fmt::{Display, Error, Formatter};
|
||||
use zellij_tile::prelude::*;
|
||||
use zellij_tile::{prelude::*, data::Theme};
|
||||
|
||||
use first_line::{ctrl_keys, superkey};
|
||||
use second_line::keybinds;
|
||||
@ -62,21 +62,30 @@ impl ZellijTile for State {
|
||||
let first_line = format!("{}{}", superkey, ctrl_keys);
|
||||
let second_line = keybinds(&self.mode_info, cols);
|
||||
|
||||
let first_line_color = match self.mode_info.palette.theme {
|
||||
Theme::Light => self.mode_info.palette.black,
|
||||
Theme::Dark => self.mode_info.palette.white,
|
||||
};
|
||||
let second_line_color = match self.mode_info.palette.theme {
|
||||
Theme::Light => self.mode_info.palette.bg,
|
||||
Theme::Dark => self.mode_info.palette.bg,
|
||||
};
|
||||
|
||||
// [48;5;238m is gray background, [0K is so that it fills the rest of the line
|
||||
// [48;5;16m is black background, [0K is so that it fills the rest of the line
|
||||
println!(
|
||||
"{}\u{1b}[{};{};{}m\u{1b}[0K",
|
||||
"{}\x1B[38;2;{};{};{}m\u{1b}[0K",
|
||||
first_line,
|
||||
self.mode_info.palette.black.0,
|
||||
self.mode_info.palette.black.1,
|
||||
self.mode_info.palette.black.2
|
||||
first_line_color.0,
|
||||
first_line_color.1,
|
||||
first_line_color.2
|
||||
);
|
||||
println!(
|
||||
"{}\u{1b}[{};{};{}m\u{1b}[0K",
|
||||
second_line,
|
||||
self.mode_info.palette.fg.0,
|
||||
self.mode_info.palette.fg.1,
|
||||
self.mode_info.palette.fg.2
|
||||
second_line_color.0,
|
||||
second_line_color.1,
|
||||
second_line_color.2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub mod boundaries;
|
||||
pub mod layout;
|
||||
pub mod pane_resizer;
|
||||
pub mod panes;
|
||||
pub mod tab;
|
||||
|
||||
|
508
src/client/pane_resizer.rs
Normal file
508
src/client/pane_resizer.rs
Normal file
@ -0,0 +1,508 @@
|
||||
use crate::os_input_output::OsApi;
|
||||
use crate::panes::{PaneId, PositionAndSize};
|
||||
use crate::tab::Pane;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
pub struct PaneResizer<'a> {
|
||||
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
os_api: &'a mut Box<dyn OsApi>,
|
||||
}
|
||||
|
||||
// TODO: currently there are some functions here duplicated with Tab
|
||||
// the reason for this is that we need to get rid of the expansion_boundary
|
||||
// otherwise we'll have a big separation of concerns issue
|
||||
// once that is done, all resizing functions should move here
|
||||
|
||||
impl<'a> PaneResizer<'a> {
|
||||
pub fn new(
|
||||
panes: &'a mut BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
os_api: &'a mut Box<dyn OsApi>,
|
||||
) -> Self {
|
||||
PaneResizer { panes, os_api }
|
||||
}
|
||||
pub fn resize(
|
||||
&mut self,
|
||||
mut current_size: PositionAndSize,
|
||||
new_size: PositionAndSize,
|
||||
) -> Option<(isize, isize)> {
|
||||
// (column_difference, row_difference)
|
||||
let mut successfully_resized = false;
|
||||
let mut column_difference: isize = 0;
|
||||
let mut row_difference: isize = 0;
|
||||
if new_size.columns < current_size.columns {
|
||||
let reduce_by = current_size.columns - new_size.columns;
|
||||
find_reducible_vertical_chain(
|
||||
&self.panes,
|
||||
reduce_by,
|
||||
current_size.columns,
|
||||
current_size.rows,
|
||||
)
|
||||
.map(|panes_to_resize| {
|
||||
self.reduce_panes_left_and_pull_adjacents_left(panes_to_resize, reduce_by);
|
||||
column_difference = new_size.columns as isize - current_size.columns as isize;
|
||||
current_size.columns = (current_size.columns as isize + column_difference) as usize;
|
||||
successfully_resized = true;
|
||||
});
|
||||
} else if new_size.columns > current_size.columns {
|
||||
let increase_by = new_size.columns - current_size.columns;
|
||||
find_increasable_vertical_chain(
|
||||
&self.panes,
|
||||
increase_by,
|
||||
current_size.columns,
|
||||
current_size.rows,
|
||||
)
|
||||
.map(|panes_to_resize| {
|
||||
self.increase_panes_right_and_push_adjacents_right(panes_to_resize, increase_by);
|
||||
column_difference = new_size.columns as isize - current_size.columns as isize;
|
||||
current_size.columns = (current_size.columns as isize + column_difference) as usize;
|
||||
successfully_resized = true;
|
||||
});
|
||||
}
|
||||
if new_size.rows < current_size.rows {
|
||||
let reduce_by = current_size.rows - new_size.rows;
|
||||
find_reducible_horizontal_chain(
|
||||
&self.panes,
|
||||
reduce_by,
|
||||
current_size.columns,
|
||||
current_size.rows,
|
||||
)
|
||||
.map(|panes_to_resize| {
|
||||
self.reduce_panes_up_and_pull_adjacents_up(panes_to_resize, reduce_by);
|
||||
row_difference = new_size.rows as isize - current_size.rows as isize;
|
||||
current_size.rows = (current_size.rows as isize + row_difference) as usize;
|
||||
successfully_resized = true;
|
||||
});
|
||||
} else if new_size.rows > current_size.rows {
|
||||
let increase_by = new_size.rows - current_size.rows;
|
||||
find_increasable_horizontal_chain(
|
||||
&self.panes,
|
||||
increase_by,
|
||||
current_size.columns,
|
||||
current_size.rows,
|
||||
)
|
||||
.map(|panes_to_resize| {
|
||||
self.increase_panes_down_and_push_down_adjacents(panes_to_resize, increase_by);
|
||||
row_difference = new_size.rows as isize - current_size.rows as isize;
|
||||
current_size.rows = (current_size.rows as isize + row_difference) as usize;
|
||||
successfully_resized = true;
|
||||
});
|
||||
}
|
||||
if successfully_resized {
|
||||
Some((column_difference, row_difference))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn reduce_panes_left_and_pull_adjacents_left(
|
||||
&mut self,
|
||||
panes_to_reduce: Vec<PaneId>,
|
||||
reduce_by: usize,
|
||||
) {
|
||||
let mut pulled_panes: HashSet<PaneId> = HashSet::new();
|
||||
for pane_id in panes_to_reduce {
|
||||
let (pane_x, pane_y, pane_columns, pane_rows) = {
|
||||
let pane = self.panes.get(&pane_id).unwrap();
|
||||
(pane.x(), pane.y(), pane.columns(), pane.rows())
|
||||
};
|
||||
let panes_to_pull = self.panes.values_mut().filter(|p| {
|
||||
p.x() > pane_x + pane_columns
|
||||
&& (p.y() <= pane_y && p.y() + p.rows() >= pane_y
|
||||
|| p.y() >= pane_y && p.y() + p.rows() <= pane_y + pane_rows)
|
||||
});
|
||||
for pane in panes_to_pull {
|
||||
if !pulled_panes.contains(&pane.pid()) {
|
||||
pane.pull_left(reduce_by);
|
||||
pulled_panes.insert(pane.pid());
|
||||
}
|
||||
}
|
||||
self.reduce_pane_width_left(&pane_id, reduce_by);
|
||||
}
|
||||
}
|
||||
fn reduce_panes_up_and_pull_adjacents_up(
|
||||
&mut self,
|
||||
panes_to_reduce: Vec<PaneId>,
|
||||
reduce_by: usize,
|
||||
) {
|
||||
let mut pulled_panes: HashSet<PaneId> = HashSet::new();
|
||||
for pane_id in panes_to_reduce {
|
||||
let (pane_x, pane_y, pane_columns, pane_rows) = {
|
||||
let pane = self.panes.get(&pane_id).unwrap();
|
||||
(pane.x(), pane.y(), pane.columns(), pane.rows())
|
||||
};
|
||||
let panes_to_pull = self.panes.values_mut().filter(|p| {
|
||||
p.y() > pane_y + pane_rows
|
||||
&& (p.x() <= pane_x && p.x() + p.columns() >= pane_x
|
||||
|| p.x() >= pane_x && p.x() + p.columns() <= pane_x + pane_columns)
|
||||
});
|
||||
for pane in panes_to_pull {
|
||||
if !pulled_panes.contains(&pane.pid()) {
|
||||
pane.pull_up(reduce_by);
|
||||
pulled_panes.insert(pane.pid());
|
||||
}
|
||||
}
|
||||
self.reduce_pane_height_up(&pane_id, reduce_by);
|
||||
}
|
||||
}
|
||||
fn increase_panes_down_and_push_down_adjacents(
|
||||
&mut self,
|
||||
panes_to_increase: Vec<PaneId>,
|
||||
increase_by: usize,
|
||||
) {
|
||||
let mut pushed_panes: HashSet<PaneId> = HashSet::new();
|
||||
for pane_id in panes_to_increase {
|
||||
let (pane_x, pane_y, pane_columns, pane_rows) = {
|
||||
let pane = self.panes.get(&pane_id).unwrap();
|
||||
(pane.x(), pane.y(), pane.columns(), pane.rows())
|
||||
};
|
||||
let panes_to_push = self.panes.values_mut().filter(|p| {
|
||||
p.y() > pane_y + pane_rows
|
||||
&& (p.x() <= pane_x && p.x() + p.columns() >= pane_x
|
||||
|| p.x() >= pane_x && p.x() + p.columns() <= pane_x + pane_columns)
|
||||
});
|
||||
for pane in panes_to_push {
|
||||
if !pushed_panes.contains(&pane.pid()) {
|
||||
pane.push_down(increase_by);
|
||||
pushed_panes.insert(pane.pid());
|
||||
}
|
||||
}
|
||||
self.increase_pane_height_down(&pane_id, increase_by);
|
||||
}
|
||||
}
|
||||
fn increase_panes_right_and_push_adjacents_right(
|
||||
&mut self,
|
||||
panes_to_increase: Vec<PaneId>,
|
||||
increase_by: usize,
|
||||
) {
|
||||
let mut pushed_panes: HashSet<PaneId> = HashSet::new();
|
||||
for pane_id in panes_to_increase {
|
||||
let (pane_x, pane_y, pane_columns, pane_rows) = {
|
||||
let pane = self.panes.get(&pane_id).unwrap();
|
||||
(pane.x(), pane.y(), pane.columns(), pane.rows())
|
||||
};
|
||||
let panes_to_push = self.panes.values_mut().filter(|p| {
|
||||
p.x() > pane_x + pane_columns
|
||||
&& (p.y() <= pane_y && p.y() + p.rows() >= pane_y
|
||||
|| p.y() >= pane_y && p.y() + p.rows() <= pane_y + pane_rows)
|
||||
});
|
||||
for pane in panes_to_push {
|
||||
if !pushed_panes.contains(&pane.pid()) {
|
||||
pane.push_right(increase_by);
|
||||
pushed_panes.insert(pane.pid());
|
||||
}
|
||||
}
|
||||
self.increase_pane_width_right(&pane_id, increase_by);
|
||||
}
|
||||
}
|
||||
fn reduce_pane_height_up(&mut self, id: &PaneId, count: usize) {
|
||||
let pane = self.panes.get_mut(id).unwrap();
|
||||
pane.reduce_height_up(count);
|
||||
if let PaneId::Terminal(pid) = id {
|
||||
self.os_api
|
||||
.set_terminal_size_using_fd(*pid, pane.columns() as u16, pane.rows() as u16);
|
||||
}
|
||||
}
|
||||
fn increase_pane_height_down(&mut self, id: &PaneId, count: usize) {
|
||||
let pane = self.panes.get_mut(id).unwrap();
|
||||
pane.increase_height_down(count);
|
||||
if let PaneId::Terminal(pid) = pane.pid() {
|
||||
self.os_api
|
||||
.set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
|
||||
}
|
||||
}
|
||||
fn increase_pane_width_right(&mut self, id: &PaneId, count: usize) {
|
||||
let pane = self.panes.get_mut(id).unwrap();
|
||||
pane.increase_width_right(count);
|
||||
if let PaneId::Terminal(pid) = pane.pid() {
|
||||
self.os_api
|
||||
.set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
|
||||
}
|
||||
}
|
||||
fn reduce_pane_width_left(&mut self, id: &PaneId, count: usize) {
|
||||
let pane = self.panes.get_mut(id).unwrap();
|
||||
pane.reduce_width_left(count);
|
||||
if let PaneId::Terminal(pid) = pane.pid() {
|
||||
self.os_api
|
||||
.set_terminal_size_using_fd(pid, pane.columns() as u16, pane.rows() as u16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_next_increasable_horizontal_pane(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
right_of: &Box<dyn Pane>,
|
||||
increase_by: usize,
|
||||
) -> Option<PaneId> {
|
||||
let next_pane_candidates = panes.values().filter(
|
||||
|p| {
|
||||
p.x() == right_of.x() + right_of.columns() + 1
|
||||
&& p.horizontally_overlaps_with(right_of.as_ref())
|
||||
}, // TODO: the name here is wrong, it should be vertically_overlaps_with
|
||||
);
|
||||
let resizable_candidates =
|
||||
next_pane_candidates.filter(|p| p.can_increase_height_by(increase_by));
|
||||
resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
|
||||
Some(next_pane) => {
|
||||
let next_pane = panes.get(&next_pane).unwrap();
|
||||
if next_pane.y() < p.y() {
|
||||
next_pane_id
|
||||
} else {
|
||||
Some(p.pid())
|
||||
}
|
||||
}
|
||||
None => Some(p.pid()),
|
||||
})
|
||||
}
|
||||
|
||||
fn find_next_increasable_vertical_pane(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
below: &Box<dyn Pane>,
|
||||
increase_by: usize,
|
||||
) -> Option<PaneId> {
|
||||
let next_pane_candidates = panes.values().filter(
|
||||
|p| p.y() == below.y() + below.rows() + 1 && p.vertically_overlaps_with(below.as_ref()), // TODO: the name here is wrong, it should be horizontally_overlaps_with
|
||||
);
|
||||
let resizable_candidates =
|
||||
next_pane_candidates.filter(|p| p.can_increase_width_by(increase_by));
|
||||
resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
|
||||
Some(next_pane) => {
|
||||
let next_pane = panes.get(&next_pane).unwrap();
|
||||
if next_pane.x() < p.x() {
|
||||
next_pane_id
|
||||
} else {
|
||||
Some(p.pid())
|
||||
}
|
||||
}
|
||||
None => Some(p.pid()),
|
||||
})
|
||||
}
|
||||
|
||||
fn find_next_reducible_vertical_pane(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
below: &Box<dyn Pane>,
|
||||
reduce_by: usize,
|
||||
) -> Option<PaneId> {
|
||||
let next_pane_candidates = panes.values().filter(
|
||||
|p| p.y() == below.y() + below.rows() + 1 && p.vertically_overlaps_with(below.as_ref()), // TODO: the name here is wrong, it should be horizontally_overlaps_with
|
||||
);
|
||||
let resizable_candidates = next_pane_candidates.filter(|p| p.can_reduce_width_by(reduce_by));
|
||||
resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
|
||||
Some(next_pane) => {
|
||||
let next_pane = panes.get(&next_pane).unwrap();
|
||||
if next_pane.x() < p.x() {
|
||||
next_pane_id
|
||||
} else {
|
||||
Some(p.pid())
|
||||
}
|
||||
}
|
||||
None => Some(p.pid()),
|
||||
})
|
||||
}
|
||||
|
||||
fn find_next_reducible_horizontal_pane(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
right_of: &Box<dyn Pane>,
|
||||
reduce_by: usize,
|
||||
) -> Option<PaneId> {
|
||||
let next_pane_candidates = panes.values().filter(
|
||||
|p| {
|
||||
p.x() == right_of.x() + right_of.columns() + 1
|
||||
&& p.horizontally_overlaps_with(right_of.as_ref())
|
||||
}, // TODO: the name here is wrong, it should be vertically_overlaps_with
|
||||
);
|
||||
let resizable_candidates = next_pane_candidates.filter(|p| p.can_reduce_height_by(reduce_by));
|
||||
resizable_candidates.fold(None, |next_pane_id, p| match next_pane_id {
|
||||
Some(next_pane) => {
|
||||
let next_pane = panes.get(&next_pane).unwrap();
|
||||
if next_pane.y() < p.y() {
|
||||
next_pane_id
|
||||
} else {
|
||||
Some(p.pid())
|
||||
}
|
||||
}
|
||||
None => Some(p.pid()),
|
||||
})
|
||||
}
|
||||
|
||||
fn find_increasable_horizontal_chain(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
increase_by: usize,
|
||||
screen_width: usize,
|
||||
screen_height: usize, // TODO: this is the previous size (make this clearer)
|
||||
) -> Option<Vec<PaneId>> {
|
||||
let mut horizontal_coordinate = 0;
|
||||
loop {
|
||||
if horizontal_coordinate == screen_height {
|
||||
return None;
|
||||
}
|
||||
|
||||
match panes
|
||||
.values()
|
||||
.find(|p| p.x() == 0 && p.y() == horizontal_coordinate)
|
||||
{
|
||||
Some(leftmost_pane) => {
|
||||
if !leftmost_pane.can_increase_height_by(increase_by) {
|
||||
horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
|
||||
continue;
|
||||
}
|
||||
let mut panes_to_resize = vec![];
|
||||
let mut current_pane = leftmost_pane;
|
||||
loop {
|
||||
panes_to_resize.push(current_pane.pid());
|
||||
if current_pane.x() + current_pane.columns() == screen_width {
|
||||
return Some(panes_to_resize);
|
||||
}
|
||||
match find_next_increasable_horizontal_pane(panes, ¤t_pane, increase_by) {
|
||||
Some(next_pane_id) => {
|
||||
current_pane = panes.get(&next_pane_id).unwrap();
|
||||
}
|
||||
None => {
|
||||
horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_increasable_vertical_chain(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
increase_by: usize,
|
||||
screen_width: usize,
|
||||
screen_height: usize, // TODO: this is the previous size (make this clearer)
|
||||
) -> Option<Vec<PaneId>> {
|
||||
let mut vertical_coordinate = 0;
|
||||
loop {
|
||||
if vertical_coordinate == screen_width {
|
||||
return None;
|
||||
}
|
||||
|
||||
match panes
|
||||
.values()
|
||||
.find(|p| p.y() == 0 && p.x() == vertical_coordinate)
|
||||
{
|
||||
Some(topmost_pane) => {
|
||||
if !topmost_pane.can_increase_width_by(increase_by) {
|
||||
vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
|
||||
continue;
|
||||
}
|
||||
let mut panes_to_resize = vec![];
|
||||
let mut current_pane = topmost_pane;
|
||||
loop {
|
||||
panes_to_resize.push(current_pane.pid());
|
||||
if current_pane.y() + current_pane.rows() == screen_height {
|
||||
return Some(panes_to_resize);
|
||||
}
|
||||
match find_next_increasable_vertical_pane(panes, ¤t_pane, increase_by) {
|
||||
Some(next_pane_id) => {
|
||||
current_pane = panes.get(&next_pane_id).unwrap();
|
||||
}
|
||||
None => {
|
||||
vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_reducible_horizontal_chain(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
reduce_by: usize,
|
||||
screen_width: usize,
|
||||
screen_height: usize, // TODO: this is the previous size (make this clearer)
|
||||
) -> Option<Vec<PaneId>> {
|
||||
let mut horizontal_coordinate = 0;
|
||||
loop {
|
||||
if horizontal_coordinate == screen_height {
|
||||
return None;
|
||||
}
|
||||
|
||||
match panes
|
||||
.values()
|
||||
.find(|p| p.x() == 0 && p.y() == horizontal_coordinate)
|
||||
{
|
||||
Some(leftmost_pane) => {
|
||||
if !leftmost_pane.can_reduce_height_by(reduce_by) {
|
||||
horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
|
||||
continue;
|
||||
}
|
||||
let mut panes_to_resize = vec![];
|
||||
let mut current_pane = leftmost_pane;
|
||||
loop {
|
||||
panes_to_resize.push(current_pane.pid());
|
||||
if current_pane.x() + current_pane.columns() == screen_width {
|
||||
return Some(panes_to_resize);
|
||||
}
|
||||
match find_next_reducible_horizontal_pane(panes, ¤t_pane, reduce_by) {
|
||||
Some(next_pane_id) => {
|
||||
current_pane = panes.get(&next_pane_id).unwrap();
|
||||
}
|
||||
None => {
|
||||
horizontal_coordinate = leftmost_pane.y() + leftmost_pane.rows() + 1;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_reducible_vertical_chain(
|
||||
panes: &BTreeMap<PaneId, Box<dyn Pane>>,
|
||||
increase_by: usize,
|
||||
screen_width: usize,
|
||||
screen_height: usize, // TODO: this is the previous size (make this clearer)
|
||||
) -> Option<Vec<PaneId>> {
|
||||
let mut vertical_coordinate = 0;
|
||||
loop {
|
||||
if vertical_coordinate == screen_width {
|
||||
return None;
|
||||
}
|
||||
|
||||
match panes
|
||||
.values()
|
||||
.find(|p| p.y() == 0 && p.x() == vertical_coordinate)
|
||||
{
|
||||
Some(topmost_pane) => {
|
||||
if !topmost_pane.can_reduce_width_by(increase_by) {
|
||||
vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
|
||||
continue;
|
||||
}
|
||||
let mut panes_to_resize = vec![];
|
||||
let mut current_pane = topmost_pane;
|
||||
loop {
|
||||
panes_to_resize.push(current_pane.pid());
|
||||
if current_pane.y() + current_pane.rows() == screen_height {
|
||||
return Some(panes_to_resize);
|
||||
}
|
||||
match find_next_reducible_vertical_pane(panes, ¤t_pane, increase_by) {
|
||||
Some(next_pane_id) => {
|
||||
current_pane = panes.get(&next_pane_id).unwrap();
|
||||
}
|
||||
None => {
|
||||
vertical_coordinate = topmost_pane.x() + topmost_pane.columns() + 1;
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -173,6 +173,18 @@ impl Pane for PluginPane {
|
||||
self.position_and_size.columns += count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn push_down(&mut self, count: usize) {
|
||||
self.position_and_size.y += count;
|
||||
}
|
||||
fn push_right(&mut self, count: usize) {
|
||||
self.position_and_size.x += count;
|
||||
}
|
||||
fn pull_left(&mut self, count: usize) {
|
||||
self.position_and_size.x -= count;
|
||||
}
|
||||
fn pull_up(&mut self, count: usize) {
|
||||
self.position_and_size.y -= count;
|
||||
}
|
||||
fn scroll_up(&mut self, _count: usize) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
@ -282,6 +282,18 @@ impl Pane for TerminalPane {
|
||||
self.position_and_size.columns += count;
|
||||
self.reflow_lines();
|
||||
}
|
||||
fn push_down(&mut self, count: usize) {
|
||||
self.position_and_size.y += count;
|
||||
}
|
||||
fn push_right(&mut self, count: usize) {
|
||||
self.position_and_size.x += count;
|
||||
}
|
||||
fn pull_left(&mut self, count: usize) {
|
||||
self.position_and_size.x -= count;
|
||||
}
|
||||
fn pull_up(&mut self, count: usize) {
|
||||
self.position_and_size.y -= count;
|
||||
}
|
||||
fn scroll_up(&mut self, count: usize) {
|
||||
self.grid.move_viewport_up(count);
|
||||
self.mark_for_rerender();
|
||||
|
@ -1,20 +1,23 @@
|
||||
//! `Tab`s holds multiple panes. It tracks their coordinates (x/y) and size,
|
||||
//! as well as how they should be resized
|
||||
|
||||
use crate::common::{colors, input::handler::parse_keys, AppInstruction, SenderWithContext};
|
||||
use crate::client::pane_resizer::PaneResizer;
|
||||
use crate::common::{input::handler::parse_keys, AppInstruction, SenderWithContext};
|
||||
use crate::layout::Layout;
|
||||
use crate::os_input_output::OsApi;
|
||||
use crate::panes::{PaneId, PositionAndSize, TerminalPane};
|
||||
use crate::pty_bus::{PtyInstruction, VteEvent};
|
||||
use crate::utils::shared::adjust_to_size;
|
||||
use crate::wasm_vm::PluginInstruction;
|
||||
use crate::{boundaries::Boundaries, panes::PluginPane};
|
||||
use crate::{os_input_output::OsApi, utils::shared::pad_to_size};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::{
|
||||
cmp::Reverse,
|
||||
collections::{BTreeMap, HashSet},
|
||||
};
|
||||
use std::{io::Write, sync::mpsc::channel};
|
||||
use zellij_tile::data::{Event, InputMode, ModeInfo, Palette};
|
||||
use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, colors};
|
||||
|
||||
const CURSOR_HEIGHT_WIDTH_RATIO: usize = 4; // this is not accurate and kind of a magic number, TODO: look into this
|
||||
const MIN_TERMINAL_HEIGHT: usize = 2;
|
||||
@ -65,6 +68,18 @@ pub struct Tab {
|
||||
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
expansion_boundary: Option<PositionAndSize>,
|
||||
should_clear_display_before_rendering: bool,
|
||||
pub mode_info: ModeInfo,
|
||||
pub input_mode: InputMode,
|
||||
pub colors: Palette
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||
pub struct TabData {
|
||||
/* subset of fields to publish to plugins */
|
||||
pub position: usize,
|
||||
pub name: String,
|
||||
pub active: bool,
|
||||
pub mode_info: ModeInfo,
|
||||
pub input_mode: InputMode,
|
||||
pub colors: Palette,
|
||||
@ -100,6 +115,10 @@ pub trait Pane {
|
||||
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 push_down(&mut self, count: usize);
|
||||
fn push_right(&mut self, count: usize);
|
||||
fn pull_left(&mut self, count: usize);
|
||||
fn pull_up(&mut self, count: usize);
|
||||
fn scroll_up(&mut self, count: usize);
|
||||
fn scroll_down(&mut self, count: usize);
|
||||
fn clear_scroll(&mut self);
|
||||
@ -154,6 +173,22 @@ pub trait Pane {
|
||||
rows: self.rows(),
|
||||
}
|
||||
}
|
||||
fn can_increase_height_by(&self, increase_by: usize) -> bool {
|
||||
self.max_height()
|
||||
.map(|max_height| self.rows() + increase_by <= max_height)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
fn can_increase_width_by(&self, increase_by: usize) -> bool {
|
||||
self.max_width()
|
||||
.map(|max_width| self.columns() + increase_by <= max_width)
|
||||
.unwrap_or(true)
|
||||
}
|
||||
fn can_reduce_height_by(&self, reduce_by: usize) -> bool {
|
||||
self.rows() > reduce_by && self.rows() - reduce_by >= self.min_height()
|
||||
}
|
||||
fn can_reduce_width_by(&self, reduce_by: usize) -> bool {
|
||||
self.columns() > reduce_by && self.columns() - reduce_by >= self.min_width()
|
||||
}
|
||||
fn min_width(&self) -> usize {
|
||||
MIN_TERMINAL_WIDTH
|
||||
}
|
||||
@ -216,6 +251,7 @@ impl Tab {
|
||||
send_pty_instructions,
|
||||
send_plugin_instructions,
|
||||
expansion_boundary: None,
|
||||
should_clear_display_before_rendering: false,
|
||||
mode_info,
|
||||
input_mode,
|
||||
colors,
|
||||
@ -635,28 +671,33 @@ impl Tab {
|
||||
stdout
|
||||
.write_all(&hide_cursor.as_bytes())
|
||||
.expect("cannot write to stdout");
|
||||
for (kind, terminal) in self.panes.iter_mut() {
|
||||
if !self.panes_to_hide.contains(&terminal.pid()) {
|
||||
match self.active_terminal.unwrap() == terminal.pid() {
|
||||
true => boundaries.add_rect(
|
||||
terminal.as_ref(),
|
||||
self.mode_info.mode,
|
||||
Some(self.colors),
|
||||
),
|
||||
false => boundaries.add_rect(terminal.as_ref(), self.mode_info.mode, None),
|
||||
if self.should_clear_display_before_rendering {
|
||||
let clear_display = "\u{1b}[2J";
|
||||
stdout
|
||||
.write_all(&clear_display.as_bytes())
|
||||
.expect("cannot write to stdout");
|
||||
self.should_clear_display_before_rendering = false;
|
||||
}
|
||||
if let Some(vte_output) = terminal.render() {
|
||||
for (kind, pane) in self.panes.iter_mut() {
|
||||
if !self.panes_to_hide.contains(&pane.pid()) {
|
||||
match self.active_terminal.unwrap() == pane.pid() {
|
||||
true => {
|
||||
boundaries.add_rect(pane.as_ref(), self.mode_info.mode, Some(self.colors))
|
||||
}
|
||||
false => boundaries.add_rect(pane.as_ref(), self.mode_info.mode, None),
|
||||
}
|
||||
if let Some(vte_output) = pane.render() {
|
||||
let vte_output = if let PaneId::Terminal(_) = kind {
|
||||
vte_output
|
||||
} else {
|
||||
pad_to_size(&vte_output, terminal.rows(), terminal.columns())
|
||||
adjust_to_size(&vte_output, pane.rows(), pane.columns())
|
||||
};
|
||||
// FIXME: Use Termion for cursor and style clearing?
|
||||
write!(
|
||||
stdout,
|
||||
"\u{1b}[{};{}H\u{1b}[m{}",
|
||||
terminal.y() + 1,
|
||||
terminal.x() + 1,
|
||||
pane.y() + 1,
|
||||
pane.x() + 1,
|
||||
vte_output
|
||||
)
|
||||
.expect("cannot write to stdout");
|
||||
@ -1669,17 +1710,30 @@ impl Tab {
|
||||
false
|
||||
}
|
||||
}
|
||||
pub fn resize_right(&mut self) {
|
||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||
let count = 10;
|
||||
if let Some(active_pane_id) = self.get_active_pane_id() {
|
||||
if self.can_increase_pane_and_surroundings_right(&active_pane_id, count) {
|
||||
self.increase_pane_and_surroundings_right(&active_pane_id, count);
|
||||
} else if self.can_reduce_pane_and_surroundings_right(&active_pane_id, count) {
|
||||
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
|
||||
pub fn resize_whole_tab(&mut self, new_screen_size: PositionAndSize) {
|
||||
if self.fullscreen_is_active {
|
||||
// this is not ideal but until we get rid of expansion_boundary, it's a necessity
|
||||
self.toggle_active_pane_fullscreen();
|
||||
}
|
||||
match PaneResizer::new(&mut self.panes, &mut self.os_api)
|
||||
.resize(self.full_screen_ws, new_screen_size)
|
||||
{
|
||||
Some((column_difference, row_difference)) => {
|
||||
self.should_clear_display_before_rendering = true;
|
||||
self.expansion_boundary.as_mut().map(|expansion_boundary| {
|
||||
// TODO: this is not always accurate
|
||||
expansion_boundary.columns =
|
||||
(expansion_boundary.columns as isize + column_difference) as usize;
|
||||
expansion_boundary.rows =
|
||||
(expansion_boundary.rows as isize + row_difference) as usize;
|
||||
});
|
||||
self.full_screen_ws.columns =
|
||||
(self.full_screen_ws.columns as isize + column_difference) as usize;
|
||||
self.full_screen_ws.rows =
|
||||
(self.full_screen_ws.rows as isize + row_difference) as usize;
|
||||
}
|
||||
self.render();
|
||||
None => {}
|
||||
};
|
||||
}
|
||||
pub fn resize_left(&mut self) {
|
||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||
@ -1693,6 +1747,18 @@ impl Tab {
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
pub fn resize_right(&mut self) {
|
||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||
let count = 10;
|
||||
if let Some(active_pane_id) = self.get_active_pane_id() {
|
||||
if self.can_increase_pane_and_surroundings_right(&active_pane_id, count) {
|
||||
self.increase_pane_and_surroundings_right(&active_pane_id, count);
|
||||
} else if self.can_reduce_pane_and_surroundings_right(&active_pane_id, count) {
|
||||
self.reduce_pane_and_surroundings_right(&active_pane_id, count);
|
||||
}
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
pub fn resize_down(&mut self) {
|
||||
// TODO: find out by how much we actually reduced and only reduce by that much
|
||||
let count = 2;
|
||||
|
@ -42,7 +42,7 @@ pub fn handle_panic(
|
||||
msg,
|
||||
location.file(),
|
||||
location.line(),
|
||||
backtrace
|
||||
backtrace,
|
||||
),
|
||||
(Some(location), None) => format!(
|
||||
"{}\n\u{1b}[0;0mError: \u{1b}[0;31mthread '{}' panicked: {}:{}\n\u{1b}[0;0m{:?}",
|
||||
@ -200,6 +200,7 @@ pub enum ScreenContext {
|
||||
CloseTab,
|
||||
GoToTab,
|
||||
UpdateTabName,
|
||||
TerminalResize,
|
||||
ChangeMode,
|
||||
}
|
||||
|
||||
@ -241,6 +242,7 @@ impl From<&ScreenInstruction> for ScreenContext {
|
||||
ScreenInstruction::CloseTab => ScreenContext::CloseTab,
|
||||
ScreenInstruction::GoToTab(_) => ScreenContext::GoToTab,
|
||||
ScreenInstruction::UpdateTabName(_) => ScreenContext::UpdateTabName,
|
||||
ScreenInstruction::TerminalResize => ScreenContext::TerminalResize,
|
||||
ScreenInstruction::ChangeMode(_) => ScreenContext::ChangeMode,
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,8 @@ impl InputHandler {
|
||||
}
|
||||
termion::event::Event::Mouse(_)
|
||||
| termion::event::Event::Unsupported(_) => {
|
||||
unimplemented!("Mouse and unsupported events aren't supported!");
|
||||
// Mouse and unsupported events aren't implemented yet,
|
||||
// use a NoOp untill then.
|
||||
}
|
||||
},
|
||||
Err(err) => panic!("Encountered read error: {:?}", err),
|
||||
|
@ -39,7 +39,9 @@ use wasm_vm::{wasi_stdout, wasi_write_string, zellij_imports, PluginInstruction}
|
||||
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
||||
use wasmer_wasi::{Pipe, WasiState};
|
||||
use xrdb::Colors;
|
||||
use zellij_tile::data::{EventType, InputMode, ModeInfo, Palette};
|
||||
use zellij_tile::data::{EventType, InputMode, ModeInfo, Palette, Theme};
|
||||
|
||||
use self::utils::logging::debug_log_to_file;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ApiCommand {
|
||||
@ -126,6 +128,19 @@ pub mod colors {
|
||||
pub const BLACK: (u8, u8, u8) = (0, 0, 0);
|
||||
}
|
||||
|
||||
pub fn detect_theme(bg: (u8, u8, u8)) -> Theme {
|
||||
let (r, g, b) = bg;
|
||||
// HSP, P stands for perceived brightness
|
||||
let hsp: f64 = (0.299 * (r as f64 * r as f64)
|
||||
+ 0.587 * (g as f64 * g as f64)
|
||||
+ 0.114 * (b as f64 * b as f64))
|
||||
.sqrt();
|
||||
match hsp > 127.5 {
|
||||
true => Theme::Light,
|
||||
false => Theme::Dark,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_palette() -> Palette {
|
||||
let palette = match Colors::new("xresources") {
|
||||
Some(colors) => {
|
||||
@ -150,7 +165,13 @@ pub fn load_palette() -> Palette {
|
||||
(rgb.0 as u8, rgb.1 as u8, rgb.2 as u8)
|
||||
})
|
||||
.collect();
|
||||
let theme = detect_theme(bg);
|
||||
debug_log_to_file(format!(
|
||||
"{:?} {:?}, white: {:?}, black: {:?}, fg: {:?}",
|
||||
theme, bg, colors[7], colors[0], fg
|
||||
));
|
||||
Palette {
|
||||
theme,
|
||||
fg,
|
||||
bg,
|
||||
black: colors[0],
|
||||
@ -164,6 +185,7 @@ pub fn load_palette() -> Palette {
|
||||
}
|
||||
}
|
||||
None => Palette {
|
||||
theme: Theme::Dark,
|
||||
fg: colors::BRIGHT_GRAY,
|
||||
bg: colors::BLACK,
|
||||
black: colors::BLACK,
|
||||
@ -459,6 +481,9 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
ScreenInstruction::UpdateTabName(c) => {
|
||||
screen.update_active_tab_name(c);
|
||||
}
|
||||
ScreenInstruction::TerminalResize => {
|
||||
screen.resize_to_screen();
|
||||
}
|
||||
ScreenInstruction::ChangeMode(mode_info) => {
|
||||
screen.change_mode(mode_info);
|
||||
}
|
||||
@ -576,6 +601,19 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let _signal_thread = thread::Builder::new()
|
||||
.name("signal_listener".to_string())
|
||||
.spawn({
|
||||
let os_input = os_input.clone();
|
||||
let send_screen_instructions = send_screen_instructions.clone();
|
||||
move || {
|
||||
os_input.receive_sigwinch(Box::new(move || {
|
||||
let _ = send_screen_instructions.send(ScreenInstruction::TerminalResize);
|
||||
}));
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
// TODO: currently we don't wait for this to quit
|
||||
// because otherwise the app will hang. Need to fix this so it both
|
||||
// listens to the ipc-bus and is able to quit cleanly
|
||||
|
@ -13,6 +13,8 @@ use std::path::PathBuf;
|
||||
use std::process::{Child, Command};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use signal_hook::{consts::signal::*, iterator::Signals};
|
||||
|
||||
use std::env;
|
||||
|
||||
fn into_raw_mode(pid: RawFd) {
|
||||
@ -65,7 +67,7 @@ pub fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) {
|
||||
/// process exits.
|
||||
fn handle_command_exit(mut child: Child) {
|
||||
// register the SIGINT signal (TODO handle more signals)
|
||||
let signals = ::signal_hook::iterator::Signals::new(&[::signal_hook::SIGINT]).unwrap();
|
||||
let mut signals = ::signal_hook::iterator::Signals::new(&[SIGINT]).unwrap();
|
||||
'handle_exit: loop {
|
||||
// test whether the child process has exited
|
||||
match child.try_wait() {
|
||||
@ -82,11 +84,16 @@ fn handle_command_exit(mut child: Child) {
|
||||
}
|
||||
|
||||
for signal in signals.pending() {
|
||||
if signal == signal_hook::SIGINT {
|
||||
// FIXME: We need to handle more signals here!
|
||||
#[allow(clippy::single_match)]
|
||||
match signal {
|
||||
SIGINT => {
|
||||
child.kill().unwrap();
|
||||
child.wait().unwrap();
|
||||
break 'handle_exit;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -188,6 +195,7 @@ pub trait OsApi: Send + Sync {
|
||||
fn get_stdout_writer(&self) -> Box<dyn io::Write>;
|
||||
/// Returns a [`Box`] pointer to this [`OsApi`] struct.
|
||||
fn box_clone(&self) -> Box<dyn OsApi>;
|
||||
fn receive_sigwinch(&self, cb: Box<dyn Fn()>);
|
||||
}
|
||||
|
||||
impl OsApi for OsInputOutput {
|
||||
@ -238,6 +246,20 @@ impl OsApi for OsInputOutput {
|
||||
waitpid(Pid::from_raw(pid), None).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
|
||||
let mut signals = Signals::new(&[SIGWINCH, SIGTERM, SIGINT, SIGQUIT]).unwrap();
|
||||
for signal in signals.forever() {
|
||||
match signal {
|
||||
SIGWINCH => {
|
||||
cb();
|
||||
}
|
||||
SIGTERM | SIGINT | SIGQUIT => {
|
||||
break;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Box<dyn OsApi> {
|
||||
|
@ -50,6 +50,7 @@ pub enum ScreenInstruction {
|
||||
CloseTab,
|
||||
GoToTab(u32),
|
||||
UpdateTabName(Vec<u8>),
|
||||
TerminalResize,
|
||||
ChangeMode(ModeInfo),
|
||||
}
|
||||
|
||||
@ -221,6 +222,15 @@ impl Screen {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resize_to_screen(&mut self) {
|
||||
let new_screen_size = self.os_api.get_terminal_size_using_fd(0);
|
||||
self.full_screen_ws = new_screen_size;
|
||||
for (_, tab) in self.tabs.iter_mut() {
|
||||
tab.resize_whole_tab(new_screen_size);
|
||||
}
|
||||
self.render();
|
||||
}
|
||||
|
||||
/// Renders this [`Screen`], which amounts to rendering its active [`Tab`].
|
||||
pub fn render(&mut self) {
|
||||
if let Some(active_tab) = self.get_active_tab_mut() {
|
||||
|
@ -11,9 +11,18 @@ fn ansi_len(s: &str) -> usize {
|
||||
.count()
|
||||
}
|
||||
|
||||
pub fn pad_to_size(s: &str, rows: usize, columns: usize) -> String {
|
||||
pub fn adjust_to_size(s: &str, rows: usize, columns: usize) -> String {
|
||||
s.lines()
|
||||
.map(|l| [l, &str::repeat(" ", columns - ansi_len(l))].concat())
|
||||
.map(|l| {
|
||||
let actual_len = ansi_len(l);
|
||||
if actual_len > columns {
|
||||
let mut line = String::from(l);
|
||||
line.truncate(columns);
|
||||
return line;
|
||||
} else {
|
||||
return [l, &str::repeat(" ", columns - ansi_len(l))].concat();
|
||||
}
|
||||
})
|
||||
.chain(iter::repeat(str::repeat(" ", columns)))
|
||||
.take(rows)
|
||||
.collect::<Vec<_>>()
|
||||
|
@ -3,14 +3,13 @@ use std::collections::{HashMap, VecDeque};
|
||||
use std::io::Write;
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::os_input_output::OsApi;
|
||||
use crate::tests::possible_tty_inputs::{get_possible_tty_inputs, Bytes};
|
||||
|
||||
use crate::tests::utils::commands::SLEEP;
|
||||
use crate::tests::utils::commands::{QUIT, SLEEP};
|
||||
|
||||
const MIN_TIME_BETWEEN_SNAPSHOTS: Duration = Duration::from_millis(50);
|
||||
|
||||
@ -72,7 +71,8 @@ pub struct FakeInputOutput {
|
||||
win_sizes: Arc<Mutex<HashMap<RawFd, PositionAndSize>>>,
|
||||
possible_tty_inputs: HashMap<u16, Bytes>,
|
||||
last_snapshot_time: Arc<Mutex<Instant>>,
|
||||
started_reading_from_pty: Arc<AtomicBool>,
|
||||
should_trigger_sigwinch: Arc<(Mutex<bool>, Condvar)>,
|
||||
sigwinch_event: Option<PositionAndSize>,
|
||||
}
|
||||
|
||||
impl FakeInputOutput {
|
||||
@ -91,7 +91,8 @@ impl FakeInputOutput {
|
||||
io_events: Arc::new(Mutex::new(vec![])),
|
||||
win_sizes: Arc::new(Mutex::new(win_sizes)),
|
||||
possible_tty_inputs: get_possible_tty_inputs(),
|
||||
started_reading_from_pty: Arc::new(AtomicBool::new(false)),
|
||||
should_trigger_sigwinch: Arc::new((Mutex::new(false), Condvar::new())),
|
||||
sigwinch_event: None,
|
||||
}
|
||||
}
|
||||
pub fn with_tty_inputs(mut self, tty_inputs: HashMap<u16, Bytes>) -> Self {
|
||||
@ -108,10 +109,20 @@ impl FakeInputOutput {
|
||||
pub fn add_terminal(&mut self, fd: RawFd) {
|
||||
self.stdin_writes.lock().unwrap().insert(fd, vec![]);
|
||||
}
|
||||
pub fn add_sigwinch_event(&mut self, new_position_and_size: PositionAndSize) {
|
||||
self.sigwinch_event = Some(new_position_and_size);
|
||||
}
|
||||
}
|
||||
|
||||
impl OsApi for FakeInputOutput {
|
||||
fn get_terminal_size_using_fd(&self, pid: RawFd) -> PositionAndSize {
|
||||
if let Some(new_position_and_size) = self.sigwinch_event {
|
||||
let (lock, _cvar) = &*self.should_trigger_sigwinch;
|
||||
let should_trigger_sigwinch = lock.lock().unwrap();
|
||||
if *should_trigger_sigwinch && pid == 0 {
|
||||
return new_position_and_size;
|
||||
}
|
||||
}
|
||||
let win_sizes = self.win_sizes.lock().unwrap();
|
||||
let winsize = win_sizes.get(&pid).unwrap();
|
||||
*winsize
|
||||
@ -159,7 +170,6 @@ impl OsApi for FakeInputOutput {
|
||||
if bytes_read > bytes.read_position {
|
||||
bytes.set_read_position(bytes_read);
|
||||
}
|
||||
self.started_reading_from_pty.store(true, Ordering::Release);
|
||||
return Ok(bytes_read);
|
||||
}
|
||||
None => Err(nix::Error::Sys(nix::errno::Errno::EAGAIN)),
|
||||
@ -199,6 +209,12 @@ impl OsApi for FakeInputOutput {
|
||||
.unwrap_or(vec![]);
|
||||
if command == SLEEP {
|
||||
std::thread::sleep(std::time::Duration::from_millis(200));
|
||||
} else if command == QUIT && self.sigwinch_event.is_some() {
|
||||
let (lock, cvar) = &*self.should_trigger_sigwinch;
|
||||
let mut should_trigger_sigwinch = lock.lock().unwrap();
|
||||
*should_trigger_sigwinch = true;
|
||||
cvar.notify_one();
|
||||
::std::thread::sleep(MIN_TIME_BETWEEN_SNAPSHOTS); // give some time for the app to resize before quitting
|
||||
}
|
||||
command
|
||||
}
|
||||
@ -209,4 +225,14 @@ impl OsApi for FakeInputOutput {
|
||||
self.io_events.lock().unwrap().push(IoEvent::Kill(fd));
|
||||
Ok(())
|
||||
}
|
||||
fn receive_sigwinch(&self, cb: Box<dyn Fn()>) {
|
||||
if self.sigwinch_event.is_some() {
|
||||
let (lock, cvar) = &*self.should_trigger_sigwinch;
|
||||
let mut should_trigger_sigwinch = lock.lock().unwrap();
|
||||
while !*should_trigger_sigwinch {
|
||||
should_trigger_sigwinch = cvar.wait(should_trigger_sigwinch).unwrap();
|
||||
}
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots}
|
||||
use crate::{start, CliArgs};
|
||||
|
||||
use crate::tests::utils::commands::{
|
||||
CLOSE_PANE_IN_PANE_MODE, COMMAND_TOGGLE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT,
|
||||
CLOSE_PANE_IN_PANE_MODE, ESC, MOVE_FOCUS_IN_PANE_MODE, PANE_MODE, QUIT,
|
||||
RESIZE_DOWN_IN_RESIZE_MODE, RESIZE_LEFT_IN_RESIZE_MODE, RESIZE_MODE, RESIZE_UP_IN_RESIZE_MODE,
|
||||
SPLIT_DOWN_IN_PANE_MODE, SPLIT_RIGHT_IN_PANE_MODE,
|
||||
};
|
||||
|
@ -12,4 +12,5 @@ pub mod resize_left;
|
||||
pub mod resize_right;
|
||||
pub mod resize_up;
|
||||
pub mod tabs;
|
||||
pub mod terminal_window_resize;
|
||||
pub mod toggle_fullscreen;
|
||||
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
source: src/tests/integration/terminal_window_resize.rs
|
||||
expression: snapshot_before_quit
|
||||
|
||||
---
|
||||
line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
█
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
source: src/tests/integration/terminal_window_resize.rs
|
||||
expression: snapshot_before_quit
|
||||
|
||||
---
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
prompt $ █
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
source: src/tests/integration/terminal_window_resize.rs
|
||||
expression: snapshot_before_quit
|
||||
|
||||
---
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
prompt $ █
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
source: src/tests/integration/terminal_window_resize.rs
|
||||
expression: snapshot_before_quit
|
||||
|
||||
---
|
||||
line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line17-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line18-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
line19-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
prompt $
|
||||
█
|
127
src/tests/integration/terminal_window_resize.rs
Normal file
127
src/tests/integration/terminal_window_resize.rs
Normal file
@ -0,0 +1,127 @@
|
||||
use crate::panes::PositionAndSize;
|
||||
use ::insta::assert_snapshot;
|
||||
|
||||
use crate::tests::fakes::FakeInputOutput;
|
||||
use crate::tests::utils::commands::QUIT;
|
||||
use crate::tests::utils::{get_next_to_last_snapshot, get_output_frame_snapshots};
|
||||
use crate::{start, CliArgs};
|
||||
|
||||
fn get_fake_os_input(fake_win_size: &PositionAndSize) -> FakeInputOutput {
|
||||
FakeInputOutput::new(fake_win_size.clone())
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn window_width_decrease_with_one_pane() {
|
||||
let fake_win_size = PositionAndSize {
|
||||
columns: 121,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
let mut fake_input_output = get_fake_os_input(&fake_win_size);
|
||||
fake_input_output.add_terminal_input(&[&QUIT]);
|
||||
fake_input_output.add_sigwinch_event(PositionAndSize {
|
||||
columns: 90,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
let opts = CliArgs::default();
|
||||
start(Box::new(fake_input_output.clone()), opts);
|
||||
let output_frames = fake_input_output
|
||||
.stdout_writer
|
||||
.output_frames
|
||||
.lock()
|
||||
.unwrap();
|
||||
let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
|
||||
let snapshot_before_quit =
|
||||
get_next_to_last_snapshot(snapshots).expect("could not find snapshot");
|
||||
assert_snapshot!(snapshot_before_quit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn window_width_increase_with_one_pane() {
|
||||
let fake_win_size = PositionAndSize {
|
||||
columns: 121,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
let mut fake_input_output = get_fake_os_input(&fake_win_size);
|
||||
fake_input_output.add_terminal_input(&[&QUIT]);
|
||||
fake_input_output.add_sigwinch_event(PositionAndSize {
|
||||
columns: 141,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
let opts = CliArgs::default();
|
||||
start(Box::new(fake_input_output.clone()), opts);
|
||||
let output_frames = fake_input_output
|
||||
.stdout_writer
|
||||
.output_frames
|
||||
.lock()
|
||||
.unwrap();
|
||||
let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
|
||||
let snapshot_before_quit =
|
||||
get_next_to_last_snapshot(snapshots).expect("could not find snapshot");
|
||||
assert_snapshot!(snapshot_before_quit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn window_height_increase_with_one_pane() {
|
||||
let fake_win_size = PositionAndSize {
|
||||
columns: 121,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
let mut fake_input_output = get_fake_os_input(&fake_win_size);
|
||||
fake_input_output.add_terminal_input(&[&QUIT]);
|
||||
fake_input_output.add_sigwinch_event(PositionAndSize {
|
||||
columns: 121,
|
||||
rows: 30,
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
let opts = CliArgs::default();
|
||||
start(Box::new(fake_input_output.clone()), opts);
|
||||
let output_frames = fake_input_output
|
||||
.stdout_writer
|
||||
.output_frames
|
||||
.lock()
|
||||
.unwrap();
|
||||
let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
|
||||
let snapshot_before_quit =
|
||||
get_next_to_last_snapshot(snapshots).expect("could not find snapshot");
|
||||
assert_snapshot!(snapshot_before_quit);
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn window_width_and_height_decrease_with_one_pane() {
|
||||
let fake_win_size = PositionAndSize {
|
||||
columns: 121,
|
||||
rows: 20,
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
let mut fake_input_output = get_fake_os_input(&fake_win_size);
|
||||
fake_input_output.add_terminal_input(&[&QUIT]);
|
||||
fake_input_output.add_sigwinch_event(PositionAndSize {
|
||||
columns: 90,
|
||||
rows: 10,
|
||||
x: 0,
|
||||
y: 0,
|
||||
});
|
||||
let opts = CliArgs::default();
|
||||
start(Box::new(fake_input_output.clone()), opts);
|
||||
let output_frames = fake_input_output
|
||||
.stdout_writer
|
||||
.output_frames
|
||||
.lock()
|
||||
.unwrap();
|
||||
let snapshots = get_output_frame_snapshots(&output_frames, &fake_win_size);
|
||||
let snapshot_before_quit =
|
||||
get_next_to_last_snapshot(snapshots).expect("could not find snapshot");
|
||||
assert_snapshot!(snapshot_before_quit);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
use crate::tests::tty_inputs::{
|
||||
COL_10, COL_121, COL_14, COL_15, COL_19, COL_20, COL_24, COL_25, COL_29, COL_30, COL_34,
|
||||
COL_39, COL_4, COL_40, COL_47, COL_50, COL_60, COL_70, COL_8, COL_9, COL_90, COL_96,
|
||||
COL_10, COL_121, COL_14, COL_141, COL_15, COL_19, COL_20, COL_24, COL_25, COL_29, COL_30,
|
||||
COL_34, COL_39, COL_4, COL_40, COL_47, COL_50, COL_60, COL_70, COL_8, COL_80, COL_9, COL_90,
|
||||
COL_96,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@ -69,9 +70,11 @@ pub fn get_possible_tty_inputs() -> HashMap<u16, Bytes> {
|
||||
let col_50_bytes = Bytes::new().content_from_str(&COL_50);
|
||||
let col_60_bytes = Bytes::new().content_from_str(&COL_60);
|
||||
let col_70_bytes = Bytes::new().content_from_str(&COL_70);
|
||||
let col_80_bytes = Bytes::new().content_from_str(&COL_80);
|
||||
let col_90_bytes = Bytes::new().content_from_str(&COL_90);
|
||||
let col_96_bytes = Bytes::new().content_from_str(&COL_96);
|
||||
let col_121_bytes = Bytes::new().content_from_str(&COL_121);
|
||||
let col_141_bytes = Bytes::new().content_from_str(&COL_141);
|
||||
possible_inputs.insert(4, col_4_bytes);
|
||||
possible_inputs.insert(8, col_8_bytes);
|
||||
possible_inputs.insert(9, col_9_bytes);
|
||||
@ -91,8 +94,10 @@ pub fn get_possible_tty_inputs() -> HashMap<u16, Bytes> {
|
||||
possible_inputs.insert(50, col_50_bytes);
|
||||
possible_inputs.insert(60, col_60_bytes);
|
||||
possible_inputs.insert(70, col_70_bytes);
|
||||
possible_inputs.insert(80, col_80_bytes);
|
||||
possible_inputs.insert(90, col_90_bytes);
|
||||
possible_inputs.insert(96, col_96_bytes);
|
||||
possible_inputs.insert(121, col_121_bytes);
|
||||
possible_inputs.insert(141, col_141_bytes);
|
||||
possible_inputs
|
||||
}
|
||||
|
@ -1,3 +1,26 @@
|
||||
pub const COL_141: [&str; 20] = [
|
||||
"line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line3-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line4-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line5-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line6-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line7-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line8-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line9-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line10-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line11-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line12-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line13-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line14-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line15-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line16-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line17-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line18-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line19-baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"prompt $ ",
|
||||
];
|
||||
|
||||
pub const COL_121: [&str; 20] = [
|
||||
"line1-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
"line2-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\r\n",
|
||||
@ -457,6 +480,29 @@ pub const COL_70: [&str; 20] = [
|
||||
"prompt $ ",
|
||||
];
|
||||
|
||||
pub const COL_80: [&str; 20] = [
|
||||
"line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line3-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line4-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line5-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line6-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line7-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line8-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line9-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line10-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line11-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line12-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line13-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line14-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line15-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line16-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line17-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line18-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line19-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"prompt $ ",
|
||||
];
|
||||
|
||||
pub const COL_90: [&str; 20] = [
|
||||
"line1-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
"line2-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\n",
|
||||
|
@ -45,7 +45,6 @@ pub fn get_next_to_last_snapshot(mut snapshots: Vec<String>) -> Option<String> {
|
||||
}
|
||||
|
||||
pub mod commands {
|
||||
pub const COMMAND_TOGGLE: [u8; 1] = [7]; // ctrl-g
|
||||
pub const QUIT: [u8; 1] = [17]; // ctrl-q
|
||||
pub const ESC: [u8; 1] = [27];
|
||||
|
||||
|
@ -58,6 +58,11 @@ impl Default for InputMode {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum Theme {
|
||||
Light,
|
||||
Dark
|
||||
}
|
||||
pub mod colors {
|
||||
pub const WHITE: (u8, u8, u8) = (238, 238, 238);
|
||||
pub const GREEN: (u8, u8, u8) = (175, 255, 0);
|
||||
@ -69,6 +74,7 @@ pub mod colors {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct Palette {
|
||||
pub theme: Theme,
|
||||
pub fg: (u8, u8, u8),
|
||||
pub bg: (u8, u8, u8),
|
||||
pub black: (u8, u8, u8),
|
||||
@ -84,6 +90,7 @@ pub struct Palette {
|
||||
impl Default for Palette {
|
||||
fn default() -> Palette {
|
||||
Palette {
|
||||
theme: Theme::Dark,
|
||||
fg: colors::BRIGHT_GRAY,
|
||||
bg: colors::BLACK,
|
||||
black: colors::BLACK,
|
||||
|
Loading…
Reference in New Issue
Block a user