@@ -411,33 +411,35 @@ fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
411411 let next_buffer = & b. content ;
412412
413413 let mut updates = vec ! [ ] ;
414- let mut last_nonblank_column = vec ! [ 0 ; a. area. height as usize ] ;
414+ let mut last_nonblank_columns = vec ! [ 0 ; a. area. height as usize ] ;
415415 for y in 0 ..a. area . height {
416416 let row_start = y as usize * a. area . width as usize ;
417417 let row_end = row_start + a. area . width as usize ;
418418 let row = & next_buffer[ row_start..row_end] ;
419419 let bg = row. last ( ) . map ( |cell| cell. bg ) . unwrap_or ( Color :: Reset ) ;
420420
421- let mut last_nonblank: Option < usize > = None ;
422- let mut col = 0usize ;
423- while col < row. len ( ) {
424- let cell = & row[ col] ;
425- let width = cell. symbol ( ) . width ( ) . max ( 1 ) ;
421+ // Scan the row to find the rightmost column that still matters: any non-space glyph,
422+ // any cell whose bg differs from the row’s trailing bg, or any cell with modifiers.
423+ // Multi-width glyphs extend that region through their full displayed width.
424+ // After that point the rest of the row can be cleared with a single ClearToEnd, a perf win
425+ // versus emitting multiple space Put commands.
426+ let mut last_nonblank_column = 0usize ;
427+ let mut column = 0usize ;
428+ while column < row. len ( ) {
429+ let cell = & row[ column] ;
430+ let width = cell. symbol ( ) . width ( ) ;
426431 if cell. symbol ( ) != " " || cell. bg != bg || cell. modifier != Modifier :: empty ( ) {
427- last_nonblank = Some ( col + width. saturating_sub ( 1 ) ) ;
432+ last_nonblank_column = column + ( width. saturating_sub ( 1 ) ) ;
428433 }
429- col += width;
434+ column += width. max ( 1 ) ; // treat zero-width symbols as width 1
430435 }
431- let x = last_nonblank. unwrap_or ( 0 ) ;
432- last_nonblank_column[ y as usize ] = x as u16 ;
433- if x + 1 < row. len ( ) {
434- let ( x_abs, y_abs) = a. pos_of ( row_start + x + 1 ) ;
435- updates. push ( DrawCommand :: ClearToEnd {
436- x : x_abs,
437- y : y_abs,
438- bg,
439- } ) ;
436+
437+ if last_nonblank_column + 1 < row. len ( ) {
438+ let ( x, y) = a. pos_of ( row_start + last_nonblank_column + 1 ) ;
439+ updates. push ( DrawCommand :: ClearToEnd { x, y, bg } ) ;
440440 }
441+
442+ last_nonblank_columns[ y as usize ] = last_nonblank_column as u16 ;
441443 }
442444
443445 // Cells invalidated by drawing/replacing preceding multi-width characters:
@@ -449,7 +451,7 @@ fn diff_buffers<'a>(a: &'a Buffer, b: &'a Buffer) -> Vec<DrawCommand<'a>> {
449451 if !current. skip && ( current != previous || invalidated > 0 ) && to_skip == 0 {
450452 let ( x, y) = a. pos_of ( i) ;
451453 let row = i / a. area . width as usize ;
452- if x <= last_nonblank_column [ row] {
454+ if x <= last_nonblank_columns [ row] {
453455 updates. push ( DrawCommand :: Put {
454456 x,
455457 y,
0 commit comments