#[allow(dead_code)] const DARK_GREY_FG: &[u8] = b"\x1b[90m";
#[allow(dead_code)] pub fn dim_ansi(input: &str) -> String {
let bytes = input.as_bytes();
let mut out = Vec::with_capacity(bytes.len());
let mut i = 0;
while i < bytes.len() {
if bytes[i] == 0x1b && i + 1 < bytes.len() && bytes[i + 1] == b'[' {
let start = i;
let mut j = i + 2;
while j < bytes.len() && !bytes[j].is_ascii_alphabetic() {
j += 1;
}
if j >= bytes.len() {
out.extend_from_slice(&bytes[start..]);
return String::from_utf8(out).unwrap_or_else(|_| input.to_string());
}
let final_byte = bytes[j];
if final_byte == b'm' {
let body = &bytes[i + 2..j];
if body == b"0" || body.is_empty() || sgr_has_background(body) {
out.extend_from_slice(&bytes[start..=j]);
} else {
out.extend_from_slice(DARK_GREY_FG);
}
i = j + 1;
} else {
out.extend_from_slice(&bytes[start..=j]);
i = j + 1;
}
} else {
out.push(bytes[i]);
i += 1;
}
}
String::from_utf8(out).unwrap_or_else(|_| input.to_string())
}
fn sgr_has_background(body: &[u8]) -> bool {
let Ok(s) = std::str::from_utf8(body) else {
return false;
};
for p in s.split(';') {
if p == "48" {
return true;
}
if let Ok(n) = p.parse::<u16>()
&& ((40..=47).contains(&n) || (100..=107).contains(&n))
{
return true;
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn plain_text_passes_through() {
assert_eq!(dim_ansi("hello"), "hello");
}
#[test]
fn sgr_replaced_with_dark_grey() {
let input = "\x1b[31mRED\x1b[0m tail";
let out = dim_ansi(input);
assert!(out.starts_with("\x1b[90mRED\x1b[0m"));
assert!(out.ends_with(" tail"));
}
#[test]
fn multiple_sgr_all_replaced() {
let input = "\x1b[31mA\x1b[32mB\x1b[34mC\x1b[0m";
let out = dim_ansi(input);
let expected = "\x1b[90mA\x1b[90mB\x1b[90mC\x1b[0m";
assert_eq!(out, expected);
}
#[test]
fn non_sgr_sequence_preserved() {
let input = "\x1b[2;3Htext";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn background_color_is_preserved() {
let input = "\x1b[42mgreen bg\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn combined_fg_and_bg_preserves_the_sgr() {
let input = "\x1b[31;42mcolored\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn extended_bg_256_color_is_preserved() {
let input = "\x1b[48;5;226mhighlight\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn bright_bg_is_preserved() {
let input = "\x1b[105mbright pink bg\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn reset_preserved() {
let input = "\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn empty_input() {
assert_eq!(dim_ansi(""), "");
}
#[test]
fn unterminated_escape_copied_verbatim() {
let input = "a\x1b[31";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn truecolor_bg_is_preserved() {
let input = "\x1b[48;2;255;128;0mhighlight\x1b[0m";
let out = dim_ansi(input);
assert_eq!(out, input);
}
#[test]
fn fg_only_before_truecolor_bg_dims_correctly() {
let fg = "\x1b[33m"; let bg = "\x1b[48;2;0;0;128m"; let input = format!("{fg}{bg}text\x1b[0m");
let out = dim_ansi(&input);
assert!(out.contains("\x1b[90m"), "fg not dimmed");
assert!(out.contains(bg), "truecolor bg was stripped");
assert!(out.contains("\x1b[0m"), "reset was stripped");
}
}