From 13a4c9114c4574ee8d14ffe0bb6b326ad203375d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 2 Dec 2023 10:28:45 +0100 Subject: [PATCH 01/13] create datastructures for colors --- src/uucore/src/lib/features.rs | 2 + src/uucore/src/lib/features/colors.rs | 225 ++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 src/uucore/src/lib/features/colors.rs diff --git a/src/uucore/src/lib/features.rs b/src/uucore/src/lib/features.rs index 1d0d437824..a28e8a7bfc 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 0000000000..58b0b75708 --- /dev/null +++ b/src/uucore/src/lib/features/colors.rs @@ -0,0 +1,225 @@ +// 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. + +/* 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 ?* +*/ + +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 +*/ +static FILE_TYPES: &[(&str, &str)] = &[ + ("RESET", "0"), // reset to "normal" color + ("DIR", "01;34"), // directory + ("LINK", "01;36"), // symbolic link + ("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 + ("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 + ("EXEC", "01;32"), // files with execute permission +]; + +/* +# 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 '#') +*/ +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"), + (".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"), + (".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"), +]; From 0e8c171c80ab35f4d16a2613700648ec059ebaa5 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 2 Dec 2023 11:00:55 +0100 Subject: [PATCH 02/13] dircolors: move the FILE_ATTRIBUTE_CODES datastructures and use it --- src/uu/dircolors/Cargo.toml | 2 +- src/uu/dircolors/src/dircolors.rs | 43 +-- src/uucore/Cargo.toml | 1 + src/uucore/src/lib/features/colors.rs | 458 +++++++++++++++----------- src/uucore/src/lib/lib.rs | 2 + 5 files changed, 273 insertions(+), 233 deletions(-) diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 6099b5a842..66ee792f83 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/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 2e3087d810..58228ddeb5 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -12,6 +12,7 @@ use std::io::{BufRead, BufReader}; use std::path::Path; use clap::{crate_version, Arg, ArgAction, Command}; +use uucore::colors::FILE_ATTRIBUTE_CODES; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::{help_about, help_section, help_usage}; @@ -276,7 +277,6 @@ enum ParseState { Pass, } -use std::collections::HashMap; use uucore::{format_usage, parse_glob}; #[allow(clippy::cognitive_complexity)] @@ -294,45 +294,6 @@ where OutputFmt::Unknown => unreachable!(), } - 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"); - let term = env::var("TERM").unwrap_or_else(|_| "none".to_owned()); let term = term.as_str(); @@ -384,7 +345,7 @@ 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.get(lower.as_str()) { if *fmt == OutputFmt::Display { result.push_str(format!("\x1b[{val}m{s}\t{val}\x1b[0m\n").as_str()); } else { diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index b43445b4a9..44f8bb2d13 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/colors.rs b/src/uucore/src/lib/features/colors.rs index 58b0b75708..69be16ba29 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -3,6 +3,9 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. +use once_cell::sync::Lazy; +use std::collections::HashMap; + /* 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 @@ -11,33 +14,41 @@ * COLORTERM ?* */ -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*", -]; +pub static TERMS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + [ + "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*", + ] + .iter() + .for_each(|&term| { + m.insert(term, ""); + }); + m +}); /* # Below are the color init strings for the basic file types. @@ -53,173 +64,238 @@ static TERMS: &[&str] = &[ #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all */ -static FILE_TYPES: &[(&str, &str)] = &[ - ("RESET", "0"), // reset to "normal" color - ("DIR", "01;34"), // directory - ("LINK", "01;36"), // symbolic link - ("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 - ("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 - ("EXEC", "01;32"), // files with execute permission -]; +// FILE_TYPES with Lazy initialization +pub static FILE_TYPES: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + [ + ("RESET", "0"), // reset to "normal" color + ("DIR", "01;34"), // directory + ("LINK", "01;36"), // symbolic link + ("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 + ("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 + ("EXEC", "01;32"), // files with execute permission + ] + .iter() + .for_each(|&(k, v)| { + m.insert(k, v); + }); + m +}); /* # 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 '#') */ -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"), - (".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"), - (".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_COLORS: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + [ + // 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"), + (".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"), + (".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"), + ] + .iter() + .for_each(|&(k, v)| { + m.insert(k, v); + }); + m +}); + +pub static FILE_ATTRIBUTE_CODES: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + [ + ("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"), + ] + .iter() + .for_each(|&(k, v)| { + m.insert(k, v); + }); + m +}); diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index af8668ef02..426b4216ca 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")] From 5d19f79cd0b791bf28c9c8d9d8f4fd61817f6026 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 2 Dec 2023 12:57:38 +0100 Subject: [PATCH 03/13] dircolors should use the datastructures when printing --- src/uu/dircolors/src/dircolors.rs | 119 ++++++++++++++++++++++---- src/uucore/src/lib/features/colors.rs | 89 +++++++------------ 2 files changed, 134 insertions(+), 74 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 58228ddeb5..43e35c3d2a 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -12,7 +12,7 @@ use std::io::{BufRead, BufReader}; use std::path::Path; use clap::{crate_version, Arg, ArgAction, Command}; -use uucore::colors::FILE_ATTRIBUTE_CODES; +use uucore::colors::{FILE_ATTRIBUTE_CODES, FILE_COLORS, FILE_TYPES}; use uucore::display::Quotable; use uucore::error::{UResult, USimpleError, UUsageError}; use uucore::{help_about, help_section, help_usage}; @@ -58,6 +58,89 @@ 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(":") + } + } +} + +enum ExtensionFormat { + StarDot, // Format as ".*ext" + Dot, // Format as ".ext" + NoDot, // Format as "ext" +} + +fn generate_ls_colors(fmt: &OutputFmt, format: ExtensionFormat, 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.iter() { + display_parts.push(format!("\x1b[{}m*{}\t{}\x1b[0m", code, extension, code)); + } + display_parts.join("\n") + } + _ => { + // existing logic for other formats + let mut parts = vec![]; + for &(extension, code) in FILE_COLORS.iter() { + let formatted_extension = match format { + ExtensionFormat::StarDot => format!("*{}", extension), + ExtensionFormat::Dot => extension.to_string(), + ExtensionFormat::NoDot => { + if extension.starts_with('.') { + extension[1..].to_string() + } else { + extension.to_string() + } + } + }; + 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(); @@ -126,7 +209,12 @@ 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, ExtensionFormat::StarDot, ":") + ); + + return Ok(()); } else if files.len() > 1 { return Err(UUsageError::new( 1, @@ -287,12 +375,9 @@ where { // 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); + + result.push_str(&prefix); let term = env::var("TERM").unwrap_or_else(|_| "none".to_owned()); let term = term.as_str(); @@ -331,6 +416,7 @@ 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()); @@ -345,7 +431,10 @@ where } } else if lower == "options" || lower == "color" || lower == "eightbit" { // Slackware only. Ignore - } else if let Some(s) = FILE_ATTRIBUTE_CODES.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 { @@ -363,15 +452,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) } diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs index 69be16ba29..96ca6d4567 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -4,19 +4,15 @@ // file that was distributed with this source code. use once_cell::sync::Lazy; -use std::collections::HashMap; /* 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 ?* */ - -pub static TERMS: Lazy> = Lazy::new(|| { - let mut m = HashMap::new(); - [ +pub static TERMS: Lazy> = Lazy::new(|| { + vec![ "Eterm", "ansi", "*color*", @@ -43,11 +39,6 @@ pub static TERMS: Lazy> = Lazy::new(|| { "vt100", "xterm*", ] - .iter() - .for_each(|&term| { - m.insert(term, ""); - }); - m }); /* @@ -64,34 +55,27 @@ pub static TERMS: Lazy> = Lazy::new(|| { #NORMAL 00 # no color code at all #FILE 00 # regular file: use no color at all */ -// FILE_TYPES with Lazy initialization -pub static FILE_TYPES: Lazy> = Lazy::new(|| { - let mut m = HashMap::new(); - [ - ("RESET", "0"), // reset to "normal" color - ("DIR", "01;34"), // directory - ("LINK", "01;36"), // symbolic link - ("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 - ("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 - ("EXEC", "01;32"), // files with execute permission +pub static FILE_TYPES: Lazy> = Lazy::new(|| { + vec![ + ("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 ] - .iter() - .for_each(|&(k, v)| { - m.insert(k, v); - }); - m }); /* @@ -99,9 +83,9 @@ pub static FILE_TYPES: Lazy> = Lazy::new(|| { # 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: Lazy> = Lazy::new(|| { - let mut m = HashMap::new(); - [ +pub static FILE_COLORS: Lazy> = Lazy::new(|| { + vec![ + /* // Executables (Windows) (".cmd", "01;32"), (".exe", "01;32"), @@ -109,7 +93,7 @@ pub static FILE_COLORS: Lazy> = Lazy::new(|| { (".btm", "01;32"), (".bat", "01;32"), (".sh", "01;32"), - (".csh", "01;32"), + (".csh", "01;32"),*/ // Archives or compressed (".tar", "01;31"), (".tgz", "01;31"), @@ -207,6 +191,7 @@ pub static FILE_COLORS: Lazy> = Lazy::new(|| { (".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 @@ -222,13 +207,14 @@ pub static FILE_COLORS: Lazy> = Lazy::new(|| { (".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"), + ("~", "00;90"), + ("#", "00;90"), (".bak", "00;90"), (".old", "00;90"), (".orig", "00;90"), @@ -245,16 +231,10 @@ pub static FILE_COLORS: Lazy> = Lazy::new(|| { (".rpmorig", "00;90"), (".rpmsave", "00;90"), ] - .iter() - .for_each(|&(k, v)| { - m.insert(k, v); - }); - m }); -pub static FILE_ATTRIBUTE_CODES: Lazy> = Lazy::new(|| { - let mut m = HashMap::new(); - [ +pub static FILE_ATTRIBUTE_CODES: Lazy> = Lazy::new(|| { + vec![ ("normal", "no"), ("norm", "no"), ("file", "fi"), @@ -293,9 +273,4 @@ pub static FILE_ATTRIBUTE_CODES: Lazy> = Lazy::new(|| { ("multihardlink", "mh"), ("clrtoeol", "cl"), ] - .iter() - .for_each(|&(k, v)| { - m.insert(k, v); - }); - m }); From e4b875043429ac78f4ae4b2824caea3e8d180244 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 2 Dec 2023 15:06:09 +0100 Subject: [PATCH 04/13] dircolors -p: generate it dynamically --- src/uu/dircolors/src/colors.rs | 225 --------------------- src/uu/dircolors/src/dircolors.rs | 65 +++++- tests/fixtures/dircolors/internal.expected | 60 ++---- 3 files changed, 75 insertions(+), 275 deletions(-) delete mode 100644 src/uu/dircolors/src/colors.rs diff --git a/src/uu/dircolors/src/colors.rs b/src/uu/dircolors/src/colors.rs deleted file mode 100644 index c0a981db89..0000000000 --- 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 43e35c3d2a..338bf83e51 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -10,9 +10,10 @@ use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::Path; +use std::fmt::Write; use clap::{crate_version, Arg, ArgAction, Command}; -use uucore::colors::{FILE_ATTRIBUTE_CODES, FILE_COLORS, FILE_TYPES}; +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}; @@ -29,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, @@ -181,7 +179,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { ), )); } - println!("{INTERNAL_DB}"); + + println!("{}", generate_dircolors_config()); return Ok(()); } @@ -222,6 +221,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]); @@ -368,7 +368,7 @@ enum ParseState { 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, @@ -384,7 +384,7 @@ where 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() { @@ -396,13 +396,12 @@ where let (key, val) = line.split_two(); if val.is_empty() { return Err(format!( - "{}:{}: invalid line; missing second token", + "{}:{}: 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; @@ -417,6 +416,7 @@ where } 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()); @@ -482,6 +482,53 @@ fn escape(s: &str) -> String { result } + +pub fn generate_dircolors_config() -> String { + let mut config = String::new(); + + // Adding the complete header comments as in the original file + writeln!(config, "# Configuration file for dircolors, a utility to help you set the").unwrap(); + writeln!(config, "# LS_COLORS environment variable used by GNU ls with the --color option.").unwrap(); + writeln!(config, "# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the").unwrap(); + writeln!(config, "# slackware version of dircolors) are recognized but ignored.").unwrap(); + writeln!(config, "# Global config options can be specified before TERM or COLORTERM entries").unwrap(); + writeln!(config, "# Below are TERM or COLORTERM entries, which can be glob patterns, which").unwrap(); + writeln!(config, "# restrict following config to systems with matching environment variables.").unwrap(); + writeln!(config, "COLORTERM ?*").unwrap(); + for term in TERMS.iter() { + writeln!(config, "TERM {}", term).unwrap(); + } + + // Adding file types and their color codes with header + writeln!(config, "# Below are the color init strings for the basic file types.").unwrap(); + writeln!(config, "# One can use codes for 256 or more colors supported by modern terminals.").unwrap(); + writeln!(config, "# The default color codes use the capabilities of an 8 color terminal").unwrap(); + writeln!(config, "# with some additional attributes as per the following codes:").unwrap(); + writeln!(config, "# Attribute codes:").unwrap(); + writeln!(config, "# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed").unwrap(); + writeln!(config, "# Text color codes:").unwrap(); + writeln!(config, "# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white").unwrap(); + writeln!(config, "# Background color codes:").unwrap(); + writeln!(config, "# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white").unwrap(); + writeln!(config, "#NORMAL 00 # no color code at all").unwrap(); + writeln!(config, "#FILE 00 # regular file: use no color at all").unwrap(); + + for (name, _, code) in FILE_TYPES.iter() { + writeln!(config, "{} {}", name, code).unwrap(); + } + + writeln!(config, "# List any file extensions like '.gz' or '.tar' that you would like ls").unwrap(); + writeln!(config, "# to color below. Put the extension, a space, and the color init string.").unwrap(); + + for (ext, color) in FILE_COLORS.iter() { + writeln!(config, "{} {}", ext, color).unwrap(); + } + writeln!(config, "# Subsequent TERM or COLORTERM entries, can be used to add / override").unwrap(); + write!(config, "# config specific to those matching environment variables.").unwrap(); + + config +} + #[cfg(test)] mod tests { use super::escape; diff --git a/tests/fixtures/dircolors/internal.expected b/tests/fixtures/dircolors/internal.expected index 7bc91ef470..933e70bc47 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,14 +172,12 @@ 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 +~ 00;90 +# 00;90 .bak 00;90 .old 00;90 .orig 00;90 From 1a4ca7e65dc6991f8584c6f03d493bace427ff2d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 2 Dec 2023 15:18:20 +0100 Subject: [PATCH 05/13] fix clippy warnings --- src/uu/dircolors/src/dircolors.rs | 143 +++++++++++++++++--------- src/uucore/src/lib/features/colors.rs | 2 +- 2 files changed, 98 insertions(+), 47 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 338bf83e51..28d74775db 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -7,10 +7,10 @@ use std::borrow::Borrow; use std::env; +use std::fmt::Write; use std::fs::File; use std::io::{BufRead, BufReader}; use std::path::Path; -use std::fmt::Write; use clap::{crate_version, Arg, ArgAction, Command}; use uucore::colors::{FILE_ATTRIBUTE_CODES, FILE_COLORS, FILE_TYPES, TERMS}; @@ -92,13 +92,7 @@ pub fn generate_type_output(fmt: &OutputFmt) -> String { } } -enum ExtensionFormat { - StarDot, // Format as ".*ext" - Dot, // Format as ".ext" - NoDot, // Format as "ext" -} - -fn generate_ls_colors(fmt: &OutputFmt, format: ExtensionFormat, sep: &str) -> String { +fn generate_ls_colors(fmt: &OutputFmt, sep: &str) -> String { match fmt { OutputFmt::Display => { let mut display_parts = vec![]; @@ -113,25 +107,15 @@ fn generate_ls_colors(fmt: &OutputFmt, format: ExtensionFormat, sep: &str) -> St // existing logic for other formats let mut parts = vec![]; for &(extension, code) in FILE_COLORS.iter() { - let formatted_extension = match format { - ExtensionFormat::StarDot => format!("*{}", extension), - ExtensionFormat::Dot => extension.to_string(), - ExtensionFormat::NoDot => { - if extension.starts_with('.') { - extension[1..].to_string() - } else { - extension.to_string() - } - } - }; + let formatted_extension = format!("*{}", extension); parts.push(format!("{}={}", formatted_extension, code)); } - let (prefix, suffix) = get_colors_format_strings(&fmt); + let (prefix, suffix) = get_colors_format_strings(fmt); let ls_colors = parts.join(sep); format!( "{}{}:{}:{}", prefix, - generate_type_output(&fmt), + generate_type_output(fmt), ls_colors, suffix ) @@ -208,10 +192,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let result; if files.is_empty() { - println!( - "{}", - generate_ls_colors(&out_format, ExtensionFormat::StarDot, ":") - ); + println!("{}", generate_ls_colors(&out_format, ":")); return Ok(()); } else if files.len() > 1 { @@ -373,9 +354,8 @@ where T: IntoIterator, T::Item: Borrow, { - // 1790 > $(dircolors | wc -m) let mut result = String::with_capacity(1790); - let (prefix, suffix) = get_colors_format_strings(&fmt); + let (prefix, suffix) = get_colors_format_strings(fmt); result.push_str(&prefix); @@ -482,34 +462,89 @@ fn escape(s: &str) -> String { result } - pub fn generate_dircolors_config() -> String { let mut config = String::new(); // Adding the complete header comments as in the original file - writeln!(config, "# Configuration file for dircolors, a utility to help you set the").unwrap(); - writeln!(config, "# LS_COLORS environment variable used by GNU ls with the --color option.").unwrap(); - writeln!(config, "# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the").unwrap(); - writeln!(config, "# slackware version of dircolors) are recognized but ignored.").unwrap(); - writeln!(config, "# Global config options can be specified before TERM or COLORTERM entries").unwrap(); - writeln!(config, "# Below are TERM or COLORTERM entries, which can be glob patterns, which").unwrap(); - writeln!(config, "# restrict following config to systems with matching environment variables.").unwrap(); + writeln!( + config, + "# Configuration file for dircolors, a utility to help you set the" + ) + .unwrap(); + writeln!( + config, + "# LS_COLORS environment variable used by GNU ls with the --color option." + ) + .unwrap(); + writeln!( + config, + "# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the" + ) + .unwrap(); + writeln!( + config, + "# slackware version of dircolors) are recognized but ignored." + ) + .unwrap(); + writeln!( + config, + "# Global config options can be specified before TERM or COLORTERM entries" + ) + .unwrap(); + writeln!( + config, + "# Below are TERM or COLORTERM entries, which can be glob patterns, which" + ) + .unwrap(); + writeln!( + config, + "# restrict following config to systems with matching environment variables." + ) + .unwrap(); writeln!(config, "COLORTERM ?*").unwrap(); for term in TERMS.iter() { writeln!(config, "TERM {}", term).unwrap(); } // Adding file types and their color codes with header - writeln!(config, "# Below are the color init strings for the basic file types.").unwrap(); - writeln!(config, "# One can use codes for 256 or more colors supported by modern terminals.").unwrap(); - writeln!(config, "# The default color codes use the capabilities of an 8 color terminal").unwrap(); - writeln!(config, "# with some additional attributes as per the following codes:").unwrap(); + writeln!( + config, + "# Below are the color init strings for the basic file types." + ) + .unwrap(); + writeln!( + config, + "# One can use codes for 256 or more colors supported by modern terminals." + ) + .unwrap(); + writeln!( + config, + "# The default color codes use the capabilities of an 8 color terminal" + ) + .unwrap(); + writeln!( + config, + "# with some additional attributes as per the following codes:" + ) + .unwrap(); writeln!(config, "# Attribute codes:").unwrap(); - writeln!(config, "# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed").unwrap(); + writeln!( + config, + "# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed" + ) + .unwrap(); writeln!(config, "# Text color codes:").unwrap(); - writeln!(config, "# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white").unwrap(); + writeln!( + config, + "# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white" + ) + .unwrap(); writeln!(config, "# Background color codes:").unwrap(); - writeln!(config, "# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white").unwrap(); + writeln!( + config, + "# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white" + ) + .unwrap(); writeln!(config, "#NORMAL 00 # no color code at all").unwrap(); writeln!(config, "#FILE 00 # regular file: use no color at all").unwrap(); @@ -517,14 +552,30 @@ pub fn generate_dircolors_config() -> String { writeln!(config, "{} {}", name, code).unwrap(); } - writeln!(config, "# List any file extensions like '.gz' or '.tar' that you would like ls").unwrap(); - writeln!(config, "# to color below. Put the extension, a space, and the color init string.").unwrap(); + writeln!( + config, + "# List any file extensions like '.gz' or '.tar' that you would like ls" + ) + .unwrap(); + writeln!( + config, + "# to color below. Put the extension, a space, and the color init string." + ) + .unwrap(); for (ext, color) in FILE_COLORS.iter() { writeln!(config, "{} {}", ext, color).unwrap(); } - writeln!(config, "# Subsequent TERM or COLORTERM entries, can be used to add / override").unwrap(); - write!(config, "# config specific to those matching environment variables.").unwrap(); + writeln!( + config, + "# Subsequent TERM or COLORTERM entries, can be used to add / override" + ) + .unwrap(); + write!( + config, + "# config specific to those matching environment variables." + ) + .unwrap(); config } diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs index 96ca6d4567..81d117a50b 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. - +// cSpell:disable use once_cell::sync::Lazy; /* The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the From f5776bc511ec0fbe5dac93af190ef8a3c8d610be Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 4 Dec 2023 22:40:18 +0100 Subject: [PATCH 06/13] fix comment Co-authored-by: Terts Diepraam --- src/uucore/src/lib/features/colors.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs index 81d117a50b..1f55db5a7d 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -78,11 +78,11 @@ pub static FILE_TYPES: Lazy> = L ] }); -/* -# 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 '#') -*/ +/// 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: Lazy> = Lazy::new(|| { vec![ /* From dabbcff9fbbbce7c0ec692431f73fb17657c8199 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 3 Dec 2023 10:34:33 +0100 Subject: [PATCH 07/13] dircolors: manage the --print-ls-colors pipe option --- src/uu/dircolors/src/dircolors.rs | 17 +++++++++++++---- tests/by-util/test_dircolors.rs | 10 ++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 28d74775db..cf8ed62922 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -9,6 +9,7 @@ use std::borrow::Borrow; use std::env; use std::fmt::Write; use std::fs::File; +use std::io::IsTerminal; use std::io::{BufRead, BufReader}; use std::path::Path; @@ -192,9 +193,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let result; if files.is_empty() { - 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, @@ -376,7 +384,8 @@ where let (key, val) = line.split_two(); if val.is_empty() { return Err(format!( - "{}:{}: invalid line; missing second token", + // The double space is what GNU is doing + "{}:{}: invalid line; missing second token", fp.maybe_quote(), num )); diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index d4fa0a3b0a..e3752fcde9 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -159,6 +159,16 @@ 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!() From 3e354109076eb1f806715e0d5c89006fd2a1a12a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 4 Dec 2023 22:47:42 +0100 Subject: [PATCH 08/13] dircolors: fix comments --- src/uucore/src/lib/features/colors.rs | 512 +++++++++++++------------- 1 file changed, 250 insertions(+), 262 deletions(-) diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs index 1f55db5a7d..81d2fd3f33 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -3,274 +3,262 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // cSpell:disable -use once_cell::sync::Lazy; -/* 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: Lazy> = Lazy::new(|| { - vec![ - "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*", - ] -}); +/// 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: Lazy> = Lazy::new(|| { - vec![ - ("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 - ] -}); +/// 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: Lazy> = Lazy::new(|| { - vec![ - /* - // 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_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: Lazy> = Lazy::new(|| { - vec![ - ("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"), - ] -}); +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"), +]; From 1c9413e185c8eb16175761b929a373578f0607e3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 4 Dec 2023 22:51:08 +0100 Subject: [PATCH 09/13] bring back the old format --- src/uucore/src/lib/features/colors.rs | 4 ++-- tests/fixtures/dircolors/internal.expected | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uucore/src/lib/features/colors.rs b/src/uucore/src/lib/features/colors.rs index 81d2fd3f33..e0de8b1e3e 100644 --- a/src/uucore/src/lib/features/colors.rs +++ b/src/uucore/src/lib/features/colors.rs @@ -204,8 +204,8 @@ pub static FILE_COLORS: &[(&str, &str)] = &[ (".spx", "00;36"), (".xspf", "00;36"), // Backup files - ("~", "00;90"), - ("#", "00;90"), + ("*~", "00;90"), + ("*#", "00;90"), (".bak", "00;90"), (".old", "00;90"), (".orig", "00;90"), diff --git a/tests/fixtures/dircolors/internal.expected b/tests/fixtures/dircolors/internal.expected index 933e70bc47..e151973f20 100644 --- a/tests/fixtures/dircolors/internal.expected +++ b/tests/fixtures/dircolors/internal.expected @@ -176,8 +176,8 @@ EXEC 01;32 .opus 00;36 .spx 00;36 .xspf 00;36 -~ 00;90 -# 00;90 +*~ 00;90 +*# 00;90 .bak 00;90 .old 00;90 .orig 00;90 From b0fdb1edef1a197c95faf83ffbb325190dfee9c3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 4 Dec 2023 23:25:13 +0100 Subject: [PATCH 10/13] Rest of the comments --- src/uu/dircolors/src/dircolors.rs | 158 +++++++++--------------------- tests/by-util/test_dircolors.rs | 2 + 2 files changed, 48 insertions(+), 112 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index cf8ed62922..41e640b2a5 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -7,9 +7,8 @@ use std::borrow::Borrow; use std::env; -use std::fmt::Write; use std::fs::File; -use std::io::IsTerminal; +//use std::io::IsTerminal; use std::io::{BufRead, BufReader}; use std::path::Path; @@ -99,16 +98,20 @@ fn generate_ls_colors(fmt: &OutputFmt, sep: &str) -> String { let mut display_parts = vec![]; let type_output = generate_type_output(fmt); display_parts.push(type_output); - for &(extension, code) in FILE_COLORS.iter() { - display_parts.push(format!("\x1b[{}m*{}\t{}\x1b[0m", code, extension, code)); + 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.iter() { - let formatted_extension = format!("*{}", extension); + 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); @@ -193,6 +196,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let result; if files.is_empty() { + 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 @@ -203,6 +209,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { 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, @@ -474,117 +481,44 @@ fn escape(s: &str) -> String { pub fn generate_dircolors_config() -> String { let mut config = String::new(); - // Adding the complete header comments as in the original file - writeln!( - config, - "# Configuration file for dircolors, a utility to help you set the" - ) - .unwrap(); - writeln!( - config, - "# LS_COLORS environment variable used by GNU ls with the --color option." - ) - .unwrap(); - writeln!( - config, - "# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the" - ) - .unwrap(); - writeln!( - config, - "# slackware version of dircolors) are recognized but ignored." - ) - .unwrap(); - writeln!( - config, - "# Global config options can be specified before TERM or COLORTERM entries" - ) - .unwrap(); - writeln!( - config, - "# Below are TERM or COLORTERM entries, which can be glob patterns, which" - ) - .unwrap(); - writeln!( - config, - "# restrict following config to systems with matching environment variables." - ) - .unwrap(); - writeln!(config, "COLORTERM ?*").unwrap(); - for term in TERMS.iter() { - writeln!(config, "TERM {}", term).unwrap(); + config.push_str("# Configuration file for dircolors, a utility to help you set the\n"); + config.push_str("# LS_COLORS environment variable used by GNU ls with the --color option.\n"); + config.push_str("# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the\n"); + config.push_str("# slackware version of dircolors) are recognized but ignored.\n"); + config.push_str("# Global config options can be specified before TERM or COLORTERM entries\n"); + config.push_str("# Below are TERM or COLORTERM entries, which can be glob patterns, which\n"); + config + .push_str("# 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)); } - // Adding file types and their color codes with header - writeln!( - config, - "# Below are the color init strings for the basic file types." - ) - .unwrap(); - writeln!( - config, - "# One can use codes for 256 or more colors supported by modern terminals." - ) - .unwrap(); - writeln!( - config, - "# The default color codes use the capabilities of an 8 color terminal" - ) - .unwrap(); - writeln!( - config, - "# with some additional attributes as per the following codes:" - ) - .unwrap(); - writeln!(config, "# Attribute codes:").unwrap(); - writeln!( - config, - "# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed" - ) - .unwrap(); - writeln!(config, "# Text color codes:").unwrap(); - writeln!( - config, - "# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white" - ) - .unwrap(); - writeln!(config, "# Background color codes:").unwrap(); - writeln!( - config, - "# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white" - ) - .unwrap(); - writeln!(config, "#NORMAL 00 # no color code at all").unwrap(); - writeln!(config, "#FILE 00 # regular file: use no color at all").unwrap(); - - for (name, _, code) in FILE_TYPES.iter() { - writeln!(config, "{} {}", name, code).unwrap(); + config.push_str("# Below are the color init strings for the basic file types.\n"); + config.push_str("# One can use codes for 256 or more colors supported by modern terminals.\n"); + config.push_str("# The default color codes use the capabilities of an 8 color terminal\n"); + config.push_str("# with some additional attributes as per the following codes:\n"); + config.push_str("# Attribute codes:\n"); + config.push_str("# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed\n"); + config.push_str("# Text color codes:\n"); + config.push_str("# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white\n"); + config.push_str("# Background color codes:\n"); + config.push_str("# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white\n"); + config.push_str("#NORMAL 00 # no color code at all\n"); + config.push_str("#FILE 00 # regular file: use no color at all\n"); + + for (name, _, code) in FILE_TYPES { + config.push_str(&format!("{} {}\n", name, code)); } - writeln!( - config, - "# List any file extensions like '.gz' or '.tar' that you would like ls" - ) - .unwrap(); - writeln!( - config, - "# to color below. Put the extension, a space, and the color init string." - ) - .unwrap(); - - for (ext, color) in FILE_COLORS.iter() { - writeln!(config, "{} {}", ext, color).unwrap(); + 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)); } - writeln!( - config, - "# Subsequent TERM or COLORTERM entries, can be used to add / override" - ) - .unwrap(); - write!( - config, - "# config specific to those matching environment variables." - ) - .unwrap(); + 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 } diff --git a/tests/by-util/test_dircolors.rs b/tests/by-util/test_dircolors.rs index e3752fcde9..4a256352c7 100644 --- a/tests/by-util/test_dircolors.rs +++ b/tests/by-util/test_dircolors.rs @@ -159,6 +159,7 @@ fn test_quoting() { .no_stderr(); } +/* #[test] fn test_print_ls_colors() { new_ucmd!() @@ -168,6 +169,7 @@ fn test_print_ls_colors() { .stdout_is("\x1B[40;33mtw\t40;33\x1B[0m\n") .no_stderr(); } +*/ #[test] fn test_extra_operand() { From 97ec99cf28d7b699e7d89793bad93f7ca0976053 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 6 Dec 2023 21:14:59 +0100 Subject: [PATCH 11/13] use a single push_str Co-authored-by: Terts Diepraam --- src/uu/dircolors/src/dircolors.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 41e640b2a5..91544dc735 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -481,14 +481,17 @@ fn escape(s: &str) -> String { 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"); - config.push_str("# LS_COLORS environment variable used by GNU ls with the --color option.\n"); - config.push_str("# The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the\n"); - config.push_str("# slackware version of dircolors) are recognized but ignored.\n"); - config.push_str("# Global config options can be specified before TERM or COLORTERM entries\n"); - config.push_str("# Below are TERM or COLORTERM entries, which can be glob patterns, which\n"); - config - .push_str("# restrict following config to systems with matching environment variables.\n"); + 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)); From bd667efa7b1daf9a38edc5272c3bdab8e5743f56 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 6 Dec 2023 21:15:43 +0100 Subject: [PATCH 12/13] simplify the declaration Co-authored-by: Terts Diepraam --- src/uu/dircolors/src/dircolors.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index 91544dc735..fa523451b2 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -497,18 +497,22 @@ pub fn generate_dircolors_config() -> String { config.push_str(&format!("TERM {}\n", term)); } - config.push_str("# Below are the color init strings for the basic file types.\n"); - config.push_str("# One can use codes for 256 or more colors supported by modern terminals.\n"); - config.push_str("# The default color codes use the capabilities of an 8 color terminal\n"); - config.push_str("# with some additional attributes as per the following codes:\n"); - config.push_str("# Attribute codes:\n"); - config.push_str("# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed\n"); - config.push_str("# Text color codes:\n"); - config.push_str("# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white\n"); - config.push_str("# Background color codes:\n"); - config.push_str("# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white\n"); - config.push_str("#NORMAL 00 # no color code at all\n"); - config.push_str("#FILE 00 # regular file: use no color at all\n"); + 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)); From f99987bb35aade972e187ad3b7df6b039f5b72c2 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 6 Dec 2023 21:19:59 +0100 Subject: [PATCH 13/13] fix rustfmt --- src/uu/dircolors/src/dircolors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index fa523451b2..ecca9d1603 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -481,7 +481,7 @@ fn escape(s: &str) -> String { pub fn generate_dircolors_config() -> String { let mut config = String::new(); - config.push_str( + 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\