1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00

ensure that we can copy screens even if they are blank

We were optimizing away setting the cells if only the background
attributes were different between the src and dest
This commit is contained in:
Wez Furlong 2018-07-22 10:41:34 -07:00
parent 670b0d023f
commit e7486d331a
2 changed files with 94 additions and 14 deletions

View File

@ -5,7 +5,7 @@ use failure::Error;
use termwiz::caps::Capabilities;
use termwiz::cell::AttributeChange;
use termwiz::color::AnsiColor;
use termwiz::surface::Change;
use termwiz::surface::{Change, Position, Surface};
use termwiz::terminal::buffered::BufferedTerminal;
use termwiz::terminal::{new_terminal, Terminal};
@ -17,6 +17,10 @@ fn main() -> Result<(), Error> {
let mut buf = BufferedTerminal::new(terminal)?;
let mut block = Surface::new(5, 5);
block.add_change(Change::ClearScreen(AnsiColor::Blue.into()));
buf.draw_from_screen(&block, 10, 10);
buf.add_change(Change::Attribute(AttributeChange::Foreground(
AnsiColor::Maroon.into(),
)));
@ -25,6 +29,10 @@ fn main() -> Result<(), Error> {
AnsiColor::Red.into(),
)));
buf.add_change("and in red here\r\n");
buf.add_change(Change::CursorPosition {
x: Position::Absolute(0),
y: Position::Absolute(20),
});
buf.flush()?;

View File

@ -717,19 +717,15 @@ impl Surface {
Some(other_cell.attrs().clone())
}
};
if cell.char() != other_cell.char() {
// A little bit of bloat in the code to avoid runs of single
// character Text entries; just append to the string.
let result_len = result.len();
if result_len > 0 && result[result_len - 1].is_text() {
if let Some(Change::Text(ref mut prefix)) =
result.get_mut(result_len - 1)
{
prefix.push(other_cell.char());
}
} else {
result.push(Change::Text(other_cell.char().to_string()));
// A little bit of bloat in the code to avoid runs of single
// character Text entries; just append to the string.
let result_len = result.len();
if result_len > 0 && result[result_len - 1].is_text() {
if let Some(Change::Text(ref mut prefix)) = result.get_mut(result_len - 1) {
prefix.push(other_cell.char());
}
} else {
result.push(Change::Text(other_cell.char().to_string()));
}
}
}
@ -747,9 +743,18 @@ impl Surface {
/// Draw the contents of `other` into self at the specified coordinates.
/// The required updates are recorded as Change entries as well as stored
/// in the screen line/cell data.
/// Saves the cursor position and attributes that were in effect prior to
/// calling `draw_from_screen` and restores them after applying the changes
/// from the other surface.
pub fn draw_from_screen(&mut self, other: &Surface, x: usize, y: usize) -> SequenceNo {
let attrs = self.attributes.clone();
let cursor = (self.xpos, self.ypos);
let changes = self.diff_region(x, y, other.width, other.height, other, 0, 0);
self.add_changes(changes)
let seq = self.add_changes(changes);
self.xpos = cursor.0;
self.ypos = cursor.1;
self.attributes = attrs;
seq
}
/// Copy the contents of the specified region to the same sized
@ -1333,6 +1338,73 @@ mod test {
);
}
#[test]
fn draw_colored_region() {
let mut dest = Surface::new(4, 4);
dest.add_change("A");
let mut src = Surface::new(2, 2);
src.add_change(Change::ClearScreen(AnsiColor::Blue.into()));
dest.draw_from_screen(&src, 2, 2);
assert_eq!(
dest.screen_chars_to_string(),
"A \n\
\x20 \n\
\x20 \n\
\x20 \n"
);
let blue_space = Cell::new(
' ',
CellAttributes::default()
.set_background(AnsiColor::Blue)
.clone(),
);
assert_eq!(
dest.screen_cells(),
[
[
Cell::new('A', CellAttributes::default()),
Cell::default(),
Cell::default(),
Cell::default(),
],
[
Cell::default(),
Cell::default(),
Cell::default(),
Cell::default(),
],
[
Cell::default(),
Cell::default(),
blue_space.clone(),
blue_space.clone(),
],
[
Cell::default(),
Cell::default(),
blue_space.clone(),
blue_space.clone(),
]
]
);
assert_eq!(dest.xpos, 1);
assert_eq!(dest.ypos, 0);
assert_eq!(dest.attributes, Default::default());
dest.add_change("B");
assert_eq!(
dest.screen_chars_to_string(),
"AB \n\
\x20 \n\
\x20 \n\
\x20 \n"
);
}
#[test]
fn copy_region() {
let mut s = Surface::new(4, 3);