Skip to content

Commit

Permalink
Merge pull request #532 from mgeisler/skip-ansi-escape-sequence-early…
Browse files Browse the repository at this point in the history
…-return

Early return in `skip_ansi_escape_sequence`
  • Loading branch information
mgeisler authored Feb 10, 2024
2 parents e7a20ef + 599b78a commit b656c07
Showing 1 changed file with 33 additions and 25 deletions.
58 changes: 33 additions & 25 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,37 +41,45 @@ const CSI: (char, char) = ('\x1b', '[');
/// The final bytes of an ANSI escape sequence must be in this range.
const ANSI_FINAL_BYTE: std::ops::RangeInclusive<char> = '\x40'..='\x7e';

/// Skip ANSI escape sequences. The `ch` is the current `char`, the
/// `chars` provide the following characters. The `chars` will be
/// modified if `ch` is the start of an ANSI escape sequence.
/// Skip ANSI escape sequences.
///
/// The `ch` is the current `char`, the `chars` provide the following
/// characters. The `chars` will be modified if `ch` is the start of
/// an ANSI escape sequence.
///
/// Returns `true` if one or more chars were skipped.
#[inline]
pub(crate) fn skip_ansi_escape_sequence<I: Iterator<Item = char>>(ch: char, chars: &mut I) -> bool {
if ch == CSI.0 {
let next = chars.next();
if next == Some(CSI.1) {
// We have found the start of an ANSI escape code, typically
// used for colored terminal text. We skip until we find a
// "final byte" in the range 0x40–0x7E.
for ch in chars {
if ANSI_FINAL_BYTE.contains(&ch) {
return true;
}
if ch != CSI.0 {
return false; // Nothing to skip here.
}

let next = chars.next();
if next == Some(CSI.1) {
// We have found the start of an ANSI escape code, typically
// used for colored terminal text. We skip until we find a
// "final byte" in the range 0x40–0x7E.
for ch in chars {
if ANSI_FINAL_BYTE.contains(&ch) {
break;
}
} else if next == Some(']') {
// We have found the start of an Operating System Command, which
// extends until the next sequence "\x1b\\" (the String Terminator
// sequence) or the BEL character. The BEL character is non-standard,
// but it is still used quite often, for example, by GNU ls.
let mut last = ']';
for new in chars {
if new == '\x07' || (new == '\\' && last == CSI.0) {
return true;
}
last = new;
}
} else if next == Some(']') {
// We have found the start of an Operating System Command,
// which extends until the next sequence "\x1b\\" (the String
// Terminator sequence) or the BEL character. The BEL
// character is non-standard, but it is still used quite
// often, for example, by GNU ls.
let mut last = ']';
for new in chars {
if new == '\x07' || (new == '\\' && last == CSI.0) {
break;
}
last = new;
}
}
false

true // Indicate that some chars were skipped.
}

#[cfg(feature = "unicode-width")]
Expand Down

0 comments on commit b656c07

Please sign in to comment.