From a4f75afe297ccf21035709aab8a043ee86a1ce49 Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Wed, 24 Nov 2021 12:40:26 -0500 Subject: HACK: Strip ANSI sequences that should not be present Ref #794 --- src/ansi/mod.rs | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ansi/mod.rs b/src/ansi/mod.rs index f45c13e7..18a4948d 100644 --- a/src/ansi/mod.rs +++ b/src/ansi/mod.rs @@ -70,14 +70,39 @@ pub fn parse_style_sections(s: &str) -> Vec<(ansi_term::Style, &str)> { let mut curr_style = Style::default(); for element in AnsiElementIterator::new(s) { match element { - Element::Text(start, end) => sections.push((curr_style, &s[start..end])), - Element::Csi(style, _, _) => curr_style = style, + Element::Text(start, end) => { + // FIXME: Some ANSI sequences are making it into the text, for example "\x1b[K" in + // output from BSD grep and GNU grep. + let substring = strip_ansi_prefixes(&s[start..end]); + if !substring.is_empty() { + sections.push((curr_style, substring)) + } + } + Element::Csi(style, _, _) => { + curr_style = style; + } _ => {} } } sections } +fn strip_ansi_prefixes(mut s: &str) -> &str { + let prefixes = &["\x1b[K", "\x1b[", "\x1b"]; + loop { + let mut stripped = false; + for prefix in prefixes { + if let Some(suffix) = s.strip_prefix(prefix) { + s = suffix; + stripped = true; + } + } + if !stripped { + return s; + } + } +} + // Return the first CSI element, if any, as an `ansi_term::Style`. pub fn parse_first_style(s: &str) -> Option { AnsiElementIterator::new(s).find_map(|el| match el { -- cgit v1.2.3