From 6d4392517a32719792b84bbad58cef717f1851cc Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Sat, 5 Dec 2020 19:41:51 +0000 Subject: Update to vte 0.9.0 See https://github.com/alacritty/vte/releases/tag/v0.9.0 https://github.com/alacritty/vte/compare/v0.8.0...v0.9.0 https://github.com/alacritty/alacritty/commit/576252294d09c1f52ec73bde03652349bdf5a529#diff-49ac9e6f6e6a855312bfcd393201f18ca53e6148c4a22a3a4949f1f9d1d137a8 --- src/ansi/iterator.rs | 215 +++++++++++++++++++++++---------------------------- 1 file changed, 95 insertions(+), 120 deletions(-) diff --git a/src/ansi/iterator.rs b/src/ansi/iterator.rs index 5b252358..be1c07af 100644 --- a/src/ansi/iterator.rs +++ b/src/ansi/iterator.rs @@ -1,4 +1,7 @@ use core::str::Bytes; +use std::convert::TryFrom; +use std::iter; +use vte::{Params, ParamsIter}; pub struct AnsiElementIterator<'a> { // The input bytes @@ -116,19 +119,19 @@ impl<'a> Iterator for AnsiElementIterator<'a> { } } -// Based on https://github.com/alacritty/vte/blob/0310be12d3007e32be614c5df94653d29fcc1a8b/examples/parselog.rs +// Based on https://github.com/alacritty/vte/blob/v0.9.0/examples/parselog.rs impl vte::Perform for Performer { - fn csi_dispatch(&mut self, params: &[i64], intermediates: &[u8], ignore: bool, c: char) { + fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) { if ignore || intermediates.len() > 1 { return; } if let ('m', None) = (c, intermediates.get(0)) { if params.is_empty() { - // Attr::Reset; + // Attr::Reset; TODO: does this need to be handled? } else { self.element = Some(Element::CSI( - ansi_term_style_from_sgr_parameters(params), + ansi_term_style_from_sgr_parameters(&mut params.iter()), 0, 0, )); @@ -147,7 +150,7 @@ impl vte::Perform for Performer { } } - fn hook(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {} + fn hook(&mut self, _params: &Params, _intermediates: &[u8], _ignore: bool, _c: char) {} fn put(&mut self, _byte: u8) {} @@ -162,139 +165,111 @@ impl vte::Perform for Performer { } } -// Based on https://github.com/alacritty/alacritty/blob/57c4ac9145a20fb1ae9a21102503458d3da06c7b/alacritty_terminal/src/ansi.rs#L1168 -fn ansi_term_style_from_sgr_parameters(parameters: &[i64]) -> ansi_term::Style { - let mut i = 0; +// Based on https://github.com/alacritty/alacritty/blob/9e71002e40d5487c6fa2571a3a3c4f5c8f679334/alacritty_terminal/src/ansi.rs#L1175 +fn ansi_term_style_from_sgr_parameters(params: &mut ParamsIter<'_>) -> ansi_term::Style { let mut style = ansi_term::Style::new(); - loop { - if i >= parameters.len() { - break; - } + while let Some(param) = params.next() { + match param { + // [0] => Some(Attr::Reset), + [1] => style.is_bold = true, + [2] => style.is_dimmed = true, + [3] => style.is_italic = true, + [4] => style.is_underline = true, + [5] => style.is_blink = true, // blink slow + [6] => style.is_blink = true, // blink fast + [7] => style.is_reverse = true, + [8] => style.is_hidden = true, + [9] => style.is_strikethrough = true, + // [21] => Some(Attr::CancelBold), + // [22] => Some(Attr::CancelBoldDim), + // [23] => Some(Attr::CancelItalic), + // [24] => Some(Attr::CancelUnderline), + // [25] => Some(Attr::CancelBlink), + // [27] => Some(Attr::CancelReverse), + // [28] => Some(Attr::CancelHidden), + // [29] => Some(Attr::CancelStrike), + [30] => style.foreground = Some(ansi_term::Color::Black), + [31] => style.foreground = Some(ansi_term::Color::Red), + [32] => style.foreground = Some(ansi_term::Color::Green), + [33] => style.foreground = Some(ansi_term::Color::Yellow), + [34] => style.foreground = Some(ansi_term::Color::Blue), + [35] => style.foreground = Some(ansi_term::Color::Purple), + [36] => style.foreground = Some(ansi_term::Color::Cyan), + [37] => style.foreground = Some(ansi_term::Color::White), + [38] => { + let mut iter = params.map(|param| param[0]); + if let Some(color) = parse_sgr_color(&mut iter) { + style.foreground = Some(color); + } + } + [38, params @ ..] => { + let rgb_start = if params.len() > 4 { 2 } else { 1 }; + let rgb_iter = params[rgb_start..].iter().copied(); + let mut iter = iter::once(params[0]).chain(rgb_iter); - match parameters[i] { - // 0 => Some(Attr::Reset), - 1 => style.is_bold = true, - 2 => style.is_dimmed = true, - 3 => style.is_italic = true, - 4 => style.is_underline = true, - 5 => style.is_blink = true, // blink slow - 6 => style.is_blink = true, // blink fast - 7 => style.is_reverse = true, - 8 => style.is_hidden = true, - 9 => style.is_strikethrough = true, - // 21 => Some(Attr::CancelBold), - // 22 => Some(Attr::CancelBoldDim), - // 23 => Some(Attr::CancelItalic), - // 24 => Some(Attr::CancelUnderline), - // 25 => Some(Attr::CancelBlink), - // 27 => Some(Attr::CancelReverse), - // 28 => Some(Attr::CancelHidden), - // 29 => Some(Attr::CancelStrike), - 30 => style.foreground = Some(ansi_term::Color::Black), - 31 => style.foreground = Some(ansi_term::Color::Red), - 32 => style.foreground = Some(ansi_term::Color::Green), - 33 => style.foreground = Some(ansi_term::Color::Yellow), - 34 => style.foreground = Some(ansi_term::Color::Blue), - 35 => style.foreground = Some(ansi_term::Color::Purple), - 36 => style.foreground = Some(ansi_term::Color::Cyan), - 37 => style.foreground = Some(ansi_term::Color::White), - 38 => { - let mut start = 0; - if let Some(color) = parse_sgr_color(¶meters[i..], &mut start) { - i += start; + if let Some(color) = parse_sgr_color(&mut iter) { style.foreground = Some(color); } } - // 39 => Some(Attr::Foreground(Color::Named(NamedColor::Foreground))), - 40 => style.background = Some(ansi_term::Color::Black), - 41 => style.background = Some(ansi_term::Color::Red), - 42 => style.background = Some(ansi_term::Color::Green), - 43 => style.background = Some(ansi_term::Color::Yellow), - 44 => style.background = Some(ansi_term::Color::Blue), - 45 => style.background = Some(ansi_term::Color::Purple), - 46 => style.background = Some(ansi_term::Color::Cyan), - 47 => style.background = Some(ansi_term::Color::White), - 48 => { - let mut start = 0; - if let Some(color) = parse_sgr_color(¶meters[i..], &mut start) { - i += start; + // [39] => Some(Attr::Foreground(Color::Named(NamedColor::Foreground))), + [40] => style.background = Some(ansi_term::Color::Black), + [41] => style.background = Some(ansi_term::Color::Red), + [42] => style.background = Some(ansi_term::Color::Green), + [43] => style.background = Some(ansi_term::Color::Yellow), + [44] => style.background = Some(ansi_term::Color::Blue), + [45] => style.background = Some(ansi_term::Color::Purple), + [46] => style.background = Some(ansi_term::Color::Cyan), + [47] => style.background = Some(ansi_term::Color::White), + [48] => { + let mut iter = params.map(|param| param[0]); + if let Some(color) = parse_sgr_color(&mut iter) { + style.background = Some(color); + } + } + [48, params @ ..] => { + let rgb_start = if params.len() > 4 { 2 } else { 1 }; + let rgb_iter = params[rgb_start..].iter().copied(); + let mut iter = iter::once(params[0]).chain(rgb_iter); + if let Some(color) = parse_sgr_color(&mut iter) { style.background = Some(color); } } - // 49 => Some(Attr::Background(Color::Named(NamedColor::Background))), + // [49] => Some(Attr::Background(Color::Named(NamedColor::Background))), // "bright" colors. ansi_term doesn't offer a way to emit them as, e.g., 90m; instead // that would be 38;5;8. - 90 => style.foreground = Some(ansi_term::Color::Fixed(8)), - 91 => style.foreground = Some(ansi_term::Color::Fixed(9)), - 92 => style.foreground = Some(ansi_term::Color::Fixed(10)), - 93 => style.foreground = Some(ansi_term::Color::Fixed(11)), - 94 => style.foreground = Some(ansi_term::Color::Fixed(12)), - 95 => style.foreground = Some(ansi_term::Color::Fixed(13)), - 96 => style.foreground = Some(ansi_term::Color::Fixed(14)), - 97 => style.foreground = Some(ansi_term::Color::Fixed(15)), - 100 => style.background = Some(ansi_term::Color::Fixed(8)), - 101 => style.background = Some(ansi_term::Color::Fixed(9)), - 102 => style.background = Some(ansi_term::Color::Fixed(10)), - 103 => style.background = Some(ansi_term::Color::Fixed(11)), - 104 => style.background = Some(ansi_term::Color::Fixed(12)), - 105 => style.background = Some(ansi_term::Color::Fixed(13)), - 106 => style.background = Some(ansi_term::Color::Fixed(14)), - 107 => style.background = Some(ansi_term::Color::Fixed(15)), + [90] => style.foreground = Some(ansi_term::Color::Fixed(8)), + [91] => style.foreground = Some(ansi_term::Color::Fixed(9)), + [92] => style.foreground = Some(ansi_term::Color::Fixed(10)), + [93] => style.foreground = Some(ansi_term::Color::Fixed(11)), + [94] => style.foreground = Some(ansi_term::Color::Fixed(12)), + [95] => style.foreground = Some(ansi_term::Color::Fixed(13)), + [96] => style.foreground = Some(ansi_term::Color::Fixed(14)), + [97] => style.foreground = Some(ansi_term::Color::Fixed(15)), + [100] => style.background = Some(ansi_term::Color::Fixed(8)), + [101] => style.background = Some(ansi_term::Color::Fixed(9)), + [102] => style.background = Some(ansi_term::Color::Fixed(10)), + [103] => style.background = Some(ansi_term::Color::Fixed(11)), + [104] => style.background = Some(ansi_term::Color::Fixed(12)), + [105] => style.background = Some(ansi_term::Color::Fixed(13)), + [106] => style.background = Some(ansi_term::Color::Fixed(14)), + [107] => style.background = Some(ansi_term::Color::Fixed(15)), _ => {} }; - i += 1; } style } // Based on https://github.com/alacritty/alacritty/blob/57c4ac9145a20fb1ae9a21102503458d3da06c7b/alacritty_terminal/src/ansi.rs#L1258 -fn parse_sgr_color(attrs: &[i64], i: &mut usize) -> Option { - if attrs.len() < 2 { - return None; - } - - match attrs[*i + 1] { - 2 => { - // RGB color spec. - if attrs.len() < 5 { - // debug!("Expected RGB color spec; got {:?}", attrs); - return None; - } - - let r = attrs[*i + 2]; - let g = attrs[*i + 3]; - let b = attrs[*i + 4]; - - *i += 4; - - let range = 0..256; - if !range.contains(&r) || !range.contains(&g) || !range.contains(&b) { - // debug!("Invalid RGB color spec: ({}, {}, {})", r, g, b); - return None; - } - - Some(ansi_term::Color::RGB(r as u8, g as u8, b as u8)) - } - 5 => { - if attrs.len() < 3 { - // debug!("Expected color index; got {:?}", attrs); - None - } else { - *i += 2; - let idx = attrs[*i]; - match idx { - 0..=255 => Some(ansi_term::Color::Fixed(idx as u8)), - _ => { - // debug!("Invalid color index: {}", idx); - None - } - } - } - } - _ => { - // debug!("Unexpected color attr: {}", attrs[*i + 1]); - None +fn parse_sgr_color(params: &mut dyn Iterator) -> Option { + match params.next() { + Some(2) => { + let r = u8::try_from(params.next()?).ok()?; + let g = u8::try_from(params.next()?).ok()?; + let b = u8::try_from(params.next()?).ok()?; + Some(ansi_term::Color::RGB(r, g, b)) } + Some(5) => Some(ansi_term::Color::Fixed(u8::try_from(params.next()?).ok()?)), + _ => None, } } -- cgit v1.2.3