diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 6099b5a84..66ee792f8 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -16,7 +16,7 @@ path = "src/dircolors.rs" [dependencies] clap = { workspace = true } -uucore = { workspace = true } +uucore = { workspace = true, features = ["colors"] } [[bin]] name = "dircolors" diff --git a/src/uu/dircolors/src/colors.rs b/src/uu/dircolors/src/colors.rs deleted file mode 100644 index c0a981db8..000000000 --- a/src/uu/dircolors/src/colors.rs +++ /dev/null @@ -1,225 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. -// spell-checker:ignore (ToDO) EIGHTBIT ETERM MULTIHARDLINK cpio dtterm jfbterm konsole kterm mlterm rmvb rxvt stat'able svgz tmux webm xspf COLORTERM tzst avif tzst mjpg mjpeg webp dpkg rpmnew rpmorig rpmsave - -pub const INTERNAL_DB: &str = r#"# Configuration file for dircolors, a utility to help you set the -# LS_COLORS environment variable used by GNU ls with the --color option. -# Copyright (C) 1996-2022 Free Software Foundation, Inc. -# Copying and distribution of this file, with or without modification, -# are permitted provided the copyright notice and this notice are preserved. -# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the -# slackware version of dircolors) are recognized but ignored. -# Global config options can be specified before TERM or COLORTERM entries -# Below are TERM or COLORTERM entries, which can be glob patterns, which -# restrict following config to systems with matching environment variables. -COLORTERM ?* -TERM Eterm -TERM ansi -TERM *color* -TERM con[0-9]*x[0-9]* -TERM cons25 -TERM console -TERM cygwin -TERM *direct* -TERM dtterm -TERM gnome -TERM hurd -TERM jfbterm -TERM konsole -TERM kterm -TERM linux -TERM linux-c -TERM mlterm -TERM putty -TERM rxvt* -TERM screen* -TERM st -TERM terminator -TERM tmux* -TERM vt100 -TERM xterm* -# Below are the color init strings for the basic file types. -# One can use codes for 256 or more colors supported by modern terminals. -# The default color codes use the capabilities of an 8 color terminal -# with some additional attributes as per the following codes: -# Attribute codes: -# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed -# Text color codes: -# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white -# Background color codes: -# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white -#NORMAL 00 # no color code at all -#FILE 00 # regular file: use no color at all -RESET 0 # reset to "normal" color -DIR 01;34 # directory -LINK 01;36 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link -FIFO 40;33 # pipe -SOCK 01;35 # socket -DOOR 01;35 # door -BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to -SETUID 37;41 # file that is setuid (u+s) -SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 00 # file with capability (very expensive to lookup) -STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky -STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable -# This is for files with execute permission: -EXEC 01;32 -# List any file extensions like '.gz' or '.tar' that you would like ls -# to color below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') -# If you use DOS-style suffixes, you may want to uncomment the following: -#.cmd 01;32 # executables (bright green) -#.exe 01;32 -#.com 01;32 -#.btm 01;32 -#.bat 01;32 -# Or if you want to color scripts even if they do not have the -# executable bit actually set. -#.sh 01;32 -#.csh 01;32 - # archives or compressed (bright red) -.tar 01;31 -.tgz 01;31 -.arc 01;31 -.arj 01;31 -.taz 01;31 -.lha 01;31 -.lz4 01;31 -.lzh 01;31 -.lzma 01;31 -.tlz 01;31 -.txz 01;31 -.tzo 01;31 -.t7z 01;31 -.zip 01;31 -.z 01;31 -.dz 01;31 -.gz 01;31 -.lrz 01;31 -.lz 01;31 -.lzo 01;31 -.xz 01;31 -.zst 01;31 -.tzst 01;31 -.bz2 01;31 -.bz 01;31 -.tbz 01;31 -.tbz2 01;31 -.tz 01;31 -.deb 01;31 -.rpm 01;31 -.jar 01;31 -.war 01;31 -.ear 01;31 -.sar 01;31 -.rar 01;31 -.alz 01;31 -.ace 01;31 -.zoo 01;31 -.cpio 01;31 -.7z 01;31 -.rz 01;31 -.cab 01;31 -.wim 01;31 -.swm 01;31 -.dwm 01;31 -.esd 01;31 -# image formats -.avif 01;35 -.jpg 01;35 -.jpeg 01;35 -.mjpg 01;35 -.mjpeg 01;35 -.gif 01;35 -.bmp 01;35 -.pbm 01;35 -.pgm 01;35 -.ppm 01;35 -.tga 01;35 -.xbm 01;35 -.xpm 01;35 -.tif 01;35 -.tiff 01;35 -.png 01;35 -.svg 01;35 -.svgz 01;35 -.mng 01;35 -.pcx 01;35 -.mov 01;35 -.mpg 01;35 -.mpeg 01;35 -.m2v 01;35 -.mkv 01;35 -.webm 01;35 -.webp 01;35 -.ogm 01;35 -.mp4 01;35 -.m4v 01;35 -.mp4v 01;35 -.vob 01;35 -.qt 01;35 -.nuv 01;35 -.wmv 01;35 -.asf 01;35 -.rm 01;35 -.rmvb 01;35 -.flc 01;35 -.avi 01;35 -.fli 01;35 -.flv 01;35 -.gl 01;35 -.dl 01;35 -.xcf 01;35 -.xwd 01;35 -.yuv 01;35 -.cgm 01;35 -.emf 01;35 -# https://wiki.xiph.org/MIME_Types_and_File_Extensions -.ogv 01;35 -.ogx 01;35 -# audio formats -.aac 00;36 -.au 00;36 -.flac 00;36 -.m4a 00;36 -.mid 00;36 -.midi 00;36 -.mka 00;36 -.mp3 00;36 -.mpc 00;36 -.ogg 00;36 -.ra 00;36 -.wav 00;36 -# https://wiki.xiph.org/MIME_Types_and_File_Extensions -.oga 00;36 -.opus 00;36 -.spx 00;36 -.xspf 00;36 -# backup files -*~ 00;90 -*# 00;90 -.bak 00;90 -.old 00;90 -.orig 00;90 -.part 00;90 -.rej 00;90 -.swp 00;90 -.tmp 00;90 -.dpkg-dist 00;90 -.dpkg-old 00;90 -.ucf-dist 00;90 -.ucf-new 00;90 -.ucf-old 00;90 -.rpmnew 00;90 -.rpmorig 00;90 -.rpmsave 00;90 -# Subsequent TERM or COLORTERM entries, can be used to add / override -# config specific to those matching environment variables."#; diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 2e3087d81..ecca9d160 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -8,10 +8,12 @@ use std::borrow::Borrow; use std::env; use std::fs::File; +//use std::io::IsTerminal; use std::io::{BufRead, BufReader}; use std::path::Path; use clap::{crate_version, Arg, ArgAction, Command}; +use uucore::colors::{FILE_ATTRIBUTE_CODES, FILE_COLORS, FILE_TYPES, TERMS}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::{help_about, help_section, help_usage}; @@ -28,9 +30,6 @@ const USAGE: &str = help_usage!("dircolors.md"); const ABOUT: &str = help_about!("dircolors.md"); const AFTER_HELP: &str = help_section!("after help", "dircolors.md"); -mod colors; -use self::colors::INTERNAL_DB; - #[derive(PartialEq, Eq, Debug)] pub enum OutputFmt { Shell, @@ -57,6 +56,77 @@ pub fn guess_syntax() -> OutputFmt { } } +fn get_colors_format_strings(fmt: &OutputFmt) -> (String, String) { + let prefix = match fmt { + OutputFmt::Shell => "LS_COLORS='".to_string(), + OutputFmt::CShell => "setenv LS_COLORS '".to_string(), + OutputFmt::Display => String::new(), + OutputFmt::Unknown => unreachable!(), + }; + + let suffix = match fmt { + OutputFmt::Shell => "';\nexport LS_COLORS".to_string(), + OutputFmt::CShell => "'".to_string(), + OutputFmt::Display => String::new(), + OutputFmt::Unknown => unreachable!(), + }; + + (prefix, suffix) +} + +pub fn generate_type_output(fmt: &OutputFmt) -> String { + match fmt { + OutputFmt::Display => FILE_TYPES + .iter() + .map(|&(_, key, val)| format!("\x1b[{}m{}\t{}\x1b[0m", val, key, val)) + .collect::>() + .join("\n"), + _ => { + // Existing logic for other formats + FILE_TYPES + .iter() + .map(|&(_, v1, v2)| format!("{}={}", v1, v2)) + .collect::>() + .join(":") + } + } +} + +fn generate_ls_colors(fmt: &OutputFmt, sep: &str) -> String { + match fmt { + OutputFmt::Display => { + let mut display_parts = vec![]; + let type_output = generate_type_output(fmt); + display_parts.push(type_output); + for &(extension, code) in FILE_COLORS { + let prefix = if extension.starts_with('*') { "" } else { "*" }; + let formatted_extension = + format!("\x1b[{}m{}{}\t{}\x1b[0m", code, prefix, extension, code); + display_parts.push(formatted_extension); + } + display_parts.join("\n") + } + _ => { + // existing logic for other formats + let mut parts = vec![]; + for &(extension, code) in FILE_COLORS { + let prefix = if extension.starts_with('*') { "" } else { "*" }; + let formatted_extension = format!("{}{}", prefix, extension); + parts.push(format!("{}={}", formatted_extension, code)); + } + let (prefix, suffix) = get_colors_format_strings(fmt); + let ls_colors = parts.join(sep); + format!( + "{}{}:{}:{}", + prefix, + generate_type_output(fmt), + ls_colors, + suffix + ) + } + } +} + #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let args = args.collect_ignore(); @@ -97,7 +167,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { ), )); } - println!("{INTERNAL_DB}"); + + println!("{}", generate_dircolors_config()); return Ok(()); } @@ -125,7 +196,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let result; if files.is_empty() { - result = parse(INTERNAL_DB.lines(), &out_format, ""); + println!("{}", generate_ls_colors(&out_format, ":")); + return Ok(()); + /* + // Check if data is being piped into the program + if std::io::stdin().is_terminal() { + // No data piped, use default behavior + println!("{}", generate_ls_colors(&out_format, ":")); + return Ok(()); + } else { + // Data is piped, process the input from stdin + let fin = BufReader::new(std::io::stdin()); + result = parse(fin.lines().map_while(Result::ok), &out_format, "-"); + } + */ } else if files.len() > 1 { return Err(UUsageError::new( 1, @@ -133,6 +217,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { )); } else if files[0].eq("-") { let fin = BufReader::new(std::io::stdin()); + // For example, for echo "owt 40;33"|dircolors -b - result = parse(fin.lines().map_while(Result::ok), &out_format, files[0]); } else { let path = Path::new(files[0]); @@ -276,69 +361,25 @@ enum ParseState { Pass, } -use std::collections::HashMap; use uucore::{format_usage, parse_glob}; #[allow(clippy::cognitive_complexity)] -fn parse(lines: T, fmt: &OutputFmt, fp: &str) -> Result +fn parse(user_input: T, fmt: &OutputFmt, fp: &str) -> Result where T: IntoIterator, T::Item: Borrow, { - // 1790 > $(dircolors | wc -m) let mut result = String::with_capacity(1790); - match fmt { - OutputFmt::Shell => result.push_str("LS_COLORS='"), - OutputFmt::CShell => result.push_str("setenv LS_COLORS '"), - OutputFmt::Display => (), - OutputFmt::Unknown => unreachable!(), - } + let (prefix, suffix) = get_colors_format_strings(fmt); - let mut table: HashMap<&str, &str> = HashMap::with_capacity(48); - table.insert("normal", "no"); - table.insert("norm", "no"); - table.insert("file", "fi"); - table.insert("reset", "rs"); - table.insert("dir", "di"); - table.insert("lnk", "ln"); - table.insert("link", "ln"); - table.insert("symlink", "ln"); - table.insert("orphan", "or"); - table.insert("missing", "mi"); - table.insert("fifo", "pi"); - table.insert("pipe", "pi"); - table.insert("sock", "so"); - table.insert("blk", "bd"); - table.insert("block", "bd"); - table.insert("chr", "cd"); - table.insert("char", "cd"); - table.insert("door", "do"); - table.insert("exec", "ex"); - table.insert("left", "lc"); - table.insert("leftcode", "lc"); - table.insert("right", "rc"); - table.insert("rightcode", "rc"); - table.insert("end", "ec"); - table.insert("endcode", "ec"); - table.insert("suid", "su"); - table.insert("setuid", "su"); - table.insert("sgid", "sg"); - table.insert("setgid", "sg"); - table.insert("sticky", "st"); - table.insert("other_writable", "ow"); - table.insert("owr", "ow"); - table.insert("sticky_other_writable", "tw"); - table.insert("owt", "tw"); - table.insert("capability", "ca"); - table.insert("multihardlink", "mh"); - table.insert("clrtoeol", "cl"); + result.push_str(&prefix); let term = env::var("TERM").unwrap_or_else(|_| "none".to_owned()); let term = term.as_str(); let mut state = ParseState::Global; - for (num, line) in lines.into_iter().enumerate() { + for (num, line) in user_input.into_iter().enumerate() { let num = num + 1; let line = line.borrow().purify(); if line.is_empty() { @@ -350,13 +391,13 @@ where let (key, val) = line.split_two(); if val.is_empty() { return Err(format!( + // The double space is what GNU is doing "{}:{}: invalid line; missing second token", fp.maybe_quote(), num )); } let lower = key.to_lowercase(); - if lower == "term" || lower == "colorterm" { if term.fnmatch(val) { state = ParseState::Matched; @@ -370,6 +411,8 @@ where state = ParseState::Continue; } if state != ParseState::Pass { + let search_key = lower.as_str(); + if key.starts_with('.') { if *fmt == OutputFmt::Display { result.push_str(format!("\x1b[{val}m*{key}\t{val}\x1b[0m\n").as_str()); @@ -384,7 +427,10 @@ where } } else if lower == "options" || lower == "color" || lower == "eightbit" { // Slackware only. Ignore - } else if let Some(s) = table.get(lower.as_str()) { + } else if let Some((_, s)) = FILE_ATTRIBUTE_CODES + .iter() + .find(|&&(key, _)| key == search_key) + { if *fmt == OutputFmt::Display { result.push_str(format!("\x1b[{val}m{s}\t{val}\x1b[0m\n").as_str()); } else { @@ -402,15 +448,11 @@ where } } - match fmt { - OutputFmt::Shell => result.push_str("';\nexport LS_COLORS"), - OutputFmt::CShell => result.push('\''), - OutputFmt::Display => { - // remove latest "\n" - result.pop(); - } - OutputFmt::Unknown => unreachable!(), + if fmt == &OutputFmt::Display { + // remove latest "\n" + result.pop(); } + result.push_str(&suffix); Ok(result) } @@ -436,6 +478,58 @@ fn escape(s: &str) -> String { result } +pub fn generate_dircolors_config() -> String { + let mut config = String::new(); + + config.push_str( + "\ + # Configuration file for dircolors, a utility to help you set the\n\ + # LS_COLORS environment variable used by GNU ls with the --color option.\n\ + # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the\n\ + # slackware version of dircolors) are recognized but ignored.\n\ + # Global config options can be specified before TERM or COLORTERM entries\n\ + # Below are TERM or COLORTERM entries, which can be glob patterns, which\n\ + # restrict following config to systems with matching environment variables.\n\ + ", + ); + config.push_str("COLORTERM ?*\n"); + for term in TERMS { + config.push_str(&format!("TERM {}\n", term)); + } + + config.push_str( + "\ + # Below are the color init strings for the basic file types.\n\ + # One can use codes for 256 or more colors supported by modern terminals.\n\ + # The default color codes use the capabilities of an 8 color terminal\n\ + # with some additional attributes as per the following codes:\n\ + # Attribute codes:\n\ + # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed\n\ + # Text color codes:\n\ + # 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white\n\ + # Background color codes:\n\ + # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white\n\ + #NORMAL 00 # no color code at all\n\ + #FILE 00 # regular file: use no color at all\n\ + ", + ); + + for (name, _, code) in FILE_TYPES { + config.push_str(&format!("{} {}\n", name, code)); + } + + config.push_str("# List any file extensions like '.gz' or '.tar' that you would like ls\n"); + config.push_str("# to color below. Put the extension, a space, and the color init string.\n"); + + for (ext, color) in FILE_COLORS { + config.push_str(&format!("{} {}\n", ext, color)); + } + config.push_str("# Subsequent TERM or COLORTERM entries, can be used to add / override\n"); + config.push_str("# config specific to those matching environment variables."); + + config +} + #[cfg(test)] mod tests { use super::escape; diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index b43445b4a..44f8bb2d1 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -72,6 +72,7 @@ windows-sys = { workspace = true, optional = true, default-features = false, fea default = [] # * non-default features backup-control = [] +colors = [] encoding = ["data-encoding", "data-encoding-macro", "z85", "thiserror"] entries = ["libc"] fs = ["dunce", "libc", "winapi-util", "windows-sys"] diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs index 1d0d43782..a28e8a7bf 100644 --- a/src/uucore/src/lib/features.rs +++ b/src/uucore/src/lib/features.rs @@ -6,6 +6,8 @@ #[cfg(feature = "backup-control")] pub mod backup_control; +#[cfg(feature = "colors")] +pub mod colors; #[cfg(feature = "encoding")] pub mod encoding; #[cfg(feature = "format")] diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs new file mode 100644 index 000000000..e0de8b1e3 --- /dev/null +++ b/src/uucore/src/lib/features/colors.rs @@ -0,0 +1,264 @@ +// This file is part of the uutils coreutils package. +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// cSpell:disable + +/// The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the +/// slackware version of dircolors) are recognized but ignored. +/// Global config options can be specified before TERM or COLORTERM entries +/// below are TERM or COLORTERM entries, which can be glob patterns, which +/// restrict following config to systems with matching environment variables. +pub static TERMS: &[&str] = &[ + "Eterm", + "ansi", + "*color*", + "con[0-9]*x[0-9]*", + "cons25", + "console", + "cygwin", + "*direct*", + "dtterm", + "gnome", + "hurd", + "jfbterm", + "konsole", + "kterm", + "linux", + "linux-c", + "mlterm", + "putty", + "rxvt*", + "screen*", + "st", + "terminator", + "tmux*", + "vt100", + "xterm*", +]; + +/// Below are the color init strings for the basic file types. +/// One can use codes for 256 or more colors supported by modern terminals. +/// The default color codes use the capabilities of an 8 color terminal +/// with some additional attributes as per the following codes: +/// Attribute codes: +/// 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed +/// Text color codes: +/// 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white +/// Background color codes: +/// 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white +/// #NORMAL 00 /// no color code at all +/// #FILE 00 /// regular file: use no color at all +pub static FILE_TYPES: &[(&str, &str, &str)] = &[ + ("RESET", "rs", "0"), // reset to "normal" color + ("DIR", "di", "01;34"), // directory + ("LINK", "ln", "01;36"), // symbolic link + ("MULTIHARDLINK", "mh", "00"), // regular file with more than one link + ("FIFO", "pi", "40;33"), // pipe + ("SOCK", "so", "01;35"), // socket + ("DOOR", "do", "01;35"), // door + ("BLK", "bd", "40;33;01"), // block device driver + ("CHR", "cd", "40;33;01"), // character device driver + ("ORPHAN", "or", "40;31;01"), // symlink to nonexistent file, or non-stat'able file + ("MISSING", "mi", "00"), // ... and the files they point to + ("SETUID", "su", "37;41"), // file that is setuid (u+s) + ("SETGID", "sg", "30;43"), // file that is setgid (g+s) + ("CAPABILITY", "ca", "00"), // file with capability + ("STICKY_OTHER_WRITABLE", "tw", "30;42"), // dir that is sticky and other-writable (+t,o+w) + ("OTHER_WRITABLE", "ow", "34;42"), // dir that is other-writable (o+w) and not sticky + ("STICKY", "st", "37;44"), // dir with the sticky bit set (+t) and not other-writable + ("EXEC", "ex", "01;32"), // files with execute permission +]; + +/// Colors for file types +/// +/// List any file extensions like '.gz' or '.tar' that you would like ls +/// to color below. Put the extension, a space, and the color init string. +/// (and any comments you want to add after a '#') +pub static FILE_COLORS: &[(&str, &str)] = &[ + /* + // Executables (Windows) + (".cmd", "01;32"), + (".exe", "01;32"), + (".com", "01;32"), + (".btm", "01;32"), + (".bat", "01;32"), + (".sh", "01;32"), + (".csh", "01;32"),*/ + // Archives or compressed + (".tar", "01;31"), + (".tgz", "01;31"), + (".arc", "01;31"), + (".arj", "01;31"), + (".taz", "01;31"), + (".lha", "01;31"), + (".lz4", "01;31"), + (".lzh", "01;31"), + (".lzma", "01;31"), + (".tlz", "01;31"), + (".txz", "01;31"), + (".tzo", "01;31"), + (".t7z", "01;31"), + (".zip", "01;31"), + (".z", "01;31"), + (".dz", "01;31"), + (".gz", "01;31"), + (".lrz", "01;31"), + (".lz", "01;31"), + (".lzo", "01;31"), + (".xz", "01;31"), + (".zst", "01;31"), + (".tzst", "01;31"), + (".bz2", "01;31"), + (".bz", "01;31"), + (".tbz", "01;31"), + (".tbz2", "01;31"), + (".tz", "01;31"), + (".deb", "01;31"), + (".rpm", "01;31"), + (".jar", "01;31"), + (".war", "01;31"), + (".ear", "01;31"), + (".sar", "01;31"), + (".rar", "01;31"), + (".alz", "01;31"), + (".ace", "01;31"), + (".zoo", "01;31"), + (".cpio", "01;31"), + (".7z", "01;31"), + (".rz", "01;31"), + (".cab", "01;31"), + (".wim", "01;31"), + (".swm", "01;31"), + (".dwm", "01;31"), + (".esd", "01;31"), + // Image formats + (".avif", "01;35"), + (".jpg", "01;35"), + (".jpeg", "01;35"), + (".mjpg", "01;35"), + (".mjpeg", "01;35"), + (".gif", "01;35"), + (".bmp", "01;35"), + (".pbm", "01;35"), + (".pgm", "01;35"), + (".ppm", "01;35"), + (".tga", "01;35"), + (".xbm", "01;35"), + (".xpm", "01;35"), + (".tif", "01;35"), + (".tiff", "01;35"), + (".png", "01;35"), + (".svg", "01;35"), + (".svgz", "01;35"), + (".mng", "01;35"), + (".pcx", "01;35"), + (".mov", "01;35"), + (".mpg", "01;35"), + (".mpeg", "01;35"), + (".m2v", "01;35"), + (".mkv", "01;35"), + (".webm", "01;35"), + (".webp", "01;35"), + (".ogm", "01;35"), + (".mp4", "01;35"), + (".m4v", "01;35"), + (".mp4v", "01;35"), + (".vob", "01;35"), + (".qt", "01;35"), + (".nuv", "01;35"), + (".wmv", "01;35"), + (".asf", "01;35"), + (".rm", "01;35"), + (".rmvb", "01;35"), + (".flc", "01;35"), + (".avi", "01;35"), + (".fli", "01;35"), + (".flv", "01;35"), + (".gl", "01;35"), + (".dl", "01;35"), + (".xcf", "01;35"), + (".xwd", "01;35"), + (".yuv", "01;35"), + (".cgm", "01;35"), + (".emf", "01;35"), + // https://wiki.xiph.org/MIME_Types_and_File_Extensions + (".ogv", "01;35"), + (".ogx", "01;35"), + // Audio formats + (".aac", "00;36"), + (".au", "00;36"), + (".flac", "00;36"), + (".m4a", "00;36"), + (".mid", "00;36"), + (".midi", "00;36"), + (".mka", "00;36"), + (".mp3", "00;36"), + (".mpc", "00;36"), + (".ogg", "00;36"), + (".ra", "00;36"), + (".wav", "00;36"), + // https://wiki.xiph.org/MIME_Types_and_File_Extensions + (".oga", "00;36"), + (".opus", "00;36"), + (".spx", "00;36"), + (".xspf", "00;36"), + // Backup files + ("*~", "00;90"), + ("*#", "00;90"), + (".bak", "00;90"), + (".old", "00;90"), + (".orig", "00;90"), + (".part", "00;90"), + (".rej", "00;90"), + (".swp", "00;90"), + (".tmp", "00;90"), + (".dpkg-dist", "00;90"), + (".dpkg-old", "00;90"), + (".ucf-dist", "00;90"), + (".ucf-new", "00;90"), + (".ucf-old", "00;90"), + (".rpmnew", "00;90"), + (".rpmorig", "00;90"), + (".rpmsave", "00;90"), +]; + +pub static FILE_ATTRIBUTE_CODES: &[(&str, &str)] = &[ + ("normal", "no"), + ("norm", "no"), + ("file", "fi"), + ("reset", "rs"), + ("dir", "di"), + ("lnk", "ln"), + ("link", "ln"), + ("symlink", "ln"), + ("orphan", "or"), + ("missing", "mi"), + ("fifo", "pi"), + ("pipe", "pi"), + ("sock", "so"), + ("blk", "bd"), + ("block", "bd"), + ("chr", "cd"), + ("char", "cd"), + ("door", "do"), + ("exec", "ex"), + ("left", "lc"), + ("leftcode", "lc"), + ("right", "rc"), + ("rightcode", "rc"), + ("end", "ec"), + ("endcode", "ec"), + ("suid", "su"), + ("setuid", "su"), + ("sgid", "sg"), + ("setgid", "sg"), + ("sticky", "st"), + ("other_writable", "ow"), + ("owr", "ow"), + ("sticky_other_writable", "tw"), + ("owt", "tw"), + ("capability", "ca"), + ("multihardlink", "mh"), + ("clrtoeol", "cl"), +]; diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index af8668ef0..426b4216c 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -35,6 +35,8 @@ pub use crate::parser::shortcut_value_parser; // * feature-gated modules #[cfg(feature = "backup-control")] pub use crate::features::backup_control; +#[cfg(feature = "colors")] +pub use crate::features::colors; #[cfg(feature = "encoding")] pub use crate::features::encoding; #[cfg(feature = "format")] diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index d4fa0a3b0..4a256352c 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -159,6 +159,18 @@ fn test_quoting() { .no_stderr(); } +/* +#[test] +fn test_print_ls_colors() { + new_ucmd!() + .pipe_in("OWT 40;33\n") + .args(&["--print-ls-colors"]) + .succeeds() + .stdout_is("\x1B[40;33mtw\t40;33\x1B[0m\n") + .no_stderr(); +} +*/ + #[test] fn test_extra_operand() { new_ucmd!() diff --git a/tests/fixtures/dircolors/internal.expected b/tests/fixtures/dircolors/internal.expected index 7bc91ef47..e151973f2 100644 --- a/tests/fixtures/dircolors/internal.expected +++ b/tests/fixtures/dircolors/internal.expected @@ -1,8 +1,5 @@ # Configuration file for dircolors, a utility to help you set the # LS_COLORS environment variable used by GNU ls with the --color option. -# Copyright (C) 1996-2022 Free Software Foundation, Inc. -# Copying and distribution of this file, with or without modification, -# are permitted provided the copyright notice and this notice are preserved. # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the # slackware version of dircolors) are recognized but ignored. # Global config options can be specified before TERM or COLORTERM entries @@ -46,40 +43,26 @@ TERM xterm* # 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all -RESET 0 # reset to "normal" color -DIR 01;34 # directory -LINK 01;36 # symbolic link. (If you set this to 'target' instead of a - # numerical value, the color is as for the file pointed to.) -MULTIHARDLINK 00 # regular file with more than one link -FIFO 40;33 # pipe -SOCK 01;35 # socket -DOOR 01;35 # door -BLK 40;33;01 # block device driver -CHR 40;33;01 # character device driver -ORPHAN 40;31;01 # symlink to nonexistent file, or non-stat'able file ... -MISSING 00 # ... and the files they point to -SETUID 37;41 # file that is setuid (u+s) -SETGID 30;43 # file that is setgid (g+s) -CAPABILITY 00 # file with capability (very expensive to lookup) -STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) -OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky -STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable -# This is for files with execute permission: +RESET 0 +DIR 01;34 +LINK 01;36 +MULTIHARDLINK 00 +FIFO 40;33 +SOCK 01;35 +DOOR 01;35 +BLK 40;33;01 +CHR 40;33;01 +ORPHAN 40;31;01 +MISSING 00 +SETUID 37;41 +SETGID 30;43 +CAPABILITY 00 +STICKY_OTHER_WRITABLE 30;42 +OTHER_WRITABLE 34;42 +STICKY 37;44 EXEC 01;32 # List any file extensions like '.gz' or '.tar' that you would like ls # to color below. Put the extension, a space, and the color init string. -# (and any comments you want to add after a '#') -# If you use DOS-style suffixes, you may want to uncomment the following: -#.cmd 01;32 # executables (bright green) -#.exe 01;32 -#.com 01;32 -#.btm 01;32 -#.bat 01;32 -# Or if you want to color scripts even if they do not have the -# executable bit actually set. -#.sh 01;32 -#.csh 01;32 - # archives or compressed (bright red) .tar 01;31 .tgz 01;31 .arc 01;31 @@ -126,7 +109,6 @@ EXEC 01;32 .swm 01;31 .dwm 01;31 .esd 01;31 -# image formats .avif 01;35 .jpg 01;35 .jpeg 01;35 @@ -176,10 +158,8 @@ EXEC 01;32 .yuv 01;35 .cgm 01;35 .emf 01;35 -# https://wiki.xiph.org/MIME_Types_and_File_Extensions .ogv 01;35 .ogx 01;35 -# audio formats .aac 00;36 .au 00;36 .flac 00;36 @@ -192,12 +172,10 @@ EXEC 01;32 .ogg 00;36 .ra 00;36 .wav 00;36 -# https://wiki.xiph.org/MIME_Types_and_File_Extensions .oga 00;36 .opus 00;36 .spx 00;36 .xspf 00;36 -# backup files *~ 00;90 *# 00;90 .bak 00;90