mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
unexpand: implement "tabs" shortcuts
This commit is contained in:
parent
fa51f8b986
commit
edf4fee48f
2 changed files with 88 additions and 4 deletions
|
@ -7,7 +7,7 @@
|
|||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (ToDO) nums aflag uflag scol prevtab amode ctype cwidth nbytes lastcol pctype
|
||||
// spell-checker:ignore (ToDO) nums aflag uflag scol prevtab amode ctype cwidth nbytes lastcol pctype Preprocess
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
@ -97,9 +97,9 @@ struct Options {
|
|||
|
||||
impl Options {
|
||||
fn new(matches: &clap::ArgMatches) -> Result<Self, ParseError> {
|
||||
let tabstops = match matches.value_of(options::TABS) {
|
||||
let tabstops = match matches.values_of(options::TABS) {
|
||||
None => vec![DEFAULT_TABSTOP],
|
||||
Some(s) => tabstops_parse(s)?,
|
||||
Some(s) => tabstops_parse(&s.collect::<Vec<&str>>().join(","))?,
|
||||
};
|
||||
|
||||
let aflag = (matches.is_present(options::ALL) || matches.is_present(options::TABS))
|
||||
|
@ -120,13 +120,49 @@ impl Options {
|
|||
}
|
||||
}
|
||||
|
||||
/// Decide whether the character is either a digit or a comma.
|
||||
fn is_digit_or_comma(c: char) -> bool {
|
||||
c.is_ascii_digit() || c == ','
|
||||
}
|
||||
|
||||
/// Preprocess command line arguments and expand shortcuts. For example, "-7" is expanded to
|
||||
/// "--tabs=7 --first-only" and "-1,3" to "--tabs=1 --tabs=3 --first-only". However, if "-a" or
|
||||
/// "--all" is provided, "--first-only" is omitted.
|
||||
fn expand_shortcuts(args: &[String]) -> Vec<String> {
|
||||
let mut processed_args = Vec::with_capacity(args.len());
|
||||
let mut is_all_arg_provided = false;
|
||||
let mut has_shortcuts = false;
|
||||
|
||||
for arg in args {
|
||||
if arg.starts_with('-') && arg[1..].chars().all(is_digit_or_comma) {
|
||||
arg[1..]
|
||||
.split(',')
|
||||
.filter(|s| !s.is_empty())
|
||||
.for_each(|s| processed_args.push(format!("--tabs={}", s)));
|
||||
has_shortcuts = true;
|
||||
} else {
|
||||
processed_args.push(arg.to_string());
|
||||
|
||||
if arg == "--all" || arg == "-a" {
|
||||
is_all_arg_provided = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if has_shortcuts && !is_all_arg_provided {
|
||||
processed_args.push("--first-only".into());
|
||||
}
|
||||
|
||||
processed_args
|
||||
}
|
||||
|
||||
#[uucore::main]
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let args = args
|
||||
.collect_str(InvalidEncodingHandling::Ignore)
|
||||
.accept_any();
|
||||
|
||||
let matches = uu_app().get_matches_from(args);
|
||||
let matches = uu_app().get_matches_from(expand_shortcuts(&args));
|
||||
|
||||
unexpand(&Options::new(&matches)?).map_err_context(String::new)
|
||||
}
|
||||
|
@ -163,6 +199,7 @@ pub fn uu_app<'a>() -> Command<'a> {
|
|||
.long(options::TABS)
|
||||
.help("use comma separated LIST of tab positions or have tabs N characters apart instead of 8 (enables -a)")
|
||||
.takes_value(true)
|
||||
.multiple_occurrences(true)
|
||||
.value_name("N, LIST")
|
||||
)
|
||||
.arg(
|
||||
|
@ -379,3 +416,15 @@ fn unexpand(options: &Options) -> std::io::Result<()> {
|
|||
}
|
||||
output.flush()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::is_digit_or_comma;
|
||||
|
||||
#[test]
|
||||
fn test_is_digit_or_comma() {
|
||||
assert!(is_digit_or_comma('1'));
|
||||
assert!(is_digit_or_comma(','));
|
||||
assert!(!is_digit_or_comma('a'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,41 @@ fn unexpand_read_from_two_file() {
|
|||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_shortcut() {
|
||||
new_ucmd!()
|
||||
.arg("-3")
|
||||
.pipe_in(" a b")
|
||||
.run()
|
||||
.stdout_is("\ta b");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_shortcut_combined_with_all_arg() {
|
||||
fn run_cmd(all_arg: &str) {
|
||||
new_ucmd!()
|
||||
.args(&[all_arg, "-3"])
|
||||
.pipe_in("a b c")
|
||||
.run()
|
||||
.stdout_is("a\tb\tc");
|
||||
}
|
||||
|
||||
let all_args = vec!["-a", "--all"];
|
||||
|
||||
for arg in all_args {
|
||||
run_cmd(arg);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comma_separated_tabs_shortcut() {
|
||||
new_ucmd!()
|
||||
.args(&["-a", "-3,9"])
|
||||
.pipe_in("a b c")
|
||||
.run()
|
||||
.stdout_is("a\tb\tc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_cannot_be_zero() {
|
||||
new_ucmd!()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue