1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-14 03:16:09 +03:00

add ClearToEndOfLine

This commit is contained in:
Wez Furlong 2018-07-21 14:25:19 -07:00
parent 86e59293d3
commit 10e3f5d2a2
3 changed files with 77 additions and 3 deletions

View File

@ -2,7 +2,7 @@
use caps::{Capabilities, ColorLevel};
use cell::{AttributeChange, Blink, CellAttributes, Intensity, Underline};
use color::{ColorAttribute, ColorSpec};
use escape::csi::{Cursor, Edit, EraseInDisplay, Sgr, CSI};
use escape::csi::{Cursor, Edit, EraseInDisplay, EraseInLine, Sgr, CSI};
use escape::osc::OperatingSystemCommand;
use failure;
use screen::{Change, Position};
@ -307,6 +307,30 @@ impl TerminfoRenderer {
out.write(buf.as_slice())?;
}
}
Change::ClearToEndOfLine(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::ClrEol>() {
clr.expand().to(out.by_ref())?;
} else {
write!(
out,
"{}",
CSI::Edit(Edit::EraseInLine(EraseInLine::EraseToEndOfLine))
)?;
}
}
Change::Attribute(AttributeChange::Intensity(value)) => {
record!(set_intensity, value);
}

View File

@ -153,6 +153,23 @@ impl WindowsConsoleRenderer {
)?;
out.set_cursor_position(0, info.srWindow.Top)?;
}
Change::ClearToEndOfLine(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,
)?;
}
Change::Text(text) => {
out.flush()?;
out.set_attr(to_attr_word(&self.current_attr))?;

View File

@ -40,8 +40,10 @@ pub enum Change {
/// Implicitly clears all attributes prior to clearing the screen.
/// Moves the cursor to the home position (top left).
ClearScreen(ColorAttribute),
// ClearToStartOfLine,
// ClearToEndOfLine,
/// Clear from the current cursor X position to the rightmost
/// edge of the screen. The background color is set to the
/// provided color. The cursor position remains unchanged.
ClearToEndOfLine(ColorAttribute),
// ClearToEndOfScreen,
/// Move the cursor to the specified `Position`.
CursorPosition { x: Position, y: Position },
@ -247,6 +249,7 @@ impl Screen {
Change::Attribute(change) => self.change_attribute(change),
Change::CursorPosition { x, y } => self.set_cursor_pos(x, y),
Change::ClearScreen(color) => self.clear_screen(color),
Change::ClearToEndOfLine(color) => self.clear_eol(color),
}
}
@ -262,6 +265,16 @@ impl Screen {
}
}
fn clear_eol(&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();
}
}
fn scroll_screen_up(&mut self) {
self.lines.remove(0);
self.lines.push(Line::with_width(self.width));
@ -725,6 +738,26 @@ mod test {
assert_eq!(s.screen_chars_to_string(), " \n \n");
}
#[test]
fn clear_eol() {
let mut s = Screen::new(3, 3);
s.add_change("helwowfoo");
s.add_change(Change::ClearToEndOfLine(Default::default()));
assert_eq!(s.screen_chars_to_string(), "hel\nwow\nfoo\n");
s.add_change(Change::CursorPosition {
x: Position::Absolute(0),
y: Position::Absolute(0),
});
s.add_change(Change::ClearToEndOfLine(Default::default()));
assert_eq!(s.screen_chars_to_string(), " \nwow\nfoo\n");
s.add_change(Change::CursorPosition {
x: Position::Absolute(1),
y: Position::Absolute(1),
});
s.add_change(Change::ClearToEndOfLine(Default::default()));
assert_eq!(s.screen_chars_to_string(), " \nw \nfoo\n");
}
#[test]
fn cursor_movement() {
let mut s = Screen::new(4, 3);