mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
term: restore line length pre-allocation
A while back I made the line lengths lazily grown; the reduction in memory was nice, and it helped with render performance for really wide screens. Unfortunately, it puts a bunch of reallocation into the hot path of the parser and updating the terminal model when people run the inevitable `cat giant-file.txt` benchmark. This commit reinstates pre-allocating lines to match the physical terminal width, and tweaks the code a bit to take advantage of const Cell allocation and to avoid some clones (a really micro optimization).
This commit is contained in:
parent
9134da8c07
commit
6c2f9f2d18
@ -63,7 +63,7 @@ impl Screen {
|
||||
let mut lines =
|
||||
VecDeque::with_capacity(physical_rows + scrollback_size(config, allow_scrollback));
|
||||
for _ in 0..physical_rows {
|
||||
lines.push_back(Line::with_width(0));
|
||||
lines.push_back(Line::with_width(physical_cols));
|
||||
}
|
||||
|
||||
Screen {
|
||||
@ -215,7 +215,7 @@ impl Screen {
|
||||
// lines than the viewport size, or we resized taller,
|
||||
// pad us back out to the viewport size
|
||||
while self.lines.len() < physical_rows {
|
||||
self.lines.push_back(Line::with_width(0));
|
||||
self.lines.push_back(Line::with_width(self.physical_cols));
|
||||
}
|
||||
|
||||
let new_cursor_y;
|
||||
@ -236,7 +236,7 @@ impl Screen {
|
||||
physical_rows.saturating_sub(new_cursor_y as usize);
|
||||
let actual_num_rows_after_cursor = self.lines.len().saturating_sub(cursor_y);
|
||||
for _ in actual_num_rows_after_cursor..required_num_rows_after_cursor {
|
||||
self.lines.push_back(Line::with_width(0));
|
||||
self.lines.push_back(Line::with_width(self.physical_cols));
|
||||
}
|
||||
} else {
|
||||
// Compute the new cursor location; this is logically the inverse
|
||||
@ -595,7 +595,7 @@ impl Screen {
|
||||
for _ in 0..to_move {
|
||||
let mut line = self.lines.remove(remove_idx).unwrap();
|
||||
// Make the line like a new one of the appropriate width
|
||||
line.resize_and_clear(0, seqno);
|
||||
line.resize_and_clear(self.physical_cols, seqno);
|
||||
line.update_last_change_seqno(seqno);
|
||||
if scroll_region.end as usize == self.physical_rows {
|
||||
self.lines.push_back(line);
|
||||
@ -620,11 +620,12 @@ impl Screen {
|
||||
if scroll_region.end as usize == self.physical_rows {
|
||||
// It's cheaper to push() than it is insert() at the end
|
||||
for _ in 0..to_add {
|
||||
self.lines.push_back(Line::with_width(0));
|
||||
self.lines.push_back(Line::with_width(self.physical_cols));
|
||||
}
|
||||
} else {
|
||||
for _ in 0..to_add {
|
||||
self.lines.insert(phys_scroll.end, Line::with_width(0));
|
||||
self.lines
|
||||
.insert(phys_scroll.end, Line::with_width(self.physical_cols));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -672,7 +673,8 @@ impl Screen {
|
||||
}
|
||||
|
||||
for _ in 0..num_rows {
|
||||
self.lines.insert(phys_scroll.start, Line::with_width(0));
|
||||
self.lines
|
||||
.insert(phys_scroll.start, Line::with_width(self.physical_cols));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,7 @@ impl<'a> Performer<'a> {
|
||||
let seqno = self.seqno;
|
||||
let mut p = std::mem::take(&mut self.print);
|
||||
|
||||
let mut graphemes =
|
||||
unicode_segmentation::UnicodeSegmentation::graphemes(p.as_str(), true).peekable();
|
||||
|
||||
while let Some(g) = graphemes.next() {
|
||||
for g in unicode_segmentation::UnicodeSegmentation::graphemes(p.as_str(), true) {
|
||||
let g = if (self.shift_out && self.g1_charset == CharSet::DecLineDrawing)
|
||||
|| (!self.shift_out && self.g0_charset == CharSet::DecLineDrawing)
|
||||
{
|
||||
@ -138,7 +135,6 @@ impl<'a> Performer<'a> {
|
||||
// If we didn't do this, then we'd effectively filter them out from
|
||||
// the model, which seems like a lossy design choice.
|
||||
let print_width = grapheme_column_width(g).max(1);
|
||||
let is_last = graphemes.peek().is_none();
|
||||
let wrappable = x + print_width >= width;
|
||||
|
||||
let cell = Cell::new_grapheme_with_width(g, print_width, pen);
|
||||
@ -153,10 +149,9 @@ impl<'a> Performer<'a> {
|
||||
|
||||
// Assign the cell
|
||||
log::trace!(
|
||||
"print x={} y={} is_last={} print_width={} width={} cell={:?}",
|
||||
"print x={} y={} print_width={} width={} cell={:?}",
|
||||
x,
|
||||
y,
|
||||
is_last,
|
||||
print_width,
|
||||
width,
|
||||
cell
|
||||
|
@ -7,12 +7,12 @@ fn test_ind() {
|
||||
let mut term = TestTerm::new(4, 4, 0);
|
||||
term.print("a\r\nb\x1bD");
|
||||
term.assert_cursor_pos(1, 2, None, None);
|
||||
assert_visible_contents(&term, file!(), line!(), &["a", "b", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["a ", "b ", " ", " "]);
|
||||
term.print("\x1bD");
|
||||
term.assert_cursor_pos(1, 3, None, None);
|
||||
term.print("\x1bD");
|
||||
term.assert_cursor_pos(1, 3, None, Some(term.current_seqno() - 1));
|
||||
assert_visible_contents(&term, file!(), line!(), &["b", "", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["b ", " ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -24,7 +24,7 @@ fn test_nel() {
|
||||
term.assert_cursor_pos(0, 3, None, None);
|
||||
term.print("\x1bE");
|
||||
term.assert_cursor_pos(0, 3, None, None);
|
||||
assert_visible_contents(&term, file!(), line!(), &["b", "", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["b ", " ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -57,7 +57,7 @@ fn test_hts() {
|
||||
fn test_ri() {
|
||||
let mut term = TestTerm::new(4, 2, 0);
|
||||
term.print("a\r\nb\r\nc\r\nd.");
|
||||
assert_visible_contents(&term, file!(), line!(), &["a", "b", "c", "d."]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["a ", "b ", "c ", "d."]);
|
||||
term.assert_cursor_pos(1, 3, None, None);
|
||||
term.print("\x1bM");
|
||||
term.assert_cursor_pos(1, 2, None, None);
|
||||
@ -68,5 +68,5 @@ fn test_ri() {
|
||||
let seqno = term.current_seqno();
|
||||
term.print("\x1bM");
|
||||
term.assert_cursor_pos(1, 0, None, Some(seqno));
|
||||
assert_visible_contents(&term, file!(), line!(), &["", "a", "b", "c"]);
|
||||
assert_visible_contents(&term, file!(), line!(), &[" ", "a ", "b ", "c "]);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ fn test_rep() {
|
||||
term.print("h");
|
||||
term.cup(1, 0);
|
||||
term.print("\x1b[2ba");
|
||||
assert_visible_contents(&term, file!(), line!(), &["hhha", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["hhha", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -34,7 +34,12 @@ fn test_irm() {
|
||||
term.print("foo");
|
||||
term.cup(0, 0);
|
||||
term.print("\x1b[4hBAR");
|
||||
assert_visible_contents(&term, file!(), line!(), &["BARfoo", "", ""]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["BARfoo ", " ", " "],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -43,12 +48,12 @@ fn test_ich() {
|
||||
term.print("hey!wat?");
|
||||
term.cup(1, 0);
|
||||
term.print("\x1b[2@");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h e", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h e", "wat?", " "]);
|
||||
// check how we handle overflowing the width
|
||||
term.print("\x1b[12@");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", " "]);
|
||||
term.print("\x1b[-12@");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -57,12 +62,12 @@ fn test_ech() {
|
||||
term.print("hey!wat?");
|
||||
term.cup(1, 0);
|
||||
term.print("\x1b[2X");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h !", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h !", "wat?", " "]);
|
||||
// check how we handle overflowing the width
|
||||
term.print("\x1b[12X");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", " "]);
|
||||
term.print("\x1b[-12X");
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["h ", "wat?", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -71,14 +76,14 @@ fn test_dch() {
|
||||
term.print("hello world");
|
||||
term.cup(1, 0);
|
||||
term.print("\x1b[P");
|
||||
assert_visible_contents(&term, file!(), line!(), &["hllo world"]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["hllo world "]);
|
||||
|
||||
term.cup(4, 0);
|
||||
term.print("\x1b[2P");
|
||||
assert_visible_contents(&term, file!(), line!(), &["hlloorld"]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["hlloorld "]);
|
||||
|
||||
term.print("\x1b[-2P");
|
||||
assert_visible_contents(&term, file!(), line!(), &["hlloorld"]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["hlloorld "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -118,11 +123,11 @@ fn test_dl() {
|
||||
term.cup(0, 1);
|
||||
let seqno = term.current_seqno();
|
||||
term.delete_lines(1);
|
||||
assert_visible_contents(&term, file!(), line!(), &["a", "c", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["a", "c", " "]);
|
||||
term.assert_cursor_pos(0, 1, None, Some(seqno));
|
||||
term.cup(0, 0);
|
||||
term.delete_lines(2);
|
||||
assert_visible_contents(&term, file!(), line!(), &["", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &[" ", " ", " "]);
|
||||
term.print("1\r\n2\r\n3");
|
||||
term.cup(0, 1);
|
||||
term.delete_lines(-2);
|
||||
@ -185,7 +190,7 @@ fn test_ed() {
|
||||
fn test_ed_erase_scrollback() {
|
||||
let mut term = TestTerm::new(3, 3, 3);
|
||||
term.print("abc\r\ndef\r\nghi\r\n111\r\n222\r\na\x1b[3J");
|
||||
assert_all_contents(&term, file!(), line!(), &["111", "222", "a"]);
|
||||
assert_all_contents(&term, file!(), line!(), &["111", "222", "a "]);
|
||||
term.print("b");
|
||||
assert_all_contents(&term, file!(), line!(), &["111", "222", "ab"]);
|
||||
assert_all_contents(&term, file!(), line!(), &["111", "222", "ab "]);
|
||||
}
|
||||
|
@ -327,7 +327,18 @@ fn test_semantic() {
|
||||
));
|
||||
term.print("there");
|
||||
|
||||
assert_visible_contents(&term, file!(), line!(), &["hello", "there", "", "", ""]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
"hello ",
|
||||
"there ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
term.cup(0, 2);
|
||||
term.print(format!(
|
||||
@ -339,7 +350,13 @@ fn test_semantic() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["hello", "there", "three", "", ""],
|
||||
&[
|
||||
"hello ",
|
||||
"there ",
|
||||
"three ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
k9::snapshot!(
|
||||
@ -349,8 +366,8 @@ fn test_semantic() {
|
||||
SemanticZone {
|
||||
start_y: 0,
|
||||
start_x: 0,
|
||||
end_y: 2,
|
||||
end_x: 4,
|
||||
end_y: 4,
|
||||
end_x: 9,
|
||||
semantic_type: Output,
|
||||
},
|
||||
]
|
||||
@ -386,7 +403,7 @@ fn test_semantic() {
|
||||
let mut input = CellAttributes::default();
|
||||
input.set_semantic_type(SemanticType::Input);
|
||||
|
||||
let mut prompt_line = Line::from_text("> ls -l", &output);
|
||||
let mut prompt_line = Line::from_text("> ls -l ", &output);
|
||||
for i in 0..2 {
|
||||
prompt_line.cells_mut()[i]
|
||||
.attrs_mut()
|
||||
@ -439,11 +456,11 @@ fn test_semantic() {
|
||||
line!(),
|
||||
&term.screen().visible_lines(),
|
||||
&[
|
||||
Line::from_text("hello", &output),
|
||||
Line::from_text("there", &output),
|
||||
Line::from_text("three", &output),
|
||||
Line::from_text("hello ", &output),
|
||||
Line::from_text("there ", &output),
|
||||
Line::from_text("three ", &output),
|
||||
prompt_line,
|
||||
Line::from_text("some file", &output),
|
||||
Line::from_text("some file ", &output),
|
||||
],
|
||||
Compare::TEXT | Compare::ATTRS,
|
||||
);
|
||||
@ -457,7 +474,18 @@ fn basic_output() {
|
||||
|
||||
term.set_auto_wrap(false);
|
||||
term.print("hello, world!");
|
||||
assert_visible_contents(&term, file!(), line!(), &["", " hello, w!", "", "", ""]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
" ",
|
||||
" hello, w!",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
term.set_auto_wrap(true);
|
||||
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||
@ -467,7 +495,13 @@ fn basic_output() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " hello, wo", "rld!", "", ""],
|
||||
&[
|
||||
" ",
|
||||
" hello, wo",
|
||||
"rld! ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
term.erase_in_display(EraseInDisplay::EraseToStartOfDisplay);
|
||||
@ -475,7 +509,13 @@ fn basic_output() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", " ", "", ""],
|
||||
&[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
|
||||
term.cup(0, 2);
|
||||
@ -486,7 +526,7 @@ fn basic_output() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", "wo", "", ""],
|
||||
&[" ", " ", "wo", " ", " "],
|
||||
);
|
||||
|
||||
term.erase_in_line(EraseInLine::EraseToStartOfLine);
|
||||
@ -494,7 +534,13 @@ fn basic_output() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[" ", " ", " ", "", ""],
|
||||
&[
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -506,7 +552,7 @@ fn cursor_movement_damage() {
|
||||
|
||||
let seqno = term.current_seqno();
|
||||
term.print("fooo.");
|
||||
assert_visible_contents(&term, file!(), line!(), &["foo", "o."]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["foo", "o. "]);
|
||||
term.assert_cursor_pos(2, 1, None, None);
|
||||
term.assert_dirty_lines(seqno, &[0, 1], None);
|
||||
|
||||
@ -553,7 +599,7 @@ fn scroll_up_within_left_and_right_margins() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[&ones, &twos, &threes, &fours, &fives],
|
||||
&["111 ", "222 ", "333 ", "44444", "555 "],
|
||||
);
|
||||
|
||||
term.set_mode("?69", true); // allow left/right margins to be set
|
||||
@ -566,11 +612,11 @@ fn scroll_up_within_left_and_right_margins() {
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
&ones,
|
||||
&twos,
|
||||
"111 ",
|
||||
"222 ",
|
||||
&format!("3{}", "4".repeat(NUM_COLS + 1)),
|
||||
&format!("4{}", "5".repeat(NUM_COLS - 1)),
|
||||
&format!("5{}", " ".repeat(NUM_COLS - 1)),
|
||||
&format!("5{} ", " ".repeat(NUM_COLS - 1)),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -599,7 +645,7 @@ fn scroll_down_within_left_and_right_margins() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&[&ones, &twos, &threes, &fours, &fives],
|
||||
&["111 ", "222 ", "333 ", "44444", "555 "],
|
||||
);
|
||||
|
||||
term.set_mode("?69", true); // allow left/right margins to be set
|
||||
@ -616,9 +662,9 @@ fn scroll_down_within_left_and_right_margins() {
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
&ones,
|
||||
&twos,
|
||||
&format!("3{}", " ".repeat(NUM_COLS - 1)),
|
||||
"111 ",
|
||||
"222 ",
|
||||
&format!("3{} ", " ".repeat(NUM_COLS - 1)),
|
||||
&format!("4{}", "3".repeat(NUM_COLS - 1)),
|
||||
&format!("5{}", "4".repeat(NUM_COLS + 1)),
|
||||
],
|
||||
@ -647,7 +693,12 @@ fn test_delete_lines() {
|
||||
let seqno = term.current_seqno();
|
||||
term.assert_dirty_lines(seqno, &[], None);
|
||||
term.delete_lines(2);
|
||||
assert_visible_contents(&term, file!(), line!(), &["111", "444", "555", "", ""]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "444", "555", " ", " "],
|
||||
);
|
||||
term.assert_dirty_lines(seqno, &[1, 2, 3, 4], None);
|
||||
|
||||
term.cup(0, 3);
|
||||
@ -668,7 +719,12 @@ fn test_delete_lines() {
|
||||
print_all_lines(&term);
|
||||
term.delete_lines(2);
|
||||
|
||||
assert_visible_contents(&term, file!(), line!(), &["111", "aaa", "", "", "bbb"]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "aaa", " ", " ", "bbb"],
|
||||
);
|
||||
term.assert_dirty_lines(seqno, &[1, 2, 3], None);
|
||||
|
||||
// expand the scroll region to fill the screen
|
||||
@ -678,7 +734,12 @@ fn test_delete_lines() {
|
||||
print_all_lines(&term);
|
||||
term.delete_lines(1);
|
||||
|
||||
assert_visible_contents(&term, file!(), line!(), &["aaa", "", "", "bbb", ""]);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["aaa", " ", " ", "bbb", " "],
|
||||
);
|
||||
term.assert_dirty_lines(seqno, &[4], None);
|
||||
}
|
||||
|
||||
@ -692,7 +753,10 @@ fn test_dec_special_graphics() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["ABC▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥DEF", "hello"],
|
||||
&[
|
||||
"ABC▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥DEF ",
|
||||
"hello ",
|
||||
],
|
||||
);
|
||||
|
||||
term = TestTerm::new(2, 50, 0);
|
||||
@ -701,7 +765,10 @@ fn test_dec_special_graphics() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["SO-ABC▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥DEF", "SI-hello"],
|
||||
&[
|
||||
"SO-ABC▒␉␌␍␊°±␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥DEF ",
|
||||
"SI-hello ",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -715,7 +782,12 @@ fn test_dec_double_width() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["line1", "line2", "line3", "line4"],
|
||||
&[
|
||||
"line1 ",
|
||||
"line2 ",
|
||||
"line3 ",
|
||||
"line4 ",
|
||||
],
|
||||
);
|
||||
|
||||
let lines = term.screen().visible_lines();
|
||||
@ -736,35 +808,43 @@ fn test_resize_wrap() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222", "aa", "333", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222", "aa ", "333 ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 5, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222a", "a", "333", "", "", "", ""],
|
||||
&["111 ", "2222a", "a", "333 ", " ", " ", " ", " "],
|
||||
);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222aa", "333", "", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222aa", "333 ", " ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 7, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222aa", "333", "", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222aa", "333 ", " ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 8, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222aa", "333", "", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222aa", "333 ", " ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
|
||||
// Resize smaller again
|
||||
@ -773,28 +853,36 @@ fn test_resize_wrap() {
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222aa", "333", "", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222aa", "333 ", " ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222aa", "333", "", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222aa", "333 ", " ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 5, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222a", "a", "333", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222a", "a", "333 ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
term.resize(LINES, 4, 0, 0);
|
||||
assert_visible_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["111", "2222", "aa", "333", "", "", "", ""],
|
||||
&[
|
||||
"111 ", "2222", "aa", "333 ", " ", " ", " ", " ",
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -803,9 +891,9 @@ fn test_resize_wrap_issue_971() {
|
||||
const LINES: usize = 4;
|
||||
let mut term = TestTerm::new(LINES, 4, 0);
|
||||
term.print("====\r\nSS\r\n");
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -813,9 +901,9 @@ fn test_resize_wrap_sgc_issue_978() {
|
||||
const LINES: usize = 4;
|
||||
let mut term = TestTerm::new(LINES, 4, 0);
|
||||
term.print("\u{1b}(0qqqq\u{1b}(B\r\nSS\r\n");
|
||||
assert_visible_contents(&term, file!(), line!(), &["────", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["────", "SS ", " ", " "]);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(&term, file!(), line!(), &["────", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["────", "SS ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -823,9 +911,9 @@ fn test_resize_wrap_dectcm_issue_978() {
|
||||
const LINES: usize = 4;
|
||||
let mut term = TestTerm::new(LINES, 4, 0);
|
||||
term.print("\u{1b}[?25l====\u{1b}[?25h\r\nSS\r\n");
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -833,44 +921,44 @@ fn test_resize_wrap_escape_code_issue_978() {
|
||||
const LINES: usize = 4;
|
||||
let mut term = TestTerm::new(LINES, 4, 0);
|
||||
term.print("====\u{1b}[0m\r\nSS\r\n");
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
term.resize(LINES, 6, 0, 0);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS", "", ""]);
|
||||
assert_visible_contents(&term, file!(), line!(), &["====", "SS ", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scrollup() {
|
||||
let mut term = TestTerm::new(2, 1, 4);
|
||||
term.print("1\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 0);
|
||||
|
||||
term.print("2\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 1);
|
||||
|
||||
term.print("3\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 2);
|
||||
|
||||
term.print("4\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 3);
|
||||
|
||||
term.print("5\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", "5", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", "5", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 4);
|
||||
|
||||
term.print("6\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["2", "3", "4", "5", "6", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["2", "3", "4", "5", "6", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 5);
|
||||
|
||||
term.print("7\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["3", "4", "5", "6", "7", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["3", "4", "5", "6", "7", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 6);
|
||||
|
||||
term.print("8\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["4", "5", "6", "7", "8", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["4", "5", "6", "7", "8", " "]);
|
||||
assert_eq!(term.screen().visible_row_to_stable_row(0), 7);
|
||||
}
|
||||
|
||||
@ -878,14 +966,14 @@ fn test_scrollup() {
|
||||
fn test_ri() {
|
||||
let mut term = TestTerm::new(3, 1, 10);
|
||||
term.print("1\n\u{8d}\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", " ", " "]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scroll_margins() {
|
||||
let mut term = TestTerm::new(3, 1, 10);
|
||||
term.print("1\n2\n3\n4\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "3", "4", " "]);
|
||||
|
||||
let margins = CSI::Cursor(termwiz::escape::csi::Cursor::SetTopAndBottomMargins {
|
||||
top: OneBased::new(1),
|
||||
@ -894,14 +982,19 @@ fn test_scroll_margins() {
|
||||
term.print(format!("{}", margins));
|
||||
|
||||
term.print("z\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "z", "4", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "z", "4", " "]);
|
||||
|
||||
term.print("a\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "z", "a", "", ""]);
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "z", "a", " ", " "]);
|
||||
|
||||
term.cup(0, 1);
|
||||
term.print("W\n");
|
||||
assert_all_contents(&term, file!(), line!(), &["1", "2", "z", "a", "W", "", ""]);
|
||||
assert_all_contents(
|
||||
&term,
|
||||
file!(),
|
||||
line!(),
|
||||
&["1", "2", "z", "a", "W", " ", " "],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -919,9 +1012,9 @@ fn test_emoji_with_modifier() {
|
||||
file!(),
|
||||
line!(),
|
||||
&[
|
||||
&format!("{}", waving_hand),
|
||||
&format!("{}", waving_hand_dark_tone),
|
||||
"",
|
||||
&format!("{} ", waving_hand),
|
||||
&format!("{} ", waving_hand_dark_tone),
|
||||
" ",
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -941,7 +1034,11 @@ fn test_hyperlinks() {
|
||||
file!(),
|
||||
line!(),
|
||||
&term.screen().visible_lines(),
|
||||
&[Line::from_text("hello", &linked), "".into(), "".into()],
|
||||
&[
|
||||
Line::from_text("hello", &linked),
|
||||
" ".into(),
|
||||
" ".into(),
|
||||
],
|
||||
Compare::TEXT | Compare::ATTRS,
|
||||
);
|
||||
|
||||
@ -958,7 +1055,7 @@ fn test_hyperlinks() {
|
||||
&[
|
||||
Line::from_text_with_wrapped_last_col("hello", &linked),
|
||||
Line::from_text("hey!!", &linked),
|
||||
"".into(),
|
||||
" ".into(),
|
||||
],
|
||||
Compare::TEXT | Compare::ATTRS,
|
||||
);
|
||||
|
@ -62,7 +62,7 @@ pub enum DoubleClickRange {
|
||||
impl Line {
|
||||
pub fn with_width(width: usize) -> Self {
|
||||
let mut cells = Vec::with_capacity(width);
|
||||
cells.resize(width, Cell::default());
|
||||
cells.resize_with(width, Cell::blank);
|
||||
let bits = LineBits::NONE;
|
||||
Self {
|
||||
bits,
|
||||
@ -99,16 +99,17 @@ impl Line {
|
||||
}
|
||||
|
||||
pub fn resize_and_clear(&mut self, width: usize, seqno: SequenceNo) {
|
||||
let blank = Cell::default();
|
||||
self.cells.clear();
|
||||
self.cells.resize(width, blank);
|
||||
for c in &mut self.cells {
|
||||
*c = Cell::blank();
|
||||
}
|
||||
self.cells.resize_with(width, Cell::blank);
|
||||
self.cells.shrink_to_fit();
|
||||
self.update_last_change_seqno(seqno);
|
||||
self.bits = LineBits::NONE;
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: usize, seqno: SequenceNo) {
|
||||
self.cells.resize(width, Cell::default());
|
||||
self.cells.resize_with(width, Cell::blank);
|
||||
self.update_last_change_seqno(seqno);
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ impl Line {
|
||||
/// Returns the list of resultant line(s)
|
||||
pub fn wrap(mut self, width: usize, seqno: SequenceNo) -> Vec<Self> {
|
||||
if let Some(end_idx) = self.cells.iter().rposition(|c| c.str() != " ") {
|
||||
self.cells.resize(end_idx + 1, Cell::default());
|
||||
self.cells.resize_with(end_idx + 1, Cell::blank);
|
||||
|
||||
let mut lines: Vec<_> = self
|
||||
.cells
|
||||
@ -448,7 +449,7 @@ impl Line {
|
||||
|
||||
// if the line isn't wide enough, pad it out with the default attributes.
|
||||
if idx + width > self.cells.len() {
|
||||
self.cells.resize(idx + width, Cell::default());
|
||||
self.cells.resize_with(idx + width, Cell::blank);
|
||||
}
|
||||
|
||||
self.invalidate_implicit_hyperlinks(seqno);
|
||||
@ -511,7 +512,7 @@ impl Line {
|
||||
}
|
||||
|
||||
if x >= self.cells.len() {
|
||||
self.cells.resize(x, Cell::default());
|
||||
self.cells.resize_with(x, Cell::blank);
|
||||
}
|
||||
|
||||
// If we're inserting a wide cell, we should also insert the overlapped cells.
|
||||
@ -557,7 +558,7 @@ impl Line {
|
||||
.iter()
|
||||
.rposition(|c| c.str() != " " || c.attrs() != &def_attr)
|
||||
{
|
||||
self.cells.resize(end_idx + 1, Cell::default());
|
||||
self.cells.resize_with(end_idx + 1, Cell::blank);
|
||||
self.update_last_change_seqno(seqno);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user