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

add ClearToEndOfScreen operation

This commit is contained in:
Wez Furlong 2018-07-21 14:57:24 -07:00
parent 10e3f5d2a2
commit b6aaf829b8
3 changed files with 90 additions and 1 deletions

View File

@ -331,6 +331,30 @@ impl TerminfoRenderer {
)?;
}
}
Change::ClearToEndOfScreen(color) => {
// ClearScreen implicitly resets all to default
let defaults = CellAttributes::default()
.set_background(color.clone())
.clone();
if self.current_attr != defaults {
self.pending_attr = Some(defaults);
self.flush_pending_attr(out)?;
}
self.pending_attr = None;
// FIXME: this doesn't behave correctly for terminals without bce.
// If we knew the current cursor position, we would be able to
// emit the correctly colored background for that case.
if let Some(clr) = self.get_capability::<cap::ClrEos>() {
clr.expand().to(out.by_ref())?;
} else {
write!(
out,
"{}",
CSI::Edit(Edit::EraseInDisplay(EraseInDisplay::EraseToEndOfDisplay))
)?;
}
}
Change::Attribute(AttributeChange::Intensity(value)) => {
record!(set_intensity, value);
}

View File

@ -170,6 +170,36 @@ impl WindowsConsoleRenderer {
width,
)?;
}
Change::ClearToEndOfScreen(color) => {
out.flush()?;
self.current_attr = CellAttributes::default()
.set_background(color.clone())
.clone();
let info = out.get_buffer_info()?;
let width =
(info.dwSize.X as u32).saturating_sub(info.dwCursorPosition.X as u32);
out.fill_char(' ', info.dwCursorPosition.X, info.dwCursorPosition.Y, width)?;
out.fill_attr(
to_attr_word(&self.current_attr),
info.dwCursorPosition.X,
info.dwCursorPosition.Y,
width,
)?;
// Clear the full width of the buffer (not the viewport size)
let visible_width = info.dwSize.X as u32;
// And clear all of the visible lines below the cursor
let visible_height =
(info.dwSize.Y as u32).saturating_sub((info.dwCursorPosition.Y as u32) + 1);
let num_spaces = visible_width * visible_height;
out.fill_char(' ', 0, info.dwCursorPosition.Y + 1, num_spaces as u32)?;
out.fill_attr(
to_attr_word(&self.current_attr),
0,
info.dwCursorPosition.Y + 1,
num_spaces as u32,
)?;
}
Change::Text(text) => {
out.flush()?;
out.set_attr(to_attr_word(&self.current_attr))?;

View File

@ -44,7 +44,12 @@ pub enum Change {
/// edge of the screen. The background color is set to the
/// provided color. The cursor position remains unchanged.
ClearToEndOfLine(ColorAttribute),
// ClearToEndOfScreen,
/// Clear from the current cursor X position to the rightmost
/// edge of the screen on the current line. Clear all of the
/// lines below the current cursor Y position. The background
/// color is set ot the provided color. The cursor position
/// remains unchanged.
ClearToEndOfScreen(ColorAttribute),
/// Move the cursor to the specified `Position`.
CursorPosition { x: Position, y: Position },
/* CursorVisibility(bool),
@ -250,6 +255,7 @@ impl Screen {
Change::CursorPosition { x, y } => self.set_cursor_pos(x, y),
Change::ClearScreen(color) => self.clear_screen(color),
Change::ClearToEndOfLine(color) => self.clear_eol(color),
Change::ClearToEndOfScreen(color) => self.clear_eos(color),
}
}
@ -265,6 +271,21 @@ impl Screen {
}
}
fn clear_eos(&mut self, color: &ColorAttribute) {
self.attributes = CellAttributes::default()
.set_background(color.clone())
.clone();
let cleared = Cell::new(' ', self.attributes.clone());
for cell in self.lines[self.ypos].cells.iter_mut().skip(self.xpos) {
*cell = cleared.clone();
}
for line in &mut self.lines.iter_mut().skip(self.ypos + 1) {
for cell in &mut line.cells {
*cell = cleared.clone();
}
}
}
fn clear_eol(&mut self, color: &ColorAttribute) {
self.attributes = CellAttributes::default()
.set_background(color.clone())
@ -758,6 +779,20 @@ mod test {
assert_eq!(s.screen_chars_to_string(), " \nw \nfoo\n");
}
#[test]
fn clear_eos() {
let mut s = Screen::new(3, 3);
s.add_change("helwowfoo");
s.add_change(Change::ClearToEndOfScreen(Default::default()));
assert_eq!(s.screen_chars_to_string(), "hel\nwow\nfoo\n");
s.add_change(Change::CursorPosition {
x: Position::Absolute(1),
y: Position::Absolute(1),
});
s.add_change(Change::ClearToEndOfScreen(Default::default()));
assert_eq!(s.screen_chars_to_string(), "hel\nw \n \n");
}
#[test]
fn cursor_movement() {
let mut s = Screen::new(4, 3);