* fix(compatibility): handle inserting characters in the middle of a line after a wide character * style(fmt): make rustfmt happy
1056 lines
32 KiB
Rust
1056 lines
32 KiB
Rust
use super::super::Grid;
|
|
use ::insta::assert_snapshot;
|
|
use zellij_utils::{position::Position, vte, zellij_tile::data::Palette};
|
|
|
|
fn read_fixture(fixture_name: &str) -> Vec<u8> {
|
|
let mut path_to_file = std::path::PathBuf::new();
|
|
path_to_file.push("../src");
|
|
path_to_file.push("tests");
|
|
path_to_file.push("fixtures");
|
|
path_to_file.push(fixture_name);
|
|
std::fs::read(path_to_file)
|
|
.unwrap_or_else(|_| panic!("could not read fixture {:?}", &fixture_name))
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_0() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-0";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_1() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-1";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_2() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-2";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_3() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-3";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_4() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-4";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest1_5() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest1-5";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_0() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-0";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_1() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-1";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_2() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-2";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_3() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-3";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_4() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-4";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_5() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-5";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_6() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-6";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_7() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-7";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_8() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-8";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_9() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-9";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_10() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-10";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_11() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-11";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_12() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-12";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_13() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-13";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest2_14() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest2-14";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest3_0() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(41, 110, Palette::default());
|
|
let fixture_name = "vttest3-0";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_0() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-0";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_1() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-1";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_2() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-2";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_3() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-3";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_4() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-4";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn vttest8_5() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "vttest8-5";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn csi_b() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "csi-b";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn csi_capital_i() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "csi-capital-i";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn csi_capital_z() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "csi-capital-z";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn terminal_reports() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(51, 97, Palette::default());
|
|
let fixture_name = "terminal_reports";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid.pending_messages_to_pty));
|
|
}
|
|
|
|
#[test]
|
|
fn wide_characters() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "wide_characters";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn wide_characters_line_wrap() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "wide_characters_line_wrap";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn insert_character_in_line_with_wide_character() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "wide_characters_middle_line_insert";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn fish_wide_characters_override_clock() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "fish_wide_characters_override_clock";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn bash_delete_wide_characters() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "bash_delete_wide_characters";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn delete_wide_characters_before_cursor() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "delete_wide_characters_before_cursor";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn delete_wide_characters_before_cursor_when_cursor_is_on_wide_character() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "delete_wide_characters_before_cursor_when_cursor_is_on_wide_character";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn delete_wide_character_under_cursor() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "delete_wide_character_under_cursor";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn replace_wide_character_under_cursor() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 104, Palette::default());
|
|
let fixture_name = "replace_wide_character_under_cursor";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn wrap_wide_characters() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 90, Palette::default());
|
|
let fixture_name = "wide_characters_full";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn wrap_wide_characters_on_size_change() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 93, Palette::default());
|
|
let fixture_name = "wide_characters_full";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.change_size(21, 90);
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn unwrap_wide_characters_on_size_change() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 93, Palette::default());
|
|
let fixture_name = "wide_characters_full";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.change_size(21, 90);
|
|
grid.change_size(21, 93);
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn wrap_wide_characters_in_the_middle_of_the_line() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 91, Palette::default());
|
|
let fixture_name = "wide_characters_line_middle";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn wrap_wide_characters_at_the_end_of_the_line() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 90, Palette::default());
|
|
let fixture_name = "wide_characters_line_end";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn copy_selected_text_from_viewport() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(27, 125, Palette::default());
|
|
let fixture_name = "grid_copy";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
|
|
grid.start_selection(&Position::new(23, 6));
|
|
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
|
grid.end_selection(Some(&Position::new(25, 35)));
|
|
let text = grid.get_selected_text();
|
|
assert_eq!(
|
|
text.unwrap(),
|
|
"mauris in aliquam sem fringilla.\n\nzellij on mouse-support [?] is 📦"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn copy_selected_text_from_lines_above() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(27, 125, Palette::default());
|
|
let fixture_name = "grid_copy";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
|
|
grid.start_selection(&Position::new(-2, 10));
|
|
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
|
grid.end_selection(Some(&Position::new(2, 8)));
|
|
let text = grid.get_selected_text();
|
|
assert_eq!(
|
|
text.unwrap(),
|
|
"eu scelerisque felis imperdiet proin fermentum leo.\nCursus risus at ultrices mi tempus.\nLaoreet id donec ultrices tincidunt arcu non sodales.\nAmet dictum sit amet justo donec enim.\nHac habi"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn copy_selected_text_from_lines_below() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(27, 125, Palette::default());
|
|
let fixture_name = "grid_copy";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
|
|
grid.move_viewport_up(40);
|
|
|
|
grid.start_selection(&Position::new(63, 6));
|
|
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
|
grid.end_selection(Some(&Position::new(65, 35)));
|
|
let text = grid.get_selected_text();
|
|
assert_eq!(
|
|
text.unwrap(),
|
|
"mauris in aliquam sem fringilla.\n\nzellij on mouse-support [?] is 📦"
|
|
);
|
|
}
|
|
|
|
/*
|
|
* These tests below are general compatibility tests for non-trivial scenarios running in the terminal.
|
|
* They use fake TTY input replicated from these scenarios.
|
|
*
|
|
*/
|
|
|
|
#[test]
|
|
fn run_bandwhich_from_fish_shell() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "fish_and_bandwhich";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
fn fish_tab_completion_options() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "fish_tab_completion_options";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn fish_select_tab_completion_options() {
|
|
// the difference between this and the previous test is that here we press <TAB>
|
|
// twice, meaning the selection moves between the options and the command line
|
|
// changes.
|
|
// this is not clearly seen in the snapshot because it does not include styles,
|
|
// but we can see the command line change and the cursor staying in place
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "fish_select_tab_completion_options";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn vim_scroll_region_down() {
|
|
// here we test a case where vim defines the scroll region as lesser than the screen row count
|
|
// and then scrolls down
|
|
// the region is defined here by vim as 1-26 (there are 28 rows)
|
|
// then the cursor is moved to line 26 and a new line is added
|
|
// what should happen is that the first line in the scroll region (1) is deleted
|
|
// and an empty line is inserted in the last scroll region line (26)
|
|
// this tests also has other steps afterwards that fills the line with the next line in the
|
|
// file
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "vim_scroll_region_down";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn vim_ctrl_d() {
|
|
// in vim ctrl-d moves down half a page
|
|
// in this case, it sends the terminal the csi 'M' directive, which tells it to delete X (13 in
|
|
// this case) lines inside the scroll region and push the other lines up
|
|
// what happens here is that 13 lines are deleted and instead 13 empty lines are added at the
|
|
// end of the scroll region
|
|
// vim makes sure to fill these empty lines with the rest of the file
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "vim_ctrl_d";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn vim_ctrl_u() {
|
|
// in vim ctrl-u moves up half a page
|
|
// in this case, it sends the terminal the csi 'L' directive, which tells it to insert X (13 in
|
|
// this case) lines at the cursor, pushing away (deleting) the last line in the scroll region
|
|
// this causes the effect of scrolling up X lines (vim replaces the lines with the ones in the
|
|
// file above the current content)
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "vim_ctrl_u";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn htop() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "htop";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn htop_scrolling() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "htop_scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn htop_right_scrolling() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "htop_right_scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn vim_overwrite() {
|
|
// this tests the vim overwrite message
|
|
// to recreate:
|
|
// * open a file in vim
|
|
// * open the same file in another window
|
|
// * change the file in the other window and save
|
|
// * change the file in the original vim window and save
|
|
// * confirm you would like to change the file by pressing 'y' and then ENTER
|
|
// * if everything looks fine, this test passed :)
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "vim_overwrite";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn clear_scroll_region() {
|
|
// this is actually a test of 1049h/l (alternative buffer)
|
|
// @imsnif - the name is a monument to the time I didn't fully understand this mechanism :)
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "clear_scroll_region";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn display_tab_characters_properly() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "tab_characters";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn neovim_insert_mode() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "nvim_insert";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn bash_cursor_linewrap() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 116, Palette::default());
|
|
let fixture_name = "bash_cursor_linewrap";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn fish_paste_multiline() {
|
|
// here we paste a multiline command in fish shell, making sure we support it
|
|
// going up and changing the colors of our line-wrapped pasted text
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 149, Palette::default());
|
|
let fixture_name = "fish_paste_multiline";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn git_log() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 149, Palette::default());
|
|
let fixture_name = "git_log";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn git_diff_scrollup() {
|
|
// this tests makes sure that when we have a git diff that exceeds the screen size
|
|
// we are able to scroll up
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(28, 149, Palette::default());
|
|
let fixture_name = "git_diff_scrollup";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn emacs_longbuf() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(60, 284, Palette::default());
|
|
let fixture_name = "emacs_longbuf_tutorial";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn top_and_quit() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(56, 235, Palette::default());
|
|
let fixture_name = "top_and_quit";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn exa_plus_omf_theme() {
|
|
// this tests that we handle a tab delimited table properly
|
|
// without overriding the previous content
|
|
// this is a potential bug because the \t character is a goto
|
|
// if we forwarded it as is to the terminal, we would be skipping
|
|
// over existing on-screen content without deleting it, so we must
|
|
// convert it to spaces
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(56, 235, Palette::default());
|
|
let fixture_name = "exa_plus_omf_theme";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_up() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 50, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.scroll_up_one_line();
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_down() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 50, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.scroll_up_one_line();
|
|
grid.scroll_down_one_line();
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_up_with_line_wraps() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 25, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.scroll_up_one_line();
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_down_with_line_wraps() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 25, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.scroll_up_one_line();
|
|
grid.scroll_down_one_line();
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_up_decrease_width_and_scroll_down() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 50, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
for _ in 0..10 {
|
|
grid.scroll_up_one_line();
|
|
}
|
|
grid.change_size(10, 25);
|
|
for _ in 0..10 {
|
|
grid.scroll_down_one_line();
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn scroll_up_increase_width_and_scroll_down() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(10, 25, Palette::default());
|
|
let fixture_name = "scrolling";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
for _ in 0..10 {
|
|
grid.scroll_up_one_line();
|
|
}
|
|
grid.change_size(10, 50);
|
|
for _ in 0..10 {
|
|
grid.scroll_down_one_line();
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn move_cursor_below_scroll_region() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(34, 114, Palette::default());
|
|
let fixture_name = "move_cursor_below_scroll_region";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn insert_wide_characters_in_existing_line() {
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(21, 86, Palette::default());
|
|
let fixture_name = "chinese_characters_line_middle";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|
|
|
|
#[test]
|
|
pub fn full_screen_scroll_region_and_scroll_up() {
|
|
// this test is a regression test for a bug
|
|
// where the scroll region would be set to the
|
|
// full viewport and then scrolling up would cause
|
|
// lines to get deleted from the viewport rather
|
|
// than moving to "lines_above"
|
|
let mut vte_parser = vte::Parser::new();
|
|
let mut grid = Grid::new(54, 80, Palette::default());
|
|
let fixture_name = "scroll_region_full_screen";
|
|
let content = read_fixture(fixture_name);
|
|
for byte in content {
|
|
vte_parser.advance(&mut grid, byte);
|
|
}
|
|
grid.scroll_up_one_line();
|
|
grid.scroll_up_one_line();
|
|
grid.scroll_up_one_line();
|
|
assert_snapshot!(format!("{:?}", grid));
|
|
}
|