Skip to content
Open
Changes from all commits
Commits
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
38 changes: 31 additions & 7 deletions codex-rs/tui/src/custom_terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,14 +418,19 @@ fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
let row = &next_buffer[row_start..row_end];
let bg = row.last().map(|cell| cell.bg).unwrap_or(Color::Reset);

let x = row
.iter()
.rposition(|cell| {
cell.symbol() != " " || cell.bg != bg || cell.modifier != Modifier::empty()
})
.unwrap_or(0);
let mut last_nonblank: Option<usize> = None;
let mut col = 0usize;
while col < row.len() {
let cell = &row[col];
let width = cell.symbol().width().max(1);
if cell.symbol() != " " || cell.bg != bg || cell.modifier != Modifier::empty() {
last_nonblank = Some(col + width.saturating_sub(1));
}
col += width;
}
let x = last_nonblank.unwrap_or(0);
last_nonblank_column[y as usize] = x as u16;
if x < (a.area.width as usize).saturating_sub(1) {
if x + 1 < row.len() {
let (x_abs, y_abs) = a.pos_of(row_start + x + 1);
updates.push(DrawCommand::ClearToEnd {
x: x_abs,
Expand Down Expand Up @@ -592,6 +597,7 @@ mod tests {
use super::*;
use pretty_assertions::assert_eq;
use ratatui::layout::Rect;
use ratatui::style::Style;

#[test]
fn diff_buffers_does_not_emit_clear_to_end_for_full_width_row() {
Expand Down Expand Up @@ -620,4 +626,22 @@ mod tests {
"expected diff_buffers to update the final cell; commands: {commands:?}",
);
}

#[test]
fn diff_buffers_clear_to_end_starts_after_wide_char() {
let area = Rect::new(0, 0, 10, 1);
let mut previous = Buffer::empty(area);
let mut next = Buffer::empty(area);

previous.set_string(0, 0, "中文", Style::default());
next.set_string(0, 0, "中", Style::default());

let commands = diff_buffers(&previous, &next);
assert!(
commands
.iter()
.any(|command| matches!(command, DrawCommand::ClearToEnd { x: 2, y: 0, .. })),
"expected clear-to-end to start after the remaining wide char; commands: {commands:?}"
);
}
}