diff --git a/src/uu/pr/locales/en-US.ftl b/src/uu/pr/locales/en-US.ftl index c7fa178e4bd..3a5642a0dd4 100644 --- a/src/uu/pr/locales/en-US.ftl +++ b/src/uu/pr/locales/en-US.ftl @@ -84,6 +84,7 @@ pr-help-indent = pr-help-join-lines = merge full lines, turns off -W line truncation, no column alignment, --sep-string[=STRING] sets separators +pr-help-expand-tabs = expand input CHARs (TABs) to tab WIDTH (8) pr-help-help = Print help information # Page header text diff --git a/src/uu/pr/locales/fr-FR.ftl b/src/uu/pr/locales/fr-FR.ftl index af596787235..603ff1c9c6d 100644 --- a/src/uu/pr/locales/fr-FR.ftl +++ b/src/uu/pr/locales/fr-FR.ftl @@ -83,6 +83,7 @@ pr-help-indent = pr-help-join-lines = fusionner les lignes complètes, désactive la troncature de ligne -W, aucun alignement de colonne, --sep-string[=CHAÎNE] définit les séparateurs +pr-help-expand-tabs = convertir les CHARs d'entrée (TABs) en largeur de tabulation WIDTH (8) pr-help-help = Afficher les informations d'aide # Texte d'en-tête de page diff --git a/src/uu/pr/src/pr.rs b/src/uu/pr/src/pr.rs index a5a8b7b570d..90985588327 100644 --- a/src/uu/pr/src/pr.rs +++ b/src/uu/pr/src/pr.rs @@ -56,6 +56,7 @@ mod options { pub const MERGE: &str = "merge"; pub const INDENT: &str = "indent"; pub const JOIN_LINES: &str = "join-lines"; + pub const EXPAND_TABS: &str = "expand-tabs"; pub const HELP: &str = "help"; pub const FILES: &str = "files"; } @@ -80,6 +81,8 @@ struct OutputOptions { join_lines: bool, col_sep_for_printing: String, line_width: Option, + #[allow(dead_code)] // TODO: implement tab expansion + expand_tabs: Option<(char, usize)>, } struct FileLine { @@ -276,6 +279,7 @@ pub fn uu_app() -> Command { .arg( Arg::new(options::COLUMN) .long(options::COLUMN) + .visible_alias("columns") .help(translate!("pr-help-column")) .value_name("column"), ) @@ -311,6 +315,14 @@ pub fn uu_app() -> Command { .help(translate!("pr-help-indent")) .value_name("margin"), ) + .arg( + Arg::new(options::EXPAND_TABS) + .short('e') + .long(options::EXPAND_TABS) + .help(translate!("pr-help-expand-tabs")) + .value_name("[CHAR][WIDTH]") + .num_args(0..=1), + ) .arg( Arg::new(options::JOIN_LINES) .short('J') @@ -525,6 +537,24 @@ fn build_options( } }); + // If first char is a digit, entire string is WIDTH (e.g., -e8 -> tab, 8) + // Otherwise first char is CHAR, rest is WIDTH (e.g., -e:4 -> ':', 4) + let expand_tabs = matches + .get_one::(options::EXPAND_TABS) + .map(|s| { + let (c, w) = s.chars().next().map_or((TAB, s.as_str()), |c| { + if c.is_ascii_digit() { + (TAB, s.as_str()) + } else { + (c, &s[1..]) + } + }); + (c, w.parse().unwrap_or(8)) + }) + .or(matches + .contains_id(options::EXPAND_TABS) + .then_some((TAB, 8))); + let double_space = matches.get_flag(options::DOUBLE_SPACE); let content_line_separator = if double_space { @@ -761,6 +791,7 @@ fn build_options( join_lines, col_sep_for_printing, line_width, + expand_tabs, }) } diff --git a/tests/by-util/test_pr.rs b/tests/by-util/test_pr.rs index 19afb57bc45..7bc7966f5e0 100644 --- a/tests/by-util/test_pr.rs +++ b/tests/by-util/test_pr.rs @@ -652,3 +652,20 @@ fn test_omit_pagination_option() { .pipe_in("a\nb\n") .succeeds(); } + +#[test] +fn test_expand_tabs_option() { + // TODO: implement actual tab expansion and verify output matches GNU pr + for arg in [ + "-e", + "-e8", + "-e5", + "-e300", + "-e:8", + "--expand-tabs", + "--expand-tabs=8", + "--expand-tabs=:8", + ] { + new_ucmd!().args(&["-t", arg]).pipe_in("a\tb\n").succeeds(); + } +}