Skip to content

Commit 474cd3b

Browse files
authored
Merge branch 'main' into rm_compatibility
2 parents 37a462d + 2a314c7 commit 474cd3b

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/uu/fold/src/fold.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,15 @@ fn process_utf8_line<W: Write>(line: &str, ctx: &mut FoldContext<'_, W>) -> URes
434434
let mut iter = line.char_indices().peekable();
435435

436436
while let Some((byte_idx, ch)) = iter.next() {
437+
// Include combining characters with the base character
438+
while let Some(&(_, next_ch)) = iter.peek() {
439+
if unicode_width::UnicodeWidthChar::width(next_ch).unwrap_or(1) == 0 {
440+
iter.next();
441+
} else {
442+
break;
443+
}
444+
}
445+
437446
let next_idx = iter.peek().map(|(idx, _)| *idx).unwrap_or(line_bytes.len());
438447

439448
if ch == '\n' {

tests/by-util/test_fold.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
5+
// spell-checker:ignore fullwidth
6+
57
use uutests::new_ucmd;
68

79
#[test]
@@ -597,3 +599,36 @@ fn test_all_tab_advances_at_non_utf8_character() {
597599
.succeeds()
598600
.stdout_is_fixture_bytes("non_utf8_tab_stops_w16.expected");
599601
}
602+
603+
#[test]
604+
fn test_combining_characters_nfc() {
605+
// e acute NFC form (single character)
606+
let e_acute_nfc = "\u{00E9}"; // é as single character
607+
new_ucmd!()
608+
.arg("-w2")
609+
.pipe_in(format!("{e_acute_nfc}{e_acute_nfc}{e_acute_nfc}"))
610+
.succeeds()
611+
.stdout_is(format!("{e_acute_nfc}{e_acute_nfc}\n{e_acute_nfc}"));
612+
}
613+
614+
#[test]
615+
fn test_combining_characters_nfd() {
616+
// e acute NFD form (base + combining acute)
617+
let e_acute_nfd = "e\u{0301}"; // e + combining acute accent
618+
new_ucmd!()
619+
.arg("-w2")
620+
.pipe_in(format!("{e_acute_nfd}{e_acute_nfd}{e_acute_nfd}"))
621+
.succeeds()
622+
.stdout_is(format!("{e_acute_nfd}{e_acute_nfd}\n{e_acute_nfd}"));
623+
}
624+
625+
#[test]
626+
fn test_fullwidth_characters() {
627+
// e fullwidth (takes 2 columns)
628+
let e_fullwidth = "\u{FF45}"; // e
629+
new_ucmd!()
630+
.arg("-w2")
631+
.pipe_in(format!("{e_fullwidth}{e_fullwidth}"))
632+
.succeeds()
633+
.stdout_is(format!("{e_fullwidth}\n{e_fullwidth}"));
634+
}

0 commit comments

Comments
 (0)