Rustfmt requires long chained method calls to be broken across multiple lines when they exceed line length limits. Changes: - Break visual_width() iterator chains in renderer.rs - Break visual_width() iterator chains in terminal.rs - Fix comment alignment in ansi.rs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
55 lines
1.4 KiB
Rust
55 lines
1.4 KiB
Rust
/// Strip ANSI escape sequences from a string to get visual width
|
|
pub fn strip_ansi(text: &str) -> String {
|
|
let mut result = String::new();
|
|
let mut chars = text.chars().peekable();
|
|
|
|
while let Some(ch) = chars.next() {
|
|
if ch == '\x1b' {
|
|
// Skip ANSI escape sequence
|
|
if chars.peek() == Some(&'[') {
|
|
chars.next(); // consume '['
|
|
// Skip until we hit a letter (the command character)
|
|
while let Some(&c) = chars.peek() {
|
|
chars.next();
|
|
if c.is_ascii_alphabetic() {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
result.push(ch);
|
|
}
|
|
}
|
|
|
|
result
|
|
}
|
|
|
|
/// Get the visual width of a string (excluding ANSI codes)
|
|
pub fn visual_width(text: &str) -> usize {
|
|
strip_ansi(text).chars().count()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_strip_ansi() {
|
|
let text = "\x1b[38;2;255;87;51mHello\x1b[0m";
|
|
assert_eq!(strip_ansi(text), "Hello");
|
|
}
|
|
|
|
#[test]
|
|
fn test_visual_width() {
|
|
let text = "\x1b[38;2;255;87;51mHi\x1b[0m";
|
|
assert_eq!(visual_width(text), 2);
|
|
}
|
|
|
|
#[test]
|
|
fn test_no_ansi() {
|
|
let text = "Plain text";
|
|
assert_eq!(strip_ansi(text), "Plain text");
|
|
assert_eq!(visual_width(text), 10);
|
|
}
|
|
}
|