Parcourir la source

feat: fix auto value for colors and icons + documentation

PThorpe92 il y a 2 ans
Parent
commit
7753b24422

+ 2 - 3
README.md

@@ -310,10 +310,9 @@ eza’s options are almost, but not quite, entirely unlike `ls`’s.
 - **-T**, **--tree**: recurse into directories as a tree
 - **-x**, **--across**: sort the grid across, rather than downwards
 - **-F**, **--classify**: display type indicator by file names
-- **--colo[u]r**: when to use terminal colours
+- **--colo[u]r=(when)**: when to use terminal colours (always, auto, never)
 - **--colo[u]r-scale**: highlight levels of file sizes distinctly
-- **--icons**: display icons
-- **--no-icons**: don't display icons (always overrides --icons)
+- **--icons=(when)**: when to display icons (always, auto, never)
 - **--hyperlink**: display entries as hyperlinks
 - **-w**, **--width=(columns)**: set screen width in columns
 

+ 5 - 0
completions/bash/eza

@@ -13,6 +13,11 @@ _eza() {
             return
             ;;
 
+        --icons)
+            mapfile -t COMPREPLY < <(compgen -W 'always automatic auto never' -- "$cur")
+            return
+            ;;
+
         -L|--level)
             mapfile -t COMPREPLY < <(compgen -W '{0..9}' -- "$cur")
             return

+ 6 - 2
completions/fish/eza.fish

@@ -20,8 +20,12 @@ complete -c eza -l color \
 "
 complete -c eza -l color-scale \
     -l colour-scale -d "Highlight levels of file sizes distinctly"
-complete -c eza -l icons -d "Display icons"
-complete -c eza -l no-icons -d "Don't display icons"
+complete -c eza -l icons -d "When to display icons" -x -a "
+  always\t'Always display icons'
+  auto\t'Display icons if standard output is a terminal'
+  automatic\t'Display icons if standard output is a terminal'
+  never\t'Never display icons'
+"
 complete -c eza -l no-quotes -d "Don't quote file names with spaces"
 complete -c eza -l hyperlink -d "Display entries as hyperlinks"
 complete -c eza -l smart-group -d "Only show group if it has a different name from owner"

+ 1 - 2
completions/nush/eza.nu

@@ -13,8 +13,7 @@ export extern "eza" [
     --colour                   # When to use terminal colours
     --color-scale              # Highlight levels of file sizes distinctly
     --colour-scale             # Highlight levels of file sizes distinctly
-    --icons                    # Display icons
-    --no-icons                 # Don't display icons
+    --icons                    # When to display icons
     --no-quotes                # Don't quote file names with spaces
     --hyperlink                # Display entries as hyperlinks
     --group-directories-first  # Sort directories before other files

+ 1 - 2
completions/zsh/_eza

@@ -22,8 +22,7 @@ __eza() {
         {-F,--classify}"[Display type indicator by file names]" \
         --colo{,u}r="[When to use terminal colours]:(when):(always auto automatic never)" \
         --colo{,u}r-scale"[Highlight levels of file sizes distinctly]" \
-        --icons"[Display icons]" \
-        --no-icons"[Hide icons]" \
+        --icons="[When to display icons]:(when):(always auto automatic never)" \
         --no-quotes"[Don't quote filenames with spaces]" \
         --hyperlink"[Display entries as hyperlinks]" \
         --group-directories-first"[Sort directories before other files]" \

+ 5 - 3
man/eza.1.md

@@ -88,11 +88,13 @@ Manually setting this option overrides `NO_COLOR` environment.
 `--color-scale`, `--colour-scale`
 : Colour file sizes on a scale.
 
-`--icons`
+`--icons=WHEN`
 : Display icons next to file names.
 
-`--no-icons`
-: Don't display icons. (Always overrides --icons)
+Valid settings are ‘`always`’, ‘`automatic`’ (‘`auto`’ for short), and ‘`never`’.
+The default value is ‘`automatic`’.
+
+`automatic` or `auto` will display icons only when the standard output is connected to a real terminal. If `eza` is ran while in a `tty`, or the output of `eza` is either redirected to a file or piped into another program, icons will not be used. Setting this option to ‘`always`’ causes `eza` to always display icons, while ‘`never`’ disables the use of icons.
 
 `--no-quotes`
 : Don't quote file names with spaces.

+ 3 - 2
src/options/file_name.rs

@@ -47,7 +47,7 @@ impl ShowIcons {
         }
 
         let mode_opt = matches.get(&flags::ICONS)?;
-        if matches.has(&flags::NO_ICONS)? || (!matches.has(&flags::ICONS)? && mode_opt.is_none()) {
+        if !matches.has(&flags::ICONS)? && mode_opt.is_none() {
             return Ok(Self::Never);
         }
 
@@ -56,7 +56,8 @@ impl ShowIcons {
                 Some("always") => AlwaysOrAuto::Always,
                 Some("auto" | "automatic") => AlwaysOrAuto::Automatic,
                 Some("never") => return Ok(Self::Never),
-                _ => return Err(OptionsError::BadArgument(&flags::COLOR, word.into())),
+                None => AlwaysOrAuto::Automatic,
+                _ => return Err(OptionsError::BadArgument(&flags::ICONS, word.into())),
             },
             None => AlwaysOrAuto::Automatic,
         };

+ 5 - 7
src/options/flags.rs

@@ -16,9 +16,9 @@ pub static DEREF_LINKS: Arg = Arg { short: Some(b'X'), long: "dereference", take
 pub static WIDTH:       Arg = Arg { short: Some(b'w'), long: "width",       takes_value: TakesValue::Necessary(None) };
 pub static NO_QUOTES:Arg = Arg { short: None,          long: "no-quotes",takes_value: TakesValue::Forbidden };
 
-pub static COLOR:  Arg = Arg { short: None, long: "color",  takes_value: TakesValue::Necessary(Some(COLOURS)) };
-pub static COLOUR: Arg = Arg { short: None, long: "colour", takes_value: TakesValue::Necessary(Some(COLOURS)) };
-const COLOURS: &[&str] = &["always", "auto", "never"];
+pub static COLOR:  Arg = Arg { short: None, long: "color",  takes_value: TakesValue::Optional(Some(WHEN)) };
+pub static COLOUR: Arg = Arg { short: None, long: "colour", takes_value: TakesValue::Optional(Some(WHEN)) };
+const WHEN: &[&str] = &["always", "auto", "never"];
 
 pub static COLOR_SCALE:  Arg = Arg { short: None, long: "color-scale",  takes_value: TakesValue::Forbidden };
 pub static COLOUR_SCALE: Arg = Arg { short: None, long: "colour-scale", takes_value: TakesValue::Forbidden };
@@ -45,8 +45,7 @@ pub static BYTES:      Arg = Arg { short: Some(b'B'), long: "bytes",      takes_
 pub static GROUP:      Arg = Arg { short: Some(b'g'), long: "group",      takes_value: TakesValue::Forbidden };
 pub static NUMERIC:    Arg = Arg { short: Some(b'n'), long: "numeric",    takes_value: TakesValue::Forbidden };
 pub static HEADER:     Arg = Arg { short: Some(b'h'), long: "header",     takes_value: TakesValue::Forbidden };
-pub static ICONS:      Arg = Arg { short: None,       long: "icons",      takes_value: TakesValue::Necessary(Some(ICONS_VALUES ))};
-const ICONS_VALUES: Values = &["always", "auto", "never"];
+pub static ICONS:      Arg = Arg { short: None,       long: "icons",      takes_value: TakesValue::Optional(Some(WHEN))};
 pub static INODE:      Arg = Arg { short: Some(b'i'), long: "inode",      takes_value: TakesValue::Forbidden };
 pub static LINKS:      Arg = Arg { short: Some(b'H'), long: "links",      takes_value: TakesValue::Forbidden };
 pub static MODIFIED:   Arg = Arg { short: Some(b'm'), long: "modified",   takes_value: TakesValue::Forbidden };
@@ -67,7 +66,6 @@ pub static NO_PERMISSIONS: Arg = Arg { short: None, long: "no-permissions", take
 pub static NO_FILESIZE: Arg = Arg { short: None, long: "no-filesize", takes_value: TakesValue::Forbidden };
 pub static NO_USER: Arg = Arg { short: None, long: "no-user", takes_value: TakesValue::Forbidden };
 pub static NO_TIME: Arg = Arg { short: None, long: "no-time", takes_value: TakesValue::Forbidden };
-pub static NO_ICONS: Arg = Arg { short: None, long: "no-icons", takes_value: TakesValue::Forbidden };
 
 // optional feature options
 pub static GIT:               Arg = Arg { short: None,       long: "git",                  takes_value: TakesValue::Forbidden };
@@ -89,7 +87,7 @@ pub static ALL_ARGS: Args = Args(&[
 
     &BINARY, &BYTES, &GROUP, &NUMERIC, &HEADER, &ICONS, &INODE, &LINKS, &MODIFIED, &CHANGED,
     &BLOCKSIZE, &TIME, &ACCESSED, &CREATED, &TIME_STYLE, &HYPERLINK, &MOUNTS,
-    &NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME, &NO_ICONS, &SMART_GROUP,
+    &NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME, &SMART_GROUP,
 
     &GIT, &NO_GIT, &GIT_REPOS, &GIT_REPOS_NO_STAT,
     &EXTENDED, &OCTAL, &SECURITY_CONTEXT

+ 2 - 3
src/options/help.rs

@@ -22,8 +22,7 @@ DISPLAY OPTIONS
   -F, --classify     display type indicator by file names
   --colo[u]r=WHEN    when to use terminal colours (always, auto, never)
   --colo[u]r-scale   highlight levels of file sizes distinctly
-  --icons            display icons
-  --no-icons         don't display icons (always overrides --icons)
+  --icons=WHEN       when to display icons (always, auto, never)
   --no-quotes        don't quote file names with spaces
   --hyperlink        display entries as hyperlinks
   -w, --width COLS   set screen width in columns
@@ -152,6 +151,6 @@ mod test {
     fn unhelpful() {
         let args = vec![];
         let opts = Options::parse(args, &None);
-        assert!(!matches!(opts, OptionsResult::Help(_))) // no help when --help isn’t passed
+        assert!(!matches!(opts, OptionsResult::Help(_))); // no help when --help isn’t passed
     }
 }

+ 15 - 3
src/options/parser.rs

@@ -152,7 +152,7 @@ impl Args {
         // Iterate over the inputs with “while let” because we need to advance
         // the iterator manually whenever an argument that takes a value
         // doesn’t have one in its string so it needs the next one.
-        let mut inputs = inputs.into_iter();
+        let mut inputs = inputs.into_iter().peekable();
         while let Some(arg) = inputs.next() {
             let bytes = os_str_to_bytes(arg);
 
@@ -199,8 +199,12 @@ impl Args {
                             }
                         }
                         TakesValue::Optional(_) => {
-                            if let Some(next_arg) = inputs.next() {
-                                result_flags.push((flag, Some(next_arg)));
+                            if let Some(next_arg) = inputs.peek() {
+                                if is_flag(next_arg) {
+                                    result_flags.push((flag, None));
+                                } else {
+                                    result_flags.push((flag, Some(inputs.next().unwrap())));
+                                }
                             } else {
                                 result_flags.push((flag, None));
                             }
@@ -332,6 +336,14 @@ impl Args {
     }
 }
 
+fn is_flag(arg: &OsStr) -> bool {
+    let bytes = os_str_to_bytes(arg);
+    match bytes {
+        b"always" | b"auto" | b"automatic" | b"never" => false,
+        _ => bytes.starts_with(b"-"),
+    }
+}
+
 /// The **matches** are the result of parsing the user’s command-line strings.
 #[derive(PartialEq, Eq, Debug)]
 pub struct Matches<'args> {