Skip to content

Commit

Permalink
recognize the : form of the true color CSI/SGR encoding
Browse files Browse the repository at this point in the history
refs: #415
  • Loading branch information
wez committed Jan 7, 2021
1 parent 3df0201 commit e1f7eda
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
40 changes: 31 additions & 9 deletions termwiz/src/escape/csi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ impl Display for Sgr {
$(AnsiColor::$Ansi => code!($code) ,)*
}
} else {
write!(f, "{};5;{}m", SgrCode::$eightbit as i64, $idx)?
write!(f, "{}:5:{}m", SgrCode::$eightbit as i64, $idx)?
}
}
}
Expand Down Expand Up @@ -1188,7 +1188,7 @@ impl Display for Sgr {
),
Sgr::Foreground(ColorSpec::TrueColor(c)) => write!(
f,
"{};2;{};{};{}m",
"{}:2::{}:{}:{}m",
SgrCode::ForegroundColor as i64,
c.red,
c.green,
Expand Down Expand Up @@ -1219,7 +1219,7 @@ impl Display for Sgr {
),
Sgr::Background(ColorSpec::TrueColor(c)) => write!(
f,
"{};2;{};{};{}m",
"{}:2::{}:{}:{}m",
SgrCode::BackgroundColor as i64,
c.red,
c.green,
Expand All @@ -1228,14 +1228,14 @@ impl Display for Sgr {
Sgr::UnderlineColor(ColorSpec::Default) => code!(ResetUnderlineColor),
Sgr::UnderlineColor(ColorSpec::TrueColor(c)) => write!(
f,
"{};2;{};{};{}m",
"{}:2::{}:{}:{}m",
SgrCode::UnderlineColor as i64,
c.red,
c.green,
c.blue
)?,
Sgr::UnderlineColor(ColorSpec::PaletteIndex(idx)) => {
write!(f, "{};5;{}m", SgrCode::UnderlineColor as i64, *idx)?
write!(f, "{}:5:{}m", SgrCode::UnderlineColor as i64, *idx)?
}
}
Ok(())
Expand Down Expand Up @@ -1977,6 +1977,28 @@ impl<'a> CSIParser<'a> {
&[Some(4), Some(3)] => one!(Sgr::Underline(Underline::Curly)),
&[Some(4), Some(4)] => one!(Sgr::Underline(Underline::Dotted)),
&[Some(4), Some(5)] => one!(Sgr::Underline(Underline::Dashed)),

&[Some(38), Some(2), _colorspace, Some(r), Some(g), Some(b)] => one!(
Sgr::Foreground(RgbColor::new(r as u8, g as u8, b as u8).into())
),
&[Some(38), Some(5), Some(idx)] => {
one!(Sgr::Foreground(ColorSpec::PaletteIndex(idx as u8)))
}

&[Some(48), Some(2), _colorspace, Some(r), Some(g), Some(b)] => one!(
Sgr::Background(RgbColor::new(r as u8, g as u8, b as u8).into())
),
&[Some(48), Some(5), Some(idx)] => {
one!(Sgr::Background(ColorSpec::PaletteIndex(idx as u8)))
}

&[Some(58), Some(2), _colorspace, Some(r), Some(g), Some(b)] => one!(
Sgr::UnderlineColor(RgbColor::new(r as u8, g as u8, b as u8).into())
),
&[Some(58), Some(5), Some(idx)] => {
one!(Sgr::UnderlineColor(ColorSpec::PaletteIndex(idx as u8)))
}

_ => Err(()),
}
}
Expand Down Expand Up @@ -2200,13 +2222,13 @@ mod test {
);

assert_eq!(
parse('m', &[58, 2, 255, 255, 255], "\x1b[58;2;255;255;255m"),
parse('m', &[58, 2, 255, 255, 255], "\x1b[58:2::255:255:255m"),
vec![CSI::Sgr(Sgr::UnderlineColor(ColorSpec::TrueColor(
RgbColor::new(255, 255, 255),
)))]
);
assert_eq!(
parse('m', &[58, 5, 220, 255, 255], "\x1b[58;5;220m\x1b[255;255m"),
parse('m', &[58, 5, 220, 255, 255], "\x1b[58:5:220m\x1b[255;255m"),
vec![
CSI::Sgr(Sgr::UnderlineColor(ColorSpec::PaletteIndex(220))),
CSI::Unspecified(Box::new(Unspecified {
Expand All @@ -2232,13 +2254,13 @@ mod test {
);

assert_eq!(
parse('m', &[38, 2, 255, 255, 255], "\x1b[38;2;255;255;255m"),
parse('m', &[38, 2, 255, 255, 255], "\x1b[38:2::255:255:255m"),
vec![CSI::Sgr(Sgr::Foreground(ColorSpec::TrueColor(
RgbColor::new(255, 255, 255),
)))]
);
assert_eq!(
parse('m', &[38, 5, 220, 255, 255], "\x1b[38;5;220m\x1b[255;255m"),
parse('m', &[38, 5, 220, 255, 255], "\x1b[38:5:220m\x1b[255;255m"),
vec![
CSI::Sgr(Sgr::Foreground(ColorSpec::PaletteIndex(220))),
CSI::Unspecified(Box::new(Unspecified {
Expand Down
19 changes: 19 additions & 0 deletions termwiz/src/escape/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ impl SixelBuilder {
mod test {
use super::*;
use crate::cell::{Intensity, Underline};
use crate::color::ColorSpec;
use crate::escape::csi::Sgr;
use crate::escape::EscCode;
use std::io::Write;
Expand Down Expand Up @@ -502,6 +503,24 @@ mod test {
);
}

#[test]
fn true_color() {
let mut p = Parser::new();

let actions = p.parse_as_vec(b"\x1b[38:2::128:64:192mw");
assert_eq!(
vec![
Action::CSI(CSI::Sgr(Sgr::Foreground(ColorSpec::TrueColor(
RgbColor::new(128, 64, 192)
)))),
Action::Print('w'),
],
actions
);

assert_eq!(encode(&actions), "\u{1b}[38:2::128:64:192mw");
}

#[test]
fn basic_osc() {
let mut p = Parser::new();
Expand Down

0 comments on commit e1f7eda

Please sign in to comment.