1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-28 01:06:37 +03:00

Do a better job at BCE when erasing lines

The `dialog` program relies on this.
This commit is contained in:
Wez Furlong 2018-02-26 08:08:05 -08:00
parent 8e9620d001
commit 7b5dbab1a4
4 changed files with 62 additions and 9 deletions

View File

@ -96,6 +96,17 @@ impl CellAttributes {
bitfield!(invisible, set_invisible, 8);
// Allow up to 8 different font values
//bitfield!(font, set_font, 0b111000000, 6);
/// Clone the attributes, but exclude fancy extras such
/// as hyperlinks or future sprite things
pub fn clone_sgr_only(&self) -> Self {
Self {
attributes: self.attributes,
foreground: self.foreground,
background: self.background,
hyperlink: None,
}
}
}
impl Default for CellAttributes {
@ -196,6 +207,13 @@ impl Cell {
self.bytes[0] = b' ';
self.attrs = CellAttributes::default();
}
#[inline]
pub fn reset_with_attributes(&mut self, attr: &CellAttributes) {
self.len = 1;
self.bytes[0] = b' ';
self.attrs = attr.clone();
}
}
impl From<char> for Cell {

View File

@ -143,7 +143,12 @@ impl Screen {
&line.cells[x]
}
pub fn clear_line(&mut self, y: VisibleRowIndex, cols: std::ops::Range<usize>) {
pub fn clear_line(
&mut self,
y: VisibleRowIndex,
cols: std::ops::Range<usize>,
attr: &CellAttributes,
) {
let line_idx = self.phys_row(y);
let line = self.line_mut(line_idx);
let max_col = line.cells.len();
@ -151,7 +156,7 @@ impl Screen {
if x >= max_col {
break;
}
line.cells[x].reset();
line.cells[x].reset_with_attributes(attr);
}
}

View File

@ -945,37 +945,39 @@ impl TerminalState {
CSIAction::EraseInLine(erase) => {
let cx = self.cursor.x;
let cy = self.cursor.y;
let pen = self.pen.clone_sgr_only();
let mut screen = self.screen_mut();
let cols = screen.physical_cols;
match erase {
LineErase::ToRight => {
screen.clear_line(cy, cx..cols);
screen.clear_line(cy, cx..cols, &pen);
}
LineErase::ToLeft => {
screen.clear_line(cy, 0..cx);
screen.clear_line(cy, 0..cx, &pen);
}
LineErase::All => {
screen.clear_line(cy, 0..cols);
screen.clear_line(cy, 0..cols, &pen);
}
}
}
CSIAction::EraseInDisplay(erase) => {
let cy = self.cursor.y;
let pen = self.pen.clone_sgr_only();
let mut screen = self.screen_mut();
let cols = screen.physical_cols;
let rows = screen.physical_rows as VisibleRowIndex;
match erase {
DisplayErase::Below => for y in cy..rows {
screen.clear_line(y, 0..cols);
screen.clear_line(y, 0..cols, &pen);
},
DisplayErase::Above => for y in 0..cy {
screen.clear_line(y, 0..cols);
screen.clear_line(y, 0..cols, &pen);
},
DisplayErase::All => for y in 0..rows {
screen.clear_line(y, 0..cols);
screen.clear_line(y, 0..cols, &pen);
},
DisplayErase::SavedLines => {
println!("ed: no support for xterm Erase Saved Lines yet");
println!("TODO: ed: no support for xterm Erase Saved Lines yet");
}
}
}

View File

@ -117,3 +117,31 @@ fn test_cha() {
term.print("\x1b[100G");
term.assert_cursor_pos(3, 1, None);
}
#[test]
fn test_ed() {
let mut term = TestTerm::new(3, 3, 0);
term.print("abc\ndef\nghi");
term.cup(0, 2);
term.print("\x1b[J");
assert_visible_contents(&term, &["abc", "def", " "]);
// Set background color to blue
term.print("\x1b[44m");
// Clear whole screen
term.print("\x1b[2J");
// Check that the background color paints all of the cells;
// this is also known as BCE - Background Color Erase.
let mut attr = CellAttributes::default();
attr.background = color::ColorAttribute::PaletteIndex(color::AnsiColor::Navy as u8);
let mut line: Line = " ".into();
line.cells[0].attrs = attr.clone();
line.cells[1].attrs = attr.clone();
line.cells[2].attrs = attr.clone();
assert_lines_equal(
&term.screen().visible_lines(),
&[line.clone(), line.clone(), line],
Compare::TEXT | Compare::ATTRS,
);
}