diff --git a/src/uu/fmt/src/linebreak.rs b/src/uu/fmt/src/linebreak.rs index 4e6e336084f..3d76bfde6af 100644 --- a/src/uu/fmt/src/linebreak.rs +++ b/src/uu/fmt/src/linebreak.rs @@ -357,8 +357,7 @@ fn find_kp_breakpoints<'a, T: Clone + Iterator>>( if next_active_breaks.is_empty() { // every potential linebreak is too long! choose the linebreak with the least demerits, ld_idx - let new_break = - restart_active_breaks(args, &linebreaks[ld_idx], ld_idx, w, slen, minlength); + let new_break = restart_active_breaks(args, &linebreaks[ld_idx], ld_idx, w); next_active_breaks.push(linebreaks.len()); linebreaks.push(new_break); } @@ -460,23 +459,14 @@ fn restart_active_breaks<'a>( active: &LineBreak<'a>, act_idx: usize, w: &'a WordInfo<'a>, - slen: usize, - min: usize, ) -> LineBreak<'a> { let (break_before, line_length) = if active.fresh { // never break before a word if that word would be the first on a line (false, args.indent_len) } else { - // choose the lesser evil: breaking too early, or breaking too late - let wlen = w.word_nchars + args.compute_width(w, active.length, active.fresh); - let underlen = min as isize - active.length as isize; - let overlen = (wlen + slen + active.length) as isize - args.opts.width as isize; - if overlen > underlen { - // break early, put this word on the next line - (true, args.indent_len + w.word_nchars) - } else { - (false, args.indent_len) - } + // the word does not fit, and WIDTH is a hard maximum (like GNU fmt), + // so break early and put this word on the next line + (true, args.indent_len + w.word_nchars) }; // restart the linebreak. This will be our only active path. diff --git a/tests/by-util/test_fmt.rs b/tests/by-util/test_fmt.rs index d0d341bebe2..bea4aaba61e 100644 --- a/tests/by-util/test_fmt.rs +++ b/tests/by-util/test_fmt.rs @@ -685,3 +685,21 @@ fn test_fmt_anti_prefix_keeps_missing_final_newline() { .stdout_only(expected); } } + +#[test] +fn test_fmt_width_is_a_hard_maximum() { + // when no active break can take the next word, it must move to the next + // line instead of overflowing WIDTH + new_ucmd!() + .args(&["-w", "20"]) + .pipe_in(" at a narrow width x y\n") + .succeeds() + .stdout_only(" at a narrow\n width x y\n"); + new_ucmd!() + .args(&["-w", "20"]) + .pipe_in(" indented text that is long enough to wrap at a narrow width\n") + .succeeds() + .stdout_only( + " indented text\n that is long\n enough to wrap\n at a narrow\n width\n", + ); +}