diff options
author | Dan Davison <dandavison7@gmail.com> | 2021-11-24 12:40:26 -0500 |
---|---|---|
committer | Dan Davison <dandavison7@gmail.com> | 2021-11-24 12:46:36 -0500 |
commit | a4f75afe297ccf21035709aab8a043ee86a1ce49 (patch) | |
tree | e4563e48d3c3497d71efcfea77308c07e31264ec | |
parent | b5533f766f975bc3a1ceffe4835e6379e84efad8 (diff) |
HACK: Strip ANSI sequences that should not be present794-ansi-parse-bug
Ref #794
-rw-r--r-- | src/ansi/mod.rs | 29 |
1 files 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<ansi_term::Style> { AnsiElementIterator::new(s).find_map(|el| match el { |