Repository: nushell/nushell
File: crates/nu-color-config/src/nu_style.rs (Rust)

Code before:
        "grey66" | "xterm_grey66" => Color::Fixed(248).normal(),
        "grey70" | "xterm_grey70" => Color::Fixed(249).normal(),
        "grey74" | "xterm_grey74" => Color::Fixed(250).normal(),
        "grey78" | "xterm_grey78" => Color::Fixed(251).normal(),
        "grey82" | "xterm_grey82" => Color::Fixed(252).normal(),
        "grey85" | "xterm_grey85" => Color::Fixed(253).normal(),
        "grey89" | "xterm_grey89" => Color::Fixed(254).normal(),
        "grey93" | "xterm_grey93" => Color::Fixed(255).normal(),
        _ => Color::Default.normal(),
    }
}

pub fn lookup_color(s: &str) -> Option<Color> {
    lookup_style(s).foreground
}

fn fill_modifiers(attrs: &str, style: &mut Style) -> Result<(), ShellError> {
    // setup the attributes available in nu_ansi_term::Style
    //
    // since we can combine styles like bold-italic, iterate through the chars
    // and set the bools for later use in the nu_ansi_term::Style application

    // Check if the string consists only of known attribute codes
    let is_codes = attrs
        .chars()
        .all(|c| VALID_CODES.contains(c.to_ascii_lowercase()));

    // If it's a single character and not a valid code, treat as invalid code
    if attrs.chars().count() == 1 && !is_codes {
        let ch = attrs.chars().next().unwrap_or('?');
        return Err(ShellError::GenericError {
            error: "Invalid ANSI attribute code".into(),
            msg: format!("Unknown attribute code: '{}'", ch),
            span: None,
            help: Some(VALID_CODES_HELP.into()),
            inner: vec![],
        });
    }

    if is_codes {
        // Treat as concatenated codes
        for ch in attrs.chars().map(|c| c.to_ascii_lowercase()) {
            apply_code_to_style(ch, style)?;
        }
    } else {
        // Treat as names separated by space or comma
        for name in attrs.split([' ', ',']) {
            let trimmed = name.trim();
            if trimmed.is_empty() {
                continue;
            }

Review comment (suggestion):
Note that this relies on long versions (such as `blink`) to always have some characters outside the range of valid one-char versions. For example, if a new attribute with `k` abbreviation were added, `blink` would become ambiguous (as it could be interpreted as **b**old + b**l**ink + **i**talic + **n**ormal + **k**...)

Code after:
        "grey66" | "xterm_grey66" => Color::Fixed(248).normal(),
        "grey70" | "xterm_grey70" => Color::Fixed(249).normal(),
        "grey74" | "xterm_grey74" => Color::Fixed(250).normal(),
        "grey78" | "xterm_grey78" => Color::Fixed(251).normal(),
        "grey82" | "xterm_grey82" => Color::Fixed(252).normal(),
        "grey85" | "xterm_grey85" => Color::Fixed(253).normal(),
        "grey89" | "xterm_grey89" => Color::Fixed(254).normal(),
        "grey93" | "xterm_grey93" => Color::Fixed(255).normal(),
        _ => Color::Default.normal(),
    }
}

pub fn lookup_color(s: &str) -> Option<Color> {
    lookup_style(s).foreground
}

fn fill_modifiers(attrs: &str, style: &mut Style) -> Result<(), ShellError> {
    // setup the attributes available in nu_ansi_term::Style
    //
    // since we can combine styles like bold-italic, iterate through the chars
    // and set the bools for later use in the nu_ansi_term::Style application

    // Reject comma-delimited strings
    if attrs.contains(',') {
        return Err(ShellError::GenericError {
            error: "Invalid ANSI attribute format".into(),
            msg: "Comma-separated attributes are not supported. Use lists instead.".into(),
            span: None,
            help: Some("Use attr: [code1, code2] or attr: [name1, name2] instead of comma-separated strings.".into()),
            inner: vec![],
        });
    }

    // Treat as space-separated codes/names (from lists) or single code/name (from strings)
    for item in attrs.split_whitespace() {
        let trimmed = item.trim();
        if trimmed.is_empty() {
            continue;
        }

        // First try to match as a known attribute name
        if let Some(code) = name_to_code(&trimmed.to_ascii_lowercase()) {
            apply_code_to_style(code, style)?;
            continue;
        }

        // If not a known name, check if it's a single valid code
        if trimmed.len() == 1 {
            let ch = trimmed.chars().next().unwrap_or('?').to_ascii_lowercase();
            if VALID_CODES.contains(ch) {
                apply_code_to_style(ch, style)?;