Skip to content
This repository was archived by the owner on Aug 6, 2023. It is now read-only.

Commit

Permalink
refactor(backend/crossterm): support more style modifiers on Windows …
Browse files Browse the repository at this point in the history
…and fix build with Crossterm 0.17.8 (#368)

* Support more style modifiers on Windows
* Change Crossterm backend to write directly to buffer instead of String

Crossterm might actually do WinAPI calls instead of writing ANSI excape
codes so writing to an intermediate String may cause issues on older
versions of Windows. It also fails to compile with Crossterm 0.17.8 due
to Crossterm now expecting the writer to support `flush`, which String
doesn't.

Fixes #373
  • Loading branch information
alvinhochun authored Sep 20, 2020
1 parent aada695 commit e0b2572
Showing 1 changed file with 7 additions and 40 deletions.
47 changes: 7 additions & 40 deletions src/backend/crossterm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ use crossterm::{
},
terminal::{self, Clear, ClearType},
};
use std::{
fmt,
io::{self, Write},
};
use std::io::{self, Write};

pub struct CrosstermBackend<W: Write> {
buffer: W,
Expand Down Expand Up @@ -52,44 +49,40 @@ where
where
I: Iterator<Item = (u16, u16, &'a Cell)>,
{
use fmt::Write;

let mut string = String::with_capacity(content.size_hint().0 * 3);
let mut fg = Color::Reset;
let mut bg = Color::Reset;
let mut modifier = Modifier::empty();
let mut last_pos: Option<(u16, u16)> = None;
for (x, y, cell) in content {
// 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) {
map_error(queue!(string, MoveTo(x, y)))?;
map_error(queue!(self.buffer, MoveTo(x, y)))?;
}
last_pos = Some((x, y));
if cell.modifier != modifier {
let diff = ModifierDiff {
from: modifier,
to: cell.modifier,
};
diff.queue(&mut string)?;
diff.queue(&mut self.buffer)?;
modifier = cell.modifier;
}
if cell.fg != fg {
let color = CColor::from(cell.fg);
map_error(queue!(string, SetForegroundColor(color)))?;
map_error(queue!(self.buffer, SetForegroundColor(color)))?;
fg = cell.fg;
}
if cell.bg != bg {
let color = CColor::from(cell.bg);
map_error(queue!(string, SetBackgroundColor(color)))?;
map_error(queue!(self.buffer, SetBackgroundColor(color)))?;
bg = cell.bg;
}

string.push_str(&cell.symbol);
map_error(queue!(self.buffer, Print(&cell.symbol)))?;
}

map_error(queue!(
self.buffer,
Print(string),
SetForegroundColor(CColor::Reset),
SetBackgroundColor(CColor::Reset),
SetAttribute(CAttribute::Reset)
Expand Down Expand Up @@ -165,11 +158,10 @@ struct ModifierDiff {
pub to: Modifier,
}

#[cfg(unix)]
impl ModifierDiff {
fn queue<W>(&self, mut w: W) -> io::Result<()>
where
W: fmt::Write,
W: io::Write,
{
//use crossterm::Attribute;
let removed = self.from - self.to;
Expand Down Expand Up @@ -227,28 +219,3 @@ impl ModifierDiff {
Ok(())
}
}

#[cfg(windows)]
impl ModifierDiff {
fn queue<W>(&self, mut w: W) -> io::Result<()>
where
W: fmt::Write,
{
let removed = self.from - self.to;
if removed.contains(Modifier::BOLD) {
map_error(queue!(w, SetAttribute(CAttribute::NormalIntensity)))?;
}
if removed.contains(Modifier::UNDERLINED) {
map_error(queue!(w, SetAttribute(CAttribute::NoUnderline)))?;
}

let added = self.to - self.from;
if added.contains(Modifier::BOLD) {
map_error(queue!(w, SetAttribute(CAttribute::Bold)))?;
}
if added.contains(Modifier::UNDERLINED) {
map_error(queue!(w, SetAttribute(CAttribute::Underlined)))?;
}
Ok(())
}
}

0 comments on commit e0b2572

Please sign in to comment.