55
66import type { Terminal , IDisposable , ITerminalAddon , IDecoration } from '@xterm/xterm' ;
77import type { SearchAddon as ISearchApi , ISearchOptions , ISearchDecorationOptions } from '@xterm/addon-search' ;
8- import { Emitter } from 'vs/base/common/event' ;
8+ import { Emitter , Event } from 'vs/base/common/event' ;
99import { combinedDisposable , Disposable , dispose , MutableDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
1010
1111interface IInternalSearchOptions {
@@ -17,6 +17,11 @@ export interface ISearchPosition {
1717 startRow : number ;
1818}
1919
20+ export interface ISearchResultChangeEvent {
21+ resultIndex : number ;
22+ resultCount : number ;
23+ }
24+
2025export interface ISearchAddonOptions {
2126 highlightLimit : number ;
2227}
@@ -49,11 +54,32 @@ interface IMultiHighlight extends IDisposable {
4954 match : ISearchResult ;
5055}
5156
52- const NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\;:"\',./<>?' ;
53- const LINES_CACHE_TIME_TO_LIVE = 15 * 1000 ; // 15 secs
54- const DEFAULT_HIGHLIGHT_LIMIT = 1000 ;
57+ /**
58+ * Configuration constants for the search addon functionality.
59+ */
60+ const enum Constants {
61+ /**
62+ * Characters that are considered non-word characters for search boundary detection. These
63+ * characters are used to determine word boundaries when performing whole-word searches. Includes
64+ * common punctuation, symbols, and whitespace characters.
65+ */
66+ NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\;:"\',./<>?' ,
67+
68+ /**
69+ * Time-to-live for cached search results in milliseconds. After this duration, cached search
70+ * results will be invalidated to ensure they remain consistent with terminal content changes.
71+ */
72+ LINES_CACHE_TIME_TO_LIVE = 15000 ,
73+
74+ /**
75+ * Default maximum number of search results to highlight simultaneously. This limit prevents
76+ * performance degradation when searching for very common terms that would result in excessive
77+ * highlighting decorations.
78+ */
79+ DEFAULT_HIGHLIGHT_LIMIT = 1000
80+ }
5581
56- export class SearchAddon extends Disposable implements ITerminalAddon , ISearchApi {
82+ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchApi {
5783 private _terminal : Terminal | undefined ;
5884 private _cachedSearchTerm : string | undefined ;
5985 private _highlightedLines : Set < number > = new Set ( ) ;
@@ -72,13 +98,13 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
7298 private _linesCacheTimeoutId = 0 ;
7399 private _linesCacheDisposables = new MutableDisposable ( ) ;
74100
75- private readonly _onDidChangeResults = this . _register ( new Emitter < { resultIndex : number , resultCount : number } > ( ) ) ;
76- public readonly onDidChangeResults = this . _onDidChangeResults . event ;
101+ private readonly _onDidChangeResults = this . _register ( new Emitter < ISearchResultChangeEvent > ( ) ) ;
102+ public get onDidChangeResults ( ) : Event < ISearchResultChangeEvent > { return this . _onDidChangeResults . event ; }
77103
78104 constructor ( options ?: Partial < ISearchAddonOptions > ) {
79105 super ( ) ;
80106
81- this . _highlightLimit = options ?. highlightLimit ?? DEFAULT_HIGHLIGHT_LIMIT ;
107+ this . _highlightLimit = options ?. highlightLimit ?? Constants . DEFAULT_HIGHLIGHT_LIMIT ;
82108 }
83109
84110 public activate ( terminal : Terminal ) : void {
@@ -435,7 +461,7 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
435461 }
436462
437463 window . clearTimeout ( this . _linesCacheTimeoutId ) ;
438- this . _linesCacheTimeoutId = window . setTimeout ( ( ) => this . _destroyLinesCache ( ) , LINES_CACHE_TIME_TO_LIVE ) ;
464+ this . _linesCacheTimeoutId = window . setTimeout ( ( ) => this . _destroyLinesCache ( ) , Constants . LINES_CACHE_TIME_TO_LIVE ) ;
439465 }
440466
441467 private _destroyLinesCache ( ) : void {
@@ -455,8 +481,8 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
455481 * @param term the substring that starts at searchIndex
456482 */
457483 private _isWholeWord ( searchIndex : number , line : string , term : string ) : boolean {
458- return ( ( searchIndex === 0 ) || ( NON_WORD_CHARACTERS . includes ( line [ searchIndex - 1 ] ) ) ) &&
459- ( ( ( searchIndex + term . length ) === line . length ) || ( NON_WORD_CHARACTERS . includes ( line [ searchIndex + term . length ] ) ) ) ;
484+ return ( ( searchIndex === 0 ) || ( Constants . NON_WORD_CHARACTERS . includes ( line [ searchIndex - 1 ] ) ) ) &&
485+ ( ( ( searchIndex + term . length ) === line . length ) || ( Constants . NON_WORD_CHARACTERS . includes ( line [ searchIndex + term . length ] ) ) ) ;
460486 }
461487
462488 /**
0 commit comments