Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: support env EZA_QUOTING_STYLE, replace --no-quotes with --quotes=always,auto,never #587

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion completions/bash/eza
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,18 @@ _eza() {
mapfile -t COMPREPLY < <(compgen -W 'on follow off --' -- "$cur")
return
;;
--quotes)
mapfile -t COMPREPLY < <(compgen -W 'always auto automatic never --' -- "$cur")
return
;;
esac

case "$cur" in
# _parse_help doesn’t pick up short options when they are on the same line than long options
--*)
# colo[u]r isn’t parsed correctly so we filter these options out and add them by hand
parse_help=$(eza --help | grep -oE ' (--[[:alnum:]@-]+)' | tr -d ' ' | grep -v '\--colo')
completions=$(echo '--color --colour --color-scale --colour-scale --color-scale-mode --colour-scale-mode' "$parse_help")
completions=$(echo '--color --colour --color-scale --colour-scale --color-scale-mode --colour-scale-mode --quotes' "$parse_help")
mapfile -t COMPREPLY < <(compgen -W "$completions" -- "$cur")
;;

Expand Down
7 changes: 6 additions & 1 deletion completions/fish/eza.fish
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ complete -c eza -l icons -d "When to display icons" -x -a "
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 quotes -d "When to quote filenames" -x -a "
always\t'Always quote filenames, even filenames with no spaces/special characters'
auto\t'Quote filenames if they contain spaces or special characters'
automatic\t'Quote filenames if they contain spaces or special characters'
never\t'Never quote filenames'
"
complete -c eza -l hyperlink -d "Display entries as hyperlinks"
complete -c eza -l follow-symlinks -d "Drill down into symbolic links that point to directories"
complete -c eza -l absolute -d "Display entries with their absolute path" -x -a "
Expand Down
2 changes: 1 addition & 1 deletion completions/nush/eza.nu
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export extern "eza" [
--color-scale-mode # Use gradient or fixed colors in --color-scale
--colour-scale-mode # Use gradient or fixed colors in --colour-scale
--icons # When to display icons
--no-quotes # Don't quote file names with spaces
--quotes # When to quote filenames (always, auto, automatic, never)
--hyperlink # Display entries as hyperlinks
--absolute # Display entries with their absolute path
--follow-symlinks # Drill down into symbolic links that point to directories
Expand Down
2 changes: 1 addition & 1 deletion completions/zsh/_eza
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ __eza() {
--colo{,u}r-scale"[highlight levels of 'field' distinctly]:(fields):(all age size)" \
--colo{,u}r-scale-mode"[Use gradient or fixed colors in --color-scale]:(mode):(fixed gradient)" \
--icons="[When to display icons]:(when):(always auto automatic never)" \
--no-quotes"[Don't quote filenames with spaces]" \
--quotes="[When to quote filenames]: (when): (always auto automatic never) \
--hyperlink"[Display entries as hyperlinks]" \
--absolute"[Display entries with their absolute path]:(mode):(on follow off)" \
--follow-symlinks"[Drill down into symbolic links that point to directories]" \
Expand Down
18 changes: 16 additions & 2 deletions man/eza.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ 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.
`--quotes=WHEN`
: When to quote file names. Default is `auto` which is only when there are spaces in the name.

Valid settings are `always`, `automatic` (or `auto` for short), or `never`
`always` will quote every file name, `never` will never quote any file name, and `automatic` will only quote file names when there are spaces in the name.

`--hyperlink`
: Display entries as hyperlinks
Expand Down Expand Up @@ -350,6 +353,17 @@ Specifies the separator to use when file names are piped from stdin. Defaults to

Specifies the directory where eza will look for its configuration and theme files. Defaults to `$XDG_CONFIG_HOME/eza` or `$HOME/.config/eza` if `XDG_CONFIG_HOME` is not set.

=======
## `EZA_QUOTING_STYLE`

Options are 'never' | 'always' | 'auto'

'never' is equivalent to the `ls`' `-N` option or `QUOTING_STYLE=literal` option, where file names are never quoted

'auto' is the default, and equivalent to the `ls`' `-Q` option or `QUOTING_STYLE=shell-escape` option, where file names are quoted when they contain spaces.

'always' is equivalent to the `ls` `QUOTING_STYLE=shell-escape-always` option, where all file names are quoted.

EXIT STATUSES
=============

Expand Down
21 changes: 18 additions & 3 deletions src/options/file_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,25 @@ impl ShowIcons {

impl QuoteStyle {
pub fn deduce(matches: &MatchedFlags<'_>) -> Result<Self, OptionsError> {
if matches.has(&flags::NO_QUOTES)? {
Ok(Self::NoQuotes)
let env = std::env::var("EZA_QUOTING_STYLE");
let env = env.unwrap_or_else(|_| "auto".to_string());
let env = match env.to_ascii_lowercase().as_str() {
"always" => Self::Always,
"never" => Self::Never,
_ => Self::Auto,
};
if matches.get(&flags::QUOTES)?.is_none() {
Ok(env)
} else if let Some(word) = matches.get(&flags::QUOTES)? {
match word.to_str() {
Some("always") => Ok(Self::Always),
Some("never") => Ok(Self::Never),
Some("auto" | "automatic") => Ok(Self::Auto),
Some(arg) => Err(OptionsError::BadArgument(&flags::QUOTES, arg.into())),
_ => Err(OptionsError::BadArgument(&flags::QUOTES, "auto".into())),
}
} else {
Ok(Self::QuoteSpaces)
Ok(env)
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions src/options/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ pub static TREE: Arg = Arg { short: Some(b'T'), long: "tree",
pub static CLASSIFY: Arg = Arg { short: Some(b'F'), long: "classify", takes_value: TakesValue::Optional(Some(WHEN), "auto") };
pub static DEREF_LINKS: Arg = Arg { short: Some(b'X'), long: "dereference", takes_value: TakesValue::Forbidden };
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 ABSOLUTE: Arg = Arg { short: None, long: "absolute", takes_value: TakesValue::Optional(Some(ABSOLUTE_MODES), "on") };
pub static FOLLOW_LINKS: Arg = Arg { short: None, long: "follow-symlinks", takes_value: TakesValue::Forbidden };
pub static QUOTES: Arg = Arg { short: None, long: "quotes", takes_value: TakesValue::Necessary(Some(WHEN)) };
const ABSOLUTE_MODES: &[&str] = &["on", "follow", "off"];

pub static COLOR: Arg = Arg { short: None, long: "color", takes_value: TakesValue::Optional(Some(WHEN), "auto") };
pub static COLOUR: Arg = Arg { short: None, long: "colour", takes_value: TakesValue::Optional(Some(WHEN), "auto") };
const WHEN: &[&str] = &["always", "auto", "never"];

pub static COLOR_SCALE: Arg = Arg { short: None, long: "color-scale", takes_value: TakesValue::Optional(Some(SCALES), "all") };
pub static COLOUR_SCALE: Arg = Arg { short: None, long: "colour-scale", takes_value: TakesValue::Optional(Some(SCALES), "all") };
Expand All @@ -52,9 +51,6 @@ pub static ONLY_DIRS: Arg = Arg { short: Some(b'D'), long: "only-dirs", takes_
pub static ONLY_FILES: Arg = Arg { short: Some(b'f'), long: "only-files", takes_value: TakesValue::Forbidden };
pub static NO_SYMLINKS: Arg = Arg { short: None, long: "no-symlinks", takes_value: TakesValue::Forbidden };
pub static SHOW_SYMLINKS: Arg = Arg { short: None, long: "show-symlinks", takes_value: TakesValue::Forbidden };
const SORTS: Values = &[ "name", "Name", "size", "extension",
"Extension", "modified", "changed", "accessed",
"created", "inode", "type", "none" ];

// display options
pub static BINARY: Arg = Arg { short: Some(b'b'), long: "binary", takes_value: TakesValue::Forbidden };
Expand All @@ -76,8 +72,6 @@ pub static TIME_STYLE: Arg = Arg { short: None, long: "time-style", take
pub static HYPERLINK: Arg = Arg { short: None, long: "hyperlink", takes_value: TakesValue::Forbidden };
pub static MOUNTS: Arg = Arg { short: Some(b'M'), long: "mounts", takes_value: TakesValue::Forbidden };
pub static SMART_GROUP: Arg = Arg { short: None, long: "smart-group", takes_value: TakesValue::Forbidden };
const TIMES: Values = &["modified", "changed", "accessed", "created"];
const TIME_STYLES: Values = &["default", "long-iso", "full-iso", "iso", "relative"];

// suppressing columns
pub static NO_PERMISSIONS: Arg = Arg { short: None, long: "no-permissions", takes_value: TakesValue::Forbidden };
Expand All @@ -96,12 +90,17 @@ pub static SECURITY_CONTEXT: Arg = Arg { short: Some(b'Z'), long: "context",
pub static STDIN: Arg = Arg { short: None, long: "stdin", takes_value: TakesValue::Forbidden };
pub static FILE_FLAGS: Arg = Arg { short: Some(b'O'), long: "flags", takes_value: TakesValue::Forbidden };

const TIMES: Values = &["modified", "changed", "accessed", "created"];
const TIME_STYLES: Values = &["default", "long-iso", "full-iso", "iso", "relative"];
const WHEN: Values = &["always", "auto", "automatic", "never"];
const SORTS: Values = &[ "name", "Name", "size", "extension", "Extension", "modified", "changed", "accessed", "created", "inode", "type", "none" ];

pub static ALL_ARGS: Args = Args(&[
&VERSION, &HELP,

&ONE_LINE, &LONG, &GRID, &ACROSS, &RECURSE, &TREE, &CLASSIFY, &DEREF_LINKS, &FOLLOW_LINKS,
&COLOR, &COLOUR, &COLOR_SCALE, &COLOUR_SCALE, &COLOR_SCALE_MODE, &COLOUR_SCALE_MODE,
&WIDTH, &NO_QUOTES, &ABSOLUTE,
&WIDTH, &ABSOLUTE, &QUOTES,

&ALL, &ALMOST_ALL, &LIST_DIRS, &LEVEL, &REVERSE, &SORT, &DIRS_FIRST, &DIRS_LAST,
&IGNORE_GLOB, &GIT_IGNORE, &ONLY_DIRS, &ONLY_FILES,
Expand Down
4 changes: 2 additions & 2 deletions src/options/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ DISPLAY OPTIONS
--colo[u]r=WHEN when to use terminal colours (always, auto, never)
--colo[u]r-scale highlight levels of 'field' distinctly(all, age, size)
--colo[u]r-scale-mode use gradient or fixed colors in --color-scale (fixed, gradient)
--icons=WHEN when to display icons (always, auto, never)
--no-quotes don't quote file names with spaces
--icons=WHEN when to display icons (always, auto(matic), never)
--quotes when to quote file names (always, auto(matic), never)
--hyperlink display entries as hyperlinks
--absolute display entries with their absolute path (on, follow, off)
--follow-symlinks drill down into symbolic links that point to directories
Expand Down
2 changes: 1 addition & 1 deletion src/output/escape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub fn escape(
}
}

if quote_style != QuoteStyle::NoQuotes && needs_quotes {
if quote_style != QuoteStyle::Never && needs_quotes || quote_style == QuoteStyle::Always {
bits.insert(bits_starting_length, quote_bit.clone());
bits.push(quote_bit);
}
Expand Down
12 changes: 6 additions & 6 deletions src/output/file_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ pub enum Absolute {
#[derive(PartialEq, Debug, Copy, Clone)]
pub enum QuoteStyle {
/// Don't ever quote file names.
NoQuotes,

/// Use single quotes for file names that contain spaces and no single quotes
/// Use double quotes for file names that contain single quotes.
QuoteSpaces,
Never,
/// Quote file names that contain spaces (default)
Auto,
/// Always quote file names.
Always,
}

/// A **file name** holds all the information necessary to display the name
Expand Down Expand Up @@ -269,7 +269,7 @@ impl<'a, 'dir, C: Colours> FileName<'a, 'dir, C> {
if !target.name.is_empty() {
let target_options = Options {
classify: Classify::JustFilenames,
quote_style: QuoteStyle::QuoteSpaces,
quote_style: QuoteStyle::Auto,
show_icons: ShowIcons::Never,
embed_hyperlinks: EmbedHyperlinks::Off,
is_a_tty: self.options.is_a_tty,
Expand Down
Loading