diff options
author | Tuomas Siipola <siiptuo@kapsi.fi> | 2017-07-29 01:14:18 +0300 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-07-28 15:14:18 -0700 |
commit | 9b13e344f0be068982845694442489e4932ccd5d (patch) | |
tree | 098917a3f0ac3ccc515fd365d1dc4ced8222eb9c /src/ansi.rs | |
parent | e33168eff717683fbaf01b52dbf7b4d574a52157 (diff) | |
download | alacritty-9b13e344f0be068982845694442489e4932ccd5d.tar.gz alacritty-9b13e344f0be068982845694442489e4932ccd5d.zip |
Support background and foreground color escape codes (#662)
Diffstat (limited to 'src/ansi.rs')
-rw-r--r-- | src/ansi.rs | 156 |
1 files changed, 111 insertions, 45 deletions
diff --git a/src/ansi.rs b/src/ansi.rs index a820bb31..26a342e4 100644 --- a/src/ansi.rs +++ b/src/ansi.rs @@ -23,6 +23,61 @@ use index::{Column, Line, Contains}; use ::Rgb; +// Parse color arguments +// +// Expect that color argument looks like "rgb:xx/xx/xx" or "#xxxxxx" +fn parse_rgb_color(color: &[u8]) -> Option<Rgb> { + let mut iter = color.iter(); + + macro_rules! next { + () => { + iter.next().map(|v| *v as char) + } + } + + macro_rules! parse_hex { + () => {{ + let mut digit: u8 = 0; + let next = next!().and_then(|v| v.to_digit(16)); + if let Some(value) = next { + digit = value as u8; + } + + let next = next!().and_then(|v| v.to_digit(16)); + if let Some(value) = next { + digit <<= 4; + digit += value as u8; + } + digit + }} + } + + match next!() { + Some('r') => { + if next!() != Some('g') { return None; } + if next!() != Some('b') { return None; } + if next!() != Some(':') { return None; } + + let r = parse_hex!(); + let val = next!(); + if val != Some('/') { println!("val={:?}", val); return None; } + let g = parse_hex!(); + if next!() != Some('/') { return None; } + let b = parse_hex!(); + + Some(Rgb { r: r, g: g, b: b}) + } + Some('#') => { + Some(Rgb { + r: parse_hex!(), + g: parse_hex!(), + b: parse_hex!(), + }) + } + _ => None + } +} + /// The processor wraps a `vte::Parser` to ultimately call methods on a Handler pub struct Processor { state: ProcessorState, @@ -260,6 +315,9 @@ pub trait Handler { /// Set an indexed color value fn set_color(&mut self, usize, Rgb) {} + /// Reset an indexed color to original value + fn reset_color(&mut self, usize) {} + /// Run the dectest routine fn dectest(&mut self) {} } @@ -651,9 +709,9 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W> return; } - match params[0][0] { + match params[0] { // Set window title - b'0' | b'2' => { + b"0" | b"2" => { if params.len() < 2 { return unhandled!(); } @@ -665,10 +723,10 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W> // Set icon name // This is ignored, since alacritty has no concept of tabs - b'1' => return, + b"1" => return, // Set color index - b'4' => { + b"4" => { if params.len() < 3 { return unhandled!(); } @@ -696,51 +754,49 @@ impl<'a, H, W> vte::Perform for Performer<'a, H, W> return unhandled!(); } - // Parse color arguments - // - // Expect that color argument looks like "rgb:xx/xx/xx" - let color = { - let raw = params[2]; - let mut iter = raw.iter(); - macro_rules! next { - () => { - iter.next().map(|v| *v as char) - } - } - if next!() != Some('r') { return unhandled!(); } - if next!() != Some('g') { return unhandled!(); } - if next!() != Some('b') { return unhandled!(); } - if next!() != Some(':') { return unhandled!(); } - - macro_rules! parse_hex { - () => {{ - let mut digit: u8 = 0; - let next = next!().and_then(|v| v.to_digit(16)); - if let Some(value) = next { - digit = value as u8; - } + if let Some(color) = parse_rgb_color(params[2]) { + self.handler.set_color(index as usize, color); + } else { + unhandled!(); + } + } - let next = next!().and_then(|v| v.to_digit(16)); - if let Some(value) = next { - digit <<= 4; - digit += value as u8; - } - digit - }} - } + // Set foreground color + b"10" => { + if params.len() < 2 { + return unhandled!(); + } - let r = parse_hex!(); - let val = next!(); - if val != Some('/') { println!("val={:?}", val); return unhandled!(); } - let g = parse_hex!(); - if next!() != Some('/') { return unhandled!(); } - let b = parse_hex!(); + if let Some(color) = parse_rgb_color(params[1]) { + self.handler.set_color(NamedColor::Foreground as usize, color); + } else { + unhandled!() + } + } - Rgb { r: r, g: g, b: b} - }; + // Set background color + b"11" => { + if params.len() < 2 { + return unhandled!(); + } - self.handler.set_color(index as usize, color); + if let Some(color) = parse_rgb_color(params[1]) { + self.handler.set_color(NamedColor::Background as usize, color); + } else { + unhandled!() + } + } + + // Reset foreground color + b"110" => { + self.handler.reset_color(NamedColor::Foreground as usize); } + + // Reset background color + b"111" => { + self.handler.reset_color(NamedColor::Background as usize); + } + _ => { unhandled!(); } @@ -1241,7 +1297,7 @@ pub mod C1 { mod tests { use std::io; use index::{Line, Column}; - use super::{Processor, Handler, Attr, TermInfo, Color, StandardCharset, CharsetIndex}; + use super::{Processor, Handler, Attr, TermInfo, Color, StandardCharset, CharsetIndex, parse_rgb_color}; use ::Rgb; /// The /dev/null of io::Write @@ -1409,4 +1465,14 @@ mod tests { assert_eq!(handler.index, CharsetIndex::G1); } + + #[test] + fn parse_valid_rgb_color() { + assert_eq!(parse_rgb_color(b"rgb:11/aa/ff"), Some(Rgb { r: 0x11, g: 0xaa, b: 0xff })); + } + + #[test] + fn parse_valid_rgb_color2() { + assert_eq!(parse_rgb_color(b"#11aaff"), Some(Rgb { r: 0x11, g: 0xaa, b: 0xff })); + } } |