|
|
@ -201,7 +201,7 @@ where
|
|
|
|
for (x, y, cell) in content {
|
|
|
|
for (x, y, cell) in content {
|
|
|
|
// Move the cursor if the previous location was not (x - 1, y)
|
|
|
|
// Move the cursor if the previous location was not (x - 1, y)
|
|
|
|
if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {
|
|
|
|
if !matches!(last_pos, Some(p) if x == p.0 + 1 && y == p.1) {
|
|
|
|
map_error(queue!(self.buffer, MoveTo(x, y)))?;
|
|
|
|
queue!(self.buffer, MoveTo(x, y))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
last_pos = Some((x, y));
|
|
|
|
last_pos = Some((x, y));
|
|
|
|
if cell.modifier != modifier {
|
|
|
|
if cell.modifier != modifier {
|
|
|
@ -214,12 +214,12 @@ where
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if cell.fg != fg {
|
|
|
|
if cell.fg != fg {
|
|
|
|
let color = CColor::from(cell.fg);
|
|
|
|
let color = CColor::from(cell.fg);
|
|
|
|
map_error(queue!(self.buffer, SetForegroundColor(color)))?;
|
|
|
|
queue!(self.buffer, SetForegroundColor(color))?;
|
|
|
|
fg = cell.fg;
|
|
|
|
fg = cell.fg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if cell.bg != bg {
|
|
|
|
if cell.bg != bg {
|
|
|
|
let color = CColor::from(cell.bg);
|
|
|
|
let color = CColor::from(cell.bg);
|
|
|
|
map_error(queue!(self.buffer, SetBackgroundColor(color)))?;
|
|
|
|
queue!(self.buffer, SetBackgroundColor(color))?;
|
|
|
|
bg = cell.bg;
|
|
|
|
bg = cell.bg;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -227,7 +227,7 @@ where
|
|
|
|
if self.capabilities.has_extended_underlines {
|
|
|
|
if self.capabilities.has_extended_underlines {
|
|
|
|
if cell.underline_color != underline_color {
|
|
|
|
if cell.underline_color != underline_color {
|
|
|
|
let color = CColor::from(cell.underline_color);
|
|
|
|
let color = CColor::from(cell.underline_color);
|
|
|
|
map_error(queue!(self.buffer, SetUnderlineColor(color)))?;
|
|
|
|
queue!(self.buffer, SetUnderlineColor(color))?;
|
|
|
|
underline_color = cell.underline_color;
|
|
|
|
underline_color = cell.underline_color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -239,24 +239,24 @@ where
|
|
|
|
|
|
|
|
|
|
|
|
if new_underline_style != underline_style {
|
|
|
|
if new_underline_style != underline_style {
|
|
|
|
let attr = CAttribute::from(new_underline_style);
|
|
|
|
let attr = CAttribute::from(new_underline_style);
|
|
|
|
map_error(queue!(self.buffer, SetAttribute(attr)))?;
|
|
|
|
queue!(self.buffer, SetAttribute(attr))?;
|
|
|
|
underline_style = new_underline_style;
|
|
|
|
underline_style = new_underline_style;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
map_error(queue!(self.buffer, Print(&cell.symbol)))?;
|
|
|
|
queue!(self.buffer, Print(&cell.symbol))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
map_error(queue!(
|
|
|
|
queue!(
|
|
|
|
self.buffer,
|
|
|
|
self.buffer,
|
|
|
|
SetUnderlineColor(CColor::Reset),
|
|
|
|
SetUnderlineColor(CColor::Reset),
|
|
|
|
SetForegroundColor(CColor::Reset),
|
|
|
|
SetForegroundColor(CColor::Reset),
|
|
|
|
SetBackgroundColor(CColor::Reset),
|
|
|
|
SetBackgroundColor(CColor::Reset),
|
|
|
|
SetAttribute(CAttribute::Reset)
|
|
|
|
SetAttribute(CAttribute::Reset)
|
|
|
|
))
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn hide_cursor(&mut self) -> io::Result<()> {
|
|
|
|
fn hide_cursor(&mut self) -> io::Result<()> {
|
|
|
|
map_error(execute!(self.buffer, Hide))
|
|
|
|
execute!(self.buffer, Hide)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn show_cursor(&mut self, kind: CursorKind) -> io::Result<()> {
|
|
|
|
fn show_cursor(&mut self, kind: CursorKind) -> io::Result<()> {
|
|
|
@ -266,7 +266,7 @@ where
|
|
|
|
CursorKind::Underline => SetCursorStyle::SteadyUnderScore,
|
|
|
|
CursorKind::Underline => SetCursorStyle::SteadyUnderScore,
|
|
|
|
CursorKind::Hidden => unreachable!(),
|
|
|
|
CursorKind::Hidden => unreachable!(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
map_error(execute!(self.buffer, Show, shape))
|
|
|
|
execute!(self.buffer, Show, shape)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
|
|
|
|
fn get_cursor(&mut self) -> io::Result<(u16, u16)> {
|
|
|
@ -275,11 +275,11 @@ where
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
|
|
|
|
fn set_cursor(&mut self, x: u16, y: u16) -> io::Result<()> {
|
|
|
|
map_error(execute!(self.buffer, MoveTo(x, y)))
|
|
|
|
execute!(self.buffer, MoveTo(x, y))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn clear(&mut self) -> io::Result<()> {
|
|
|
|
fn clear(&mut self) -> io::Result<()> {
|
|
|
|
map_error(execute!(self.buffer, Clear(ClearType::All)))
|
|
|
|
execute!(self.buffer, Clear(ClearType::All))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn size(&self) -> io::Result<Rect> {
|
|
|
|
fn size(&self) -> io::Result<Rect> {
|
|
|
@ -294,10 +294,6 @@ where
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn map_error(error: crossterm::Result<()>) -> io::Result<()> {
|
|
|
|
|
|
|
|
error.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct ModifierDiff {
|
|
|
|
struct ModifierDiff {
|
|
|
|
pub from: Modifier,
|
|
|
|
pub from: Modifier,
|
|
|
@ -312,48 +308,48 @@ impl ModifierDiff {
|
|
|
|
//use crossterm::Attribute;
|
|
|
|
//use crossterm::Attribute;
|
|
|
|
let removed = self.from - self.to;
|
|
|
|
let removed = self.from - self.to;
|
|
|
|
if removed.contains(Modifier::REVERSED) {
|
|
|
|
if removed.contains(Modifier::REVERSED) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NoReverse)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NoReverse))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if removed.contains(Modifier::BOLD) {
|
|
|
|
if removed.contains(Modifier::BOLD) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NormalIntensity)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NormalIntensity))?;
|
|
|
|
if self.to.contains(Modifier::DIM) {
|
|
|
|
if self.to.contains(Modifier::DIM) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::Dim)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::Dim))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if removed.contains(Modifier::ITALIC) {
|
|
|
|
if removed.contains(Modifier::ITALIC) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NoItalic)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NoItalic))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if removed.contains(Modifier::DIM) {
|
|
|
|
if removed.contains(Modifier::DIM) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NormalIntensity)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NormalIntensity))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if removed.contains(Modifier::CROSSED_OUT) {
|
|
|
|
if removed.contains(Modifier::CROSSED_OUT) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NotCrossedOut)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NotCrossedOut))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if removed.contains(Modifier::SLOW_BLINK) || removed.contains(Modifier::RAPID_BLINK) {
|
|
|
|
if removed.contains(Modifier::SLOW_BLINK) || removed.contains(Modifier::RAPID_BLINK) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::NoBlink)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::NoBlink))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let added = self.to - self.from;
|
|
|
|
let added = self.to - self.from;
|
|
|
|
if added.contains(Modifier::REVERSED) {
|
|
|
|
if added.contains(Modifier::REVERSED) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::Reverse)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::Reverse))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::BOLD) {
|
|
|
|
if added.contains(Modifier::BOLD) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::Bold)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::Bold))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::ITALIC) {
|
|
|
|
if added.contains(Modifier::ITALIC) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::Italic)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::Italic))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::DIM) {
|
|
|
|
if added.contains(Modifier::DIM) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::Dim)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::Dim))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::CROSSED_OUT) {
|
|
|
|
if added.contains(Modifier::CROSSED_OUT) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::CrossedOut)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::CrossedOut))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::SLOW_BLINK) {
|
|
|
|
if added.contains(Modifier::SLOW_BLINK) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::SlowBlink)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::SlowBlink))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if added.contains(Modifier::RAPID_BLINK) {
|
|
|
|
if added.contains(Modifier::RAPID_BLINK) {
|
|
|
|
map_error(queue!(w, SetAttribute(CAttribute::RapidBlink)))?;
|
|
|
|
queue!(w, SetAttribute(CAttribute::RapidBlink))?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
@ -407,7 +403,7 @@ impl Command for SetUnderlineColor {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(windows)]
|
|
|
|
#[cfg(windows)]
|
|
|
|
fn execute_winapi(&self) -> crossterm::Result<()> {
|
|
|
|
fn execute_winapi(&self) -> io::Result<()> {
|
|
|
|
Err(std::io::Error::new(
|
|
|
|
Err(std::io::Error::new(
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
"SetUnderlineColor not supported by winapi.",
|
|
|
|
"SetUnderlineColor not supported by winapi.",
|
|
|
|