diff --git a/src/uu/ls/src/config.rs b/src/uu/ls/src/config.rs index 29f4d9415af..1ec120ddeff 100644 --- a/src/uu/ls/src/config.rs +++ b/src/uu/ls/src/config.rs @@ -420,15 +420,12 @@ fn is_color_compatible_term() -> bool { let term = std::env::var_os("TERM"); let colorterm = std::env::var_os("COLORTERM"); - // Search function in the TERM struct to manage the wildcards + // Entries in TERMS are glob patterns (`*color*`, `con[0-9]*x[0-9]*`), not only `prefix*` let term_matches = |term: &OsStr| -> bool { - uucore::colors::TERMS.iter().any(|&pattern| { - term == pattern - || (pattern.ends_with('*') - && term - .as_encoded_bytes() - .starts_with(&pattern.as_bytes()[..pattern.len() - 1])) - }) + let term = term.to_string_lossy(); + uucore::colors::TERMS + .iter() + .any(|pattern| parse_glob::from_str(pattern).is_ok_and(|glob| glob.matches(&term))) }; match (term, colorterm) { diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 91445abd734..2c87b8be890 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline onetwo somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff dired subdired tmpfs mdir COLORTERM mexe bcdef mfoo timefile +// spell-checker:ignore (words) READMECAREFULLY birthtime doesntexist oneline onetwo somebackup lrwx somefile somegroup somehiddenbackup somehiddenfile tabsize aaaaaaaa bbbb cccc dddddddd ncccc neee naaaaa nbcdef nfffff dired subdired tmpfs mdir COLORTERM mexe bcdef mfoo timefile konsole // spell-checker:ignore (words) fakeroot setcap drwxr bcdlps mdangling mentry awith acolons NOFILE NOTCAPABLE iproduct newfstatat isox #![allow( @@ -7106,6 +7106,40 @@ fn test_term_colorterm() { ); } +#[test] +fn test_term_glob_patterns() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.mkdir("dir"); + + for (term, colored) in [ + ("xterm-256color", true), + ("konsole", true), + ("dumb", false), + ("konsole-256color", true), + ("linux-256color", true), + ("konsole-direct", true), + ("con80x25", true), + ] { + let result = scene + .ucmd() + .arg("--color=always") + .env("LS_COLORS", "") + .env("TERM", term) + .succeeds(); + let expected = if colored { + "\\u{1b}[0m\\u{1b}[01;34mdir\\u{1b}[0m" + } else { + "dir" + }; + assert_eq!( + result.stdout_str().trim().escape_default().to_string(), + expected, + "TERM={term}" + ); + } +} + #[cfg(all(unix, not(target_vendor = "apple")))] #[test] fn test_acl_display() {