@@ -377,6 +377,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
377377 let line : IBufferLine ;
378378 let joinedRanges : [ number , number ] [ ] ;
379379 let isJoined : boolean ;
380+ let skipJoinedCheckUntilX : number = 0 ;
381+ let isValidJoinRange : boolean = true ;
380382 let lastCharX : number ;
381383 let range : [ number , number ] ;
382384 let chars : string ;
@@ -405,6 +407,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
405407 row = y + terminal . buffer . ydisp ;
406408 line = terminal . buffer . lines . get ( row ) ! ;
407409 this . _model . lineLengths [ y ] = 0 ;
410+ skipJoinedCheckUntilX = 0 ;
408411 joinedRanges = this . _characterJoinerService . getJoinedCharacters ( row ) ;
409412 for ( x = 0 ; x < terminal . cols ; x ++ ) {
410413 lastBg = this . _cellColorResolver . result . bg ;
@@ -416,17 +419,28 @@ export class WebglRenderer extends Disposable implements IRenderer {
416419
417420 // If true, indicates that the current character(s) to draw were joined.
418421 isJoined = false ;
422+
423+ // Indicates whether this cell is part of a joined range that should be ignored as it cannot
424+ // be rendered entirely, like the selection state differs across the range.
425+ isValidJoinRange = ( x >= skipJoinedCheckUntilX ) ;
426+
419427 lastCharX = x ;
420428
421429 // Process any joined character ranges as needed. Because of how the
422430 // ranges are produced, we know that they are valid for the characters
423431 // and attributes of our input.
424- if ( joinedRanges . length > 0 && x === joinedRanges [ 0 ] [ 0 ] ) {
432+ if ( joinedRanges . length > 0 && x === joinedRanges [ 0 ] [ 0 ] && isValidJoinRange ) {
425433 range = joinedRanges . shift ( ) ! ;
426434
427435 // If the ligature's selection state is not consistent, don't join it. This helps the
428436 // selection render correctly regardless whether they should be joined.
429- if ( this . _model . selection . isCellSelected ( this . _terminal , range [ 0 ] , row ) === this . _model . selection . isCellSelected ( this . _terminal , range [ 1 ] , row ) ) {
437+ const firstSelectionState = this . _model . selection . isCellSelected ( this . _terminal , range [ 0 ] , row ) ;
438+ for ( i = range [ 0 ] + 1 ; i < range [ 1 ] ; i ++ ) {
439+ isValidJoinRange &&= ( firstSelectionState === this . _model . selection . isCellSelected ( this . _terminal , i , row ) ) ;
440+ }
441+ if ( ! isValidJoinRange ) {
442+ skipJoinedCheckUntilX = range [ 1 ] ;
443+ } else {
430444 isJoined = true ;
431445
432446 // We already know the exact start and end column of the joined range,
0 commit comments