ls: Handle the use of QUOTING_STYLE variable

This commit is contained in:
Dorian Péron 2024-01-03 18:37:51 +01:00
parent 78405e6a30
commit e30f191579

View file

@ -621,7 +621,52 @@ fn extract_hyperlink(options: &clap::ArgMatches) -> bool {
} }
} }
/// Match the argument given to --quoting-style or the QUOTING_STYLE env variable.
///
/// # Arguments
///
/// * `style`: the actual argument string
/// * `show_control` - A boolean value representing whether or not to show control characters.
///
/// # Returns
///
/// * An option with None if the style string is invalid, or a `QuotingStyle` wrapped in `Some`.
fn match_quoting_style_name(style: &str, show_control: bool) -> Option<QuotingStyle> {
match style {
"literal" => Some(QuotingStyle::Literal { show_control }),
"shell" => Some(QuotingStyle::Shell {
escape: false,
always_quote: false,
show_control,
}),
"shell-always" => Some(QuotingStyle::Shell {
escape: false,
always_quote: true,
show_control,
}),
"shell-escape" => Some(QuotingStyle::Shell {
escape: true,
always_quote: false,
show_control,
}),
"shell-escape-always" => Some(QuotingStyle::Shell {
escape: true,
always_quote: true,
show_control,
}),
"c" => Some(QuotingStyle::C {
quotes: quoting_style::Quotes::Double,
}),
"escape" => Some(QuotingStyle::C {
quotes: quoting_style::Quotes::None,
}),
_ => None,
}
}
/// Extracts the quoting style to use based on the options provided. /// Extracts the quoting style to use based on the options provided.
/// If no options are given, it looks if a default quoting style is provided
/// through the QUOTING_STYLE environment variable.
/// ///
/// # Arguments /// # Arguments
/// ///
@ -632,38 +677,12 @@ fn extract_hyperlink(options: &clap::ArgMatches) -> bool {
/// ///
/// A QuotingStyle variant representing the quoting style to use. /// A QuotingStyle variant representing the quoting style to use.
fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> QuotingStyle { fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> QuotingStyle {
let opt_quoting_style = options.get_one::<String>(options::QUOTING_STYLE).cloned(); let opt_quoting_style = options.get_one::<String>(options::QUOTING_STYLE);
if let Some(style) = opt_quoting_style { if let Some(style) = opt_quoting_style {
match style.as_str() { match match_quoting_style_name(style, show_control) {
"literal" => QuotingStyle::Literal { show_control }, Some(qs) => qs,
"shell" => QuotingStyle::Shell { None => unreachable!("Should have been caught by Clap"),
escape: false,
always_quote: false,
show_control,
},
"shell-always" => QuotingStyle::Shell {
escape: false,
always_quote: true,
show_control,
},
"shell-escape" => QuotingStyle::Shell {
escape: true,
always_quote: false,
show_control,
},
"shell-escape-always" => QuotingStyle::Shell {
escape: true,
always_quote: true,
show_control,
},
"c" => QuotingStyle::C {
quotes: quoting_style::Quotes::Double,
},
"escape" => QuotingStyle::C {
quotes: quoting_style::Quotes::None,
},
_ => unreachable!("Should have been caught by Clap"),
} }
} else if options.get_flag(options::quoting::LITERAL) { } else if options.get_flag(options::quoting::LITERAL) {
QuotingStyle::Literal { show_control } QuotingStyle::Literal { show_control }
@ -675,16 +694,32 @@ fn extract_quoting_style(options: &clap::ArgMatches, show_control: bool) -> Quot
QuotingStyle::C { QuotingStyle::C {
quotes: quoting_style::Quotes::Double, quotes: quoting_style::Quotes::Double,
} }
} else if options.get_flag(options::DIRED) || !std::io::stdout().is_terminal() { } else if options.get_flag(options::DIRED) {
// By default, `ls` uses Literal quoting when
// writing to a non-terminal file descriptor
QuotingStyle::Literal { show_control } QuotingStyle::Literal { show_control }
} else { } else {
// TODO: use environment variable if available // If set, the QUOTING_STYLE environment variable specifies a default style.
QuotingStyle::Shell { if let Ok(style) = std::env::var("QUOTING_STYLE") {
escape: true, match match_quoting_style_name(style.as_str(), show_control) {
always_quote: false, Some(qs) => return qs,
show_control, None => eprintln!(
"{}: Ignoring invalid value of environment variable QUOTING_STYLE: '{}'",
std::env::args().next().unwrap_or("ls".to_string()),
style
),
}
}
// By default, `ls` uses Literal quoting when
// writing to a non-terminal file descriptor
if !std::io::stdout().is_terminal() {
QuotingStyle::Literal { show_control }
} else {
// TODO: use environment variable if available
QuotingStyle::Shell {
escape: true,
always_quote: false,
show_control,
}
} }
} }
} }