Skip to content

Commit 2640762

Browse files
committed
fix(help): Correctly calculate wrap points with ANSI escape codes
We mixed up whether `i` represented the absolute position or our incremental position. Fixes #6147
1 parent 3a7db00 commit 2640762

File tree

7 files changed

+27
-11
lines changed

7 files changed

+27
-11
lines changed

clap_builder/src/builder/styled_str.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ mod wrap_tests {
240240
let mut actual = StyledStr::new();
241241
actual.push_string(input);
242242
actual.wrap(20);
243-
assert_data_eq!(actual.ansi().to_string(), str!["12345 12345 12345 12345"]);
243+
assert_data_eq!(actual.ansi().to_string(), str![[r#"
244+
12345 12345 12345 
245+
12345
246+
"#]]);
244247
}
245248
}

clap_builder/src/output/textwrap/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ mod test {
9292
// will be empty. This is because the string is split into
9393
// words like [" ", "foobar ", "baz"], which puts "foobar " on
9494
// the second line. We never output trailing whitespace
95-
assert_eq!(wrap(" foobar baz", 6), vec!["", " foobar", " baz"]);
95+
assert_eq!(wrap(" foobar baz", 6), vec![" foobar", " baz"]);
9696
}
9797

9898
#[test]

clap_builder/src/output/textwrap/wrap_algorithms.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ impl<'w> LineWrapper<'w> {
2222
}
2323

2424
pub(crate) fn wrap(&mut self, mut words: Vec<&'w str>) -> Vec<&'w str> {
25+
let mut first_word = false;
2526
if self.indentation.is_none() {
27+
first_word = true;
2628
if let Some(word) = words.first() {
2729
if word.trim().is_empty() {
2830
self.indentation = Some(*word);
@@ -38,7 +40,10 @@ impl<'w> LineWrapper<'w> {
3840
let trimmed = word.trim_end();
3941
let word_width = display_width(trimmed);
4042
let trimmed_delta = word.len() - trimmed.len();
41-
if i != 0 && self.hard_width < self.line_width + word_width {
43+
if first_word && 0 < word_width {
44+
// Never try to wrap the first word
45+
first_word = false;
46+
} else if self.hard_width < self.line_width + word_width {
4247
if 0 < i {
4348
let prev = i - 1;
4449
let trimmed = words[prev].trim_end();

tests/ui/arg_required_else_help_stderr.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ Commands:
99
more
1010
test Subcommand with one visible alias [aliases: do-stuff]
1111
test_2 several visible aliases [aliases: do-other-stuff, tests]
12-
test_3, --test several visible long flag aliases [aliases: --testing, --testall, --test_all]
12+
test_3, --test several visible long flag aliases [aliases: --testing, --testall,
13+
--test_all]
1314
test_4, -t several visible short flag aliases [aliases: -q, -w]
14-
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k]
15+
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k
16+
]
1517
help Print this message or the help of the given subcommand(s)
1618
1719
Arguments:

tests/ui/h_flag_stdout.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ Commands:
88
more
99
test Subcommand with one visible alias [aliases: do-stuff]
1010
test_2 several visible aliases [aliases: do-other-stuff, tests]
11-
test_3, --test several visible long flag aliases [aliases: --testing, --testall, --test_all]
11+
test_3, --test several visible long flag aliases [aliases: --testing, --testall,
12+
--test_all]
1213
test_4, -t several visible short flag aliases [aliases: -q, -w]
13-
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k]
14+
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k
15+
]
1416
help Print this message or the help of the given subcommand(s)
1517
1618
Arguments:

tests/ui/help_cmd_stdout.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ Commands:
88
more
99
test Subcommand with one visible alias [aliases: do-stuff]
1010
test_2 several visible aliases [aliases: do-other-stuff, tests]
11-
test_3, --test several visible long flag aliases [aliases: --testing, --testall, --test_all]
11+
test_3, --test several visible long flag aliases [aliases: --testing, --testall,
12+
--test_all]
1213
test_4, -t several visible short flag aliases [aliases: -q, -w]
13-
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k]
14+
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k
15+
]
1416
help Print this message or the help of the given subcommand(s)
1517
1618
Arguments:

tests/ui/help_flag_stdout.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ Commands:
88
more
99
test Subcommand with one visible alias [aliases: do-stuff]
1010
test_2 several visible aliases [aliases: do-other-stuff, tests]
11-
test_3, --test several visible long flag aliases [aliases: --testing, --testall, --test_all]
11+
test_3, --test several visible long flag aliases [aliases: --testing, --testall,
12+
--test_all]
1213
test_4, -t several visible short flag aliases [aliases: -q, -w]
13-
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k]
14+
test_5, -e, --test-hdr all kinds of visible aliases [aliases: -r, -y, --thetests, --t4k, tests_4k
15+
]
1416
help Print this message or the help of the given subcommand(s)
1517
1618
Arguments:

0 commit comments

Comments
 (0)