fix(tui): wrap syntax spans before first overflowing wide character

This commit is contained in:
Felipe Coury
2026-02-10 21:50:36 -03:00
parent c510eec9f8
commit 46021a3591

View File

@@ -618,9 +618,11 @@ fn wrap_styled_spans(spans: &[RtSpan<'static>], max_cols: usize) -> Vec<Vec<RtSp
for ch in remaining.chars() {
// Tabs have no Unicode width; treat them as TAB_WIDTH columns.
let w = ch.width().unwrap_or(if ch == '\t' { TAB_WIDTH } else { 0 });
if col + chars_col + w > max_cols && byte_end > 0 {
// Adding this character would exceed the line width and we
// already have some content — break here.
if col + chars_col + w > max_cols {
// Adding this character would exceed the line width.
// Break here; if this is the first character in `remaining`
// we will flush/start a new line in the `byte_end == 0`
// branch below before consuming it.
break;
}
byte_end += ch.len_utf8();
@@ -1092,6 +1094,35 @@ mod tests {
);
}
#[test]
fn wrap_styled_spans_wraps_before_first_overflowing_char() {
let spans = vec![RtSpan::raw("abcd\t")];
let result = wrap_styled_spans(&spans, 5);
let line_text: Vec<String> = result
.iter()
.map(|line| {
line.iter()
.map(|span| span.content.as_ref())
.collect::<String>()
})
.collect();
assert_eq!(line_text, vec!["abcd", "\t", ""]);
let line_width = |line: &[RtSpan<'static>]| -> usize {
line.iter()
.flat_map(|span| span.content.chars())
.map(|ch| ch.width().unwrap_or(if ch == '\t' { TAB_WIDTH } else { 0 }))
.sum()
};
for line in &result {
assert!(
line_width(line) <= 5,
"wrapped line exceeded width 5: {line:?}"
);
}
}
#[test]
fn large_update_diff_skips_highlighting() {
// Build a patch large enough to exceed MAX_HIGHLIGHT_LINES (10_000).