Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
073f7fc
test: add word joiner and cyrillic kha character tests for fmt
mattsu2020 Nov 19, 2025
36a01a1
feat: Enhance `fmt` to handle invalid UTF-8 input by replacing malfor…
mattsu2020 Nov 19, 2025
2c617d4
chore: add FFFD to spell-checker ignore list in fmt test.
mattsu2020 Nov 19, 2025
db77543
refactor(uu/fmt): switch string outputs to byte slices for efficiency
mattsu2020 Nov 19, 2025
4445c5a
refactor(fmt): replace Option::map_or(false, f) with is_some_and(f)
mattsu2020 Nov 19, 2025
c59f1bc
style(fmt): compact whitespace check in WordSplit iterator to single …
mattsu2020 Nov 19, 2025
6a313a4
fix(test_fmt): align invalid UTF-8 handling with GNU-compatible passt…
mattsu2020 Nov 19, 2025
fee09e6
Merge branch 'main' into fmt_compatibility
mattsu2020 Dec 15, 2025
e36cf9d
Merge branch 'main' into fmt_compatibility
mattsu2020 Dec 24, 2025
94efbb4
Merge branch 'main' into fmt_compatibility
mattsu2020 Dec 27, 2025
6ee9241
refactor(parasplit): extract scan_word_end method to eliminate code d…
mattsu2020 Dec 27, 2025
6348929
feat(fmt): add byte_display_width function for UTF-8 display width ca…
mattsu2020 Dec 28, 2025
8ece9f5
Merge branch 'main' into fmt_compatibility
sylvestre Dec 29, 2025
d2fa979
Merge branch 'main' into fmt_compatibility
mattsu2020 Jan 5, 2026
637bf76
Merge branch 'main' into fmt_compatibility
mattsu2020 Jan 5, 2026
2c5b12d
refactor(fmt/parasplit): introduce DecodedCharInfo struct for unified…
mattsu2020 Jan 10, 2026
7077d69
refactor(fmt): enhance utf8_char_width with constants and comments fo…
mattsu2020 Jan 12, 2026
9182df4
style(fmt): remove extra blank lines in parasplit.rs
mattsu2020 Jan 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/uu/fmt/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ fn process_file(
match para_result {
Err(s) => {
ostream
.write_all(s.as_bytes())
.write_all(&s)
.map_err_context(|| translate!("fmt-error-failed-to-write-output"))?;
ostream
.write_all(b"\n")
Expand Down
30 changes: 15 additions & 15 deletions src/uu/fmt/src/linebreak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::parasplit::{ParaWords, Paragraph, WordInfo};
struct BreakArgs<'a> {
opts: &'a FmtOptions,
init_len: usize,
indent_str: &'a str,
indent: &'a [u8],
indent_len: usize,
uniform: bool,
ostream: &'a mut BufWriter<Stdout>,
Expand Down Expand Up @@ -59,27 +59,27 @@ pub fn break_lines(
let p_init_len = winfo.word_nchars
+ if opts.crown || opts.tagged {
// handle "init" portion
ostream.write_all(para.init_str.as_bytes())?;
ostream.write_all(&para.init_str)?;
para.init_len
} else if !para.mail_header {
// for non-(crown, tagged) that's the same as a normal indent
ostream.write_all(p_indent.as_bytes())?;
ostream.write_all(p_indent)?;
p_indent_len
} else {
// except that mail headers get no indent at all
0
};

// write first word after writing init
ostream.write_all(winfo.word.as_bytes())?;
ostream.write_all(winfo.word)?;

// does this paragraph require uniform spacing?
let uniform = para.mail_header || opts.uniform;

let mut break_args = BreakArgs {
opts,
init_len: p_init_len,
indent_str: p_indent,
indent: p_indent,
indent_len: p_indent_len,
uniform,
ostream,
Expand Down Expand Up @@ -121,7 +121,7 @@ fn accum_words_simple<'a>(
);

if l + wlen + slen > args.opts.width {
write_newline(args.indent_str, args.ostream)?;
write_newline(args.indent, args.ostream)?;
write_with_spaces(&winfo.word[winfo.word_start..], 0, args.ostream)?;
Ok((args.indent_len + winfo.word_nchars, winfo.ends_punct))
} else {
Expand All @@ -146,7 +146,7 @@ fn break_knuth_plass<'a, T: Clone + Iterator<Item = &'a WordInfo<'a>>>(
(false, false),
|(mut prev_punct, mut fresh), &(next_break, break_before)| {
if fresh {
write_newline(args.indent_str, args.ostream)?;
write_newline(args.indent, args.ostream)?;
}
// at each breakpoint, keep emitting words until we find the word matching this breakpoint
for winfo in &mut iter {
Expand All @@ -167,7 +167,7 @@ fn break_knuth_plass<'a, T: Clone + Iterator<Item = &'a WordInfo<'a>>>(
if std::ptr::eq(winfo, next_break) {
// OK, we found the matching word
if break_before {
write_newline(args.indent_str, args.ostream)?;
write_newline(args.indent, args.ostream)?;
write_with_spaces(&winfo.word[winfo.word_start..], 0, args.ostream)?;
} else {
// breaking after this word, so that means "fresh" is true for the next iteration
Expand All @@ -186,7 +186,7 @@ fn break_knuth_plass<'a, T: Clone + Iterator<Item = &'a WordInfo<'a>>>(
// after the last linebreak, write out the rest of the final line.
for winfo in iter {
if fresh {
write_newline(args.indent_str, args.ostream)?;
write_newline(args.indent, args.ostream)?;
}
let (slen, word) = slice_if_fresh(
fresh,
Expand Down Expand Up @@ -474,13 +474,13 @@ fn compute_slen(uniform: bool, newline: bool, start: bool, punct: bool) -> usize
/// Otherwise, compute `slen` and leave whitespace alone.
fn slice_if_fresh(
fresh: bool,
word: &str,
word: &[u8],
start: usize,
uniform: bool,
newline: bool,
sstart: bool,
punct: bool,
) -> (usize, &str) {
) -> (usize, &[u8]) {
if fresh {
(0, &word[start..])
} else {
Expand All @@ -489,14 +489,14 @@ fn slice_if_fresh(
}

/// Write a newline and add the indent.
fn write_newline(indent: &str, ostream: &mut BufWriter<Stdout>) -> std::io::Result<()> {
fn write_newline(indent: &[u8], ostream: &mut BufWriter<Stdout>) -> std::io::Result<()> {
ostream.write_all(b"\n")?;
ostream.write_all(indent.as_bytes())
ostream.write_all(indent)
}

/// Write the word, along with slen spaces.
fn write_with_spaces(
word: &str,
word: &[u8],
slen: usize,
ostream: &mut BufWriter<Stdout>,
) -> std::io::Result<()> {
Expand All @@ -505,5 +505,5 @@ fn write_with_spaces(
} else if slen == 1 {
ostream.write_all(b" ")?;
}
ostream.write_all(word.as_bytes())
ostream.write_all(word)
}
Loading
Loading