1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-18 19:01:36 +03:00

Add a simple optimization to use ClearScreen

This commit is contained in:
Wez Furlong 2018-07-19 18:43:18 -07:00
parent fe32fac524
commit d37eb906b3

View File

@ -215,9 +215,10 @@ impl Screen {
self.attributes = CellAttributes::default() self.attributes = CellAttributes::default()
.set_background(color.clone()) .set_background(color.clone())
.clone(); .clone();
let cleared = Cell::new(' ', self.attributes.clone());
for line in &mut self.lines { for line in &mut self.lines {
for cell in &mut line.cells { for cell in &mut line.cells {
*cell = Cell::new(' ', self.attributes.clone()); *cell = cleared.clone();
} }
} }
} }
@ -379,13 +380,8 @@ impl Screen {
fn repaint_all(&self) -> Vec<Change> { fn repaint_all(&self) -> Vec<Change> {
let mut result = Vec::new(); let mut result = Vec::new();
// Home the cursor // Home the cursor and clear the screen to defaults
result.push(Change::CursorPosition { result.push(Change::ClearScreen(Default::default()));
x: Position::Absolute(0),
y: Position::Absolute(0),
});
// Reset attributes back to defaults
result.push(Change::AllAttributes(CellAttributes::default()));
let mut attr = CellAttributes::default(); let mut attr = CellAttributes::default();
@ -416,11 +412,39 @@ impl Screen {
attr = line.cells[self.width - 1].attrs().clone(); attr = line.cells[self.width - 1].attrs().clone();
} }
// Place the cursor at its intended position // Optimization opportunity: if we end up with a Text that ends with
result.push(Change::CursorPosition { // a sequence of spaces, and that sequence is long enough, then we can
x: Position::Absolute(self.xpos), // munge the output to use ClearScreen.
y: Position::Absolute(self.ypos), if attr == CellAttributes::default() {
}); let result_len = result.len();
if result[result_len - 1].is_text() {
if let Change::Text(text) = result.remove(result_len - 1) {
let left = text.trim_right_matches(' ').to_string();
let num_trailing_spaces = text.len() - left.len();
if num_trailing_spaces > 0 && left.len() > 0 {
// We can replace the trailing space with the effects of
// the screen clearing. We only need to push the left portion
// of the string if it has non-zero length.
result.push(Change::Text(left));
} else if num_trailing_spaces == 0 {
result.push(Change::Text(text));
}
}
}
}
// Place the cursor at its intended position, but only if we moved the
// cursor. We don't explicitly track movement but can infer it from the
// size of the results: results will have an initial ClearScreen entry
// that homes the cursor. If the screen is otherwise blank there will
// be no further entries and we don't need to emit cursor movement.
let moved_cursor = result.len() != 1;
if moved_cursor {
result.push(Change::CursorPosition {
x: Position::Absolute(self.xpos),
y: Position::Absolute(self.ypos),
});
}
result result
} }
@ -722,18 +746,7 @@ mod test {
fn test_empty_changes() { fn test_empty_changes() {
let s = Screen::new(4, 3); let s = Screen::new(4, 3);
let empty = &[ let empty = &[Change::ClearScreen(Default::default())];
Change::CursorPosition {
x: Position::Absolute(0),
y: Position::Absolute(0),
},
Change::AllAttributes(CellAttributes::default()),
Change::Text(" ".to_string()),
Change::CursorPosition {
x: Position::Absolute(0),
y: Position::Absolute(0),
},
];
let (seq, changes) = s.get_changes(0); let (seq, changes) = s.get_changes(0);
assert_eq!(seq, 0); assert_eq!(seq, 0);
@ -763,12 +776,8 @@ mod test {
s.resize(2, 2); s.resize(2, 2);
let full = &[ let full = &[
Change::CursorPosition { Change::ClearScreen(Default::default()),
x: Position::Absolute(0), Change::Text("a".to_string()),
y: Position::Absolute(0),
},
Change::AllAttributes(CellAttributes::default()),
Change::Text("a ".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(0), y: Position::Absolute(0),
@ -790,11 +799,7 @@ mod test {
let (_seq, changes) = s.get_changes(0); let (_seq, changes) = s.get_changes(0);
assert_eq!( assert_eq!(
&[ &[
Change::CursorPosition { Change::ClearScreen(Default::default()),
x: Position::Absolute(0),
y: Position::Absolute(0),
},
Change::AllAttributes(CellAttributes::default()),
Change::AllAttributes( Change::AllAttributes(
CellAttributes::default() CellAttributes::default()
.set_foreground(AnsiColor::Maroon) .set_foreground(AnsiColor::Maroon)
@ -806,7 +811,6 @@ mod test {
y: Position::Relative(1), y: Position::Relative(1),
}, },
Change::AllAttributes(CellAttributes::default()), Change::AllAttributes(CellAttributes::default()),
Change::Text(" ".into()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(2), x: Position::Absolute(2),
y: Position::Absolute(0), y: Position::Absolute(0),
@ -833,12 +837,8 @@ mod test {
assert_eq!(s.ypos, 1); assert_eq!(s.ypos, 1);
let full = &[ let full = &[
Change::CursorPosition { Change::ClearScreen(Default::default()),
x: Position::Absolute(0), Change::Text(" a".to_string()),
y: Position::Absolute(0),
},
Change::AllAttributes(CellAttributes::default()),
Change::Text(" a ".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(1), y: Position::Absolute(1),
@ -859,12 +859,8 @@ mod test {
s.flush_changes_older_than(1); s.flush_changes_older_than(1);
let initial = &[ let initial = &[
Change::CursorPosition { Change::ClearScreen(Default::default()),
x: Position::Absolute(0), Change::Text("a".to_string()),
y: Position::Absolute(0),
},
Change::AllAttributes(CellAttributes::default()),
Change::Text("a ".to_string()),
Change::CursorPosition { Change::CursorPosition {
x: Position::Absolute(1), x: Position::Absolute(1),
y: Position::Absolute(0), y: Position::Absolute(0),