@@ -40,7 +40,8 @@ export interface ISearchResult {
4040 col : number ;
4141 row : number ;
4242 size : number ;
43- foundBy ?: string ;
43+ didNotYieldForThisManyRows : number ;
44+ usedForYield : boolean ;
4445}
4546
4647interface IHighlight extends IDisposable {
@@ -299,6 +300,7 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
299300 this . _iterate ( searchIterator , ++ chunkIndex ) ;
300301 }
301302 else if ( iteratorResult . value !== false ) { // search finished without being cancelled
303+
302304 const { direction, chunkSize } = iteratorResult . value ;
303305
304306 const startIndex = direction === 'down' ? this . _matches . length - chunkSize : 0 ;
@@ -326,9 +328,11 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
326328
327329 let searchDirection : ChunkSearchDirection = 'down' ;
328330
329- let downDirectionLastResult = this . _find ( term , rowIndex , 0 , 'down' ) ;
330- let upDirectionLastResult = this . _find ( term , rowIndex - 1 , this . _terminal ! . cols , 'up' ) ;
331+ let downDirectionLastResult = this . _find ( term , rowIndex , 0 , 'down' , 0 ) ;
332+ let upDirectionLastResult = this . _find ( term , rowIndex - 1 , this . _terminal ! . cols , 'up' , 0 ) ;
333+
331334
335+ let yieldForReachingMaxRowScans = false ;
332336
333337 searchDirection = downDirectionLastResult !== undefined ? 'down' : 'up' ;
334338
@@ -340,28 +344,48 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
340344 return false ;
341345 }
342346
343- if ( downDirectionLastResult !== undefined && searchDirection === 'down' ) {
347+ if ( downDirectionLastResult !== undefined && searchDirection === 'down' ) {
344348
345- currentChunkMatches . push ( downDirectionLastResult ) ;
349+ // we need two variable to check for yield on exceeding max row scans
350+ // didNotYieldForThisManyRows for the current exection
351+ // and usedForYield for the next time we are given execution
352+ if ( downDirectionLastResult . didNotYieldForThisManyRows < this . _chunkSize ) {
353+ if ( downDirectionLastResult . usedForYield === false ) {
354+ currentChunkMatches . push ( downDirectionLastResult ) ;
355+ }
346356
347- downDirectionLastResult = this . _find (
348- term ,
349- // using previous term length will cause problems with regex
350- downDirectionLastResult . row ,
351- downDirectionLastResult . col + 1 ,
352- 'down'
353- ) ;
357+ downDirectionLastResult = this . _find (
358+ term ,
359+ downDirectionLastResult . row ,
360+ downDirectionLastResult . col + 1 ,
361+ 'down' ,
362+ downDirectionLastResult . didNotYieldForThisManyRows
363+ ) ;
364+
365+ } else {
366+ yieldForReachingMaxRowScans = true ;
367+ downDirectionLastResult . didNotYieldForThisManyRows = 0 ;
368+ }
354369
355370 } else if ( upDirectionLastResult !== undefined && searchDirection === 'up' ) {
356371
357- currentChunkMatches . push ( upDirectionLastResult ) ;
372+ if ( upDirectionLastResult . didNotYieldForThisManyRows < this . _chunkSize ) {
373+ if ( upDirectionLastResult . usedForYield === false ) {
374+ currentChunkMatches . push ( upDirectionLastResult ) ;
375+ }
376+
377+ upDirectionLastResult = this . _find (
378+ term ,
379+ upDirectionLastResult . row ,
380+ upDirectionLastResult . col - 1 ,
381+ 'up' ,
382+ upDirectionLastResult . didNotYieldForThisManyRows
383+ ) ;
384+ } else {
385+ yieldForReachingMaxRowScans = true ;
386+ upDirectionLastResult . didNotYieldForThisManyRows = 0 ;
387+ }
358388
359- upDirectionLastResult = this . _find (
360- term ,
361- upDirectionLastResult . row ,
362- upDirectionLastResult . col - 1 ,
363- 'up'
364- ) ;
365389 }
366390
367391 if ( this . _matches . length + currentChunkMatches . length >= this . _highlightLimit ) {
@@ -385,9 +409,11 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
385409 if (
386410 ( currentChunkMatches . length > 0 && currentChunkMatches . length % this . _chunkSize === 0 ) ||
387411 ( downDirectionLastResult === undefined && searchDirection === 'down' ) ||
388- ( upDirectionLastResult === undefined && searchDirection === 'up' )
412+ ( upDirectionLastResult === undefined && searchDirection === 'up' ) ||
413+ yieldForReachingMaxRowScans
389414 )
390415 {
416+ yieldForReachingMaxRowScans = false ;
391417 if ( searchDirection === 'down' ) {
392418 this . _matches . push ( ...currentChunkMatches ) ;
393419
@@ -398,7 +424,9 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
398424 }
399425
400426 const yieldReturn = { direction :searchDirection , chunkSize :currentChunkMatches . length } ;
427+
401428 currentChunkMatches = [ ] ;
429+
402430 yield yieldReturn ;
403431
404432 searchDirection = searchDirection === 'down' ? 'up' :'down' ;
@@ -425,7 +453,7 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
425453 }
426454
427455
428- private _find ( term : string , startRow : number , startCol : number , direction : ChunkSearchDirection ) : ISearchResult | undefined {
456+ private _find ( term : string , startRow : number , startCol : number , direction : ChunkSearchDirection , didNotYieldForThisManyRows : number ) : ISearchResult | undefined {
429457 if ( ! this . _terminal || ! term || term . length === 0 ) {
430458 return undefined ;
431459 }
@@ -440,14 +468,22 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
440468 const resultAtRowAndToTheRightOfColumn = this . _findInLine ( term , { startRow :startRow , startCol : startCol } , false ) ;
441469
442470 let resultAtOtherRowsScanColumnsLeftToRight : ISearchResult | undefined = undefined ;
471+ let numberOfRowsSearched = 0 ;
443472
444473 if ( resultAtRowAndToTheRightOfColumn === undefined ) {
474+
445475 for ( let y = startRow + 1 ; y < this . _terminal . buffer . active . baseY + this . _terminal . rows ; y ++ ) {
446476
447477 resultAtOtherRowsScanColumnsLeftToRight = this . _findInLine ( term , { startRow :y , startCol : 0 } , false ) ;
448478 if ( resultAtOtherRowsScanColumnsLeftToRight ) {
479+ resultAtOtherRowsScanColumnsLeftToRight . didNotYieldForThisManyRows = numberOfRowsSearched + didNotYieldForThisManyRows ;
449480 break ;
450481 }
482+
483+ numberOfRowsSearched ++ ;
484+ if ( numberOfRowsSearched + didNotYieldForThisManyRows >= this . _chunkSize ) {
485+ return { term :'-1' , row : y , col : 0 , size :- 1 , didNotYieldForThisManyRows : this . _chunkSize , usedForYield : true } ;
486+ }
451487 }
452488 }
453489 out = resultAtRowAndToTheRightOfColumn !== undefined ? resultAtRowAndToTheRightOfColumn : resultAtOtherRowsScanColumnsLeftToRight ;
@@ -457,17 +493,24 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
457493 const resultAtRowAndToTheLeftOfColumn = this . _findInLine ( term , { startRow :startRow , startCol : startCol } , true ) ;
458494
459495 let resultAtOtherRowsScanColumnsRightToLeft : ISearchResult | undefined = undefined ;
496+ let numberOfRowsSearched = 0 ;
460497
461498 if ( resultAtRowAndToTheLeftOfColumn === undefined ) {
499+
462500 const startFrom = this . _searchOptions ?. regex === true ? startRow : startRow - 1 ;
463501 for ( let y = startFrom ; y >= 0 ; y -- ) {
464502 for ( let j = this . _terminal ! . cols ; j >= 0 ; j -- ) {
465503 resultAtOtherRowsScanColumnsRightToLeft = this . _findInLine ( term , { startRow : y , startCol : j } , true ) ;
466504 if ( resultAtOtherRowsScanColumnsRightToLeft ) {
505+ resultAtOtherRowsScanColumnsRightToLeft . didNotYieldForThisManyRows = numberOfRowsSearched + didNotYieldForThisManyRows ;
467506 y = - 1 ; // break outer loop
468507 break ;
469508 }
470509 }
510+ numberOfRowsSearched ++ ;
511+ if ( numberOfRowsSearched + didNotYieldForThisManyRows >= this . _chunkSize ) {
512+ return { term :'-1' , row : y , col : this . _terminal . cols , size : - 1 , didNotYieldForThisManyRows : this . _chunkSize , usedForYield : true } ;
513+ }
471514 }
472515 }
473516 out = resultAtRowAndToTheLeftOfColumn !== undefined ? resultAtRowAndToTheLeftOfColumn : resultAtOtherRowsScanColumnsRightToLeft ;
@@ -569,7 +612,9 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
569612 term,
570613 col : startColIndex ,
571614 row : row + startRowOffset ,
572- size
615+ size,
616+ didNotYieldForThisManyRows :0 , // does not matter
617+ usedForYield :false
573618 } ;
574619
575620
0 commit comments