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:
parent
10e3f5d2a2
commit
b6aaf829b8
@ -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);
|
||||
}
|
||||
|
@ -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))?;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user