Files
orca/config/patches/@xterm__addon-search@0.17.0-beta.300.patch
Neil 8463dcb7b9 fix(terminal): make wrapped-line search rewind iterative and bound its scans (#18402)
Patches @xterm/addon-search so one very long un-newlined line no longer overflows the stack, freezes the renderer, or goes unsearched. Submitted upstream as xtermjs/xterm.js#6149 (issue #6148); drop the patch once a release ships it. See the PR for measurements and the differential fuzz.
2026-09-03 17:59:16 -07:00

276 lines
377 KiB
Diff

diff --git a/lib/addon-search.js b/lib/addon-search.js
index d939cf1a65f3de449059efbf4fc5c3c3515f533f..8d2b66d265c256d4ebd507624d6a29b8075929ce 100644
--- a/lib/addon-search.js
+++ b/lib/addon-search.js
@@ -1,2 +1,2 @@
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SearchAddon=t():e.SearchAddon=t()}(globalThis,()=>(()=>{"use strict";var e={578(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.IntervalTimer=t.MicrotaskTimer=t.TimeoutTimer=void 0,t.timeout=function(e){return new Promise(t=>setTimeout(t,e))},t.disposableTimeout=function(e,t=0,s){const r=setTimeout(()=>{e(),s&&n.dispose()},t),n=(0,i.toDisposable)(()=>{clearTimeout(r)});return s?.add(n),n};const i=s(426);t.TimeoutTimer=class{constructor(){this._token=-1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,e()},t)}setIfNotSet(e,t){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout(()=>{this._token=-1,e()},t))}},t.MicrotaskTimer=class{constructor(){this._isScheduled=!1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(e){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,e())}))}},t.IntervalTimer=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(e,t,s=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();const i=s.setInterval(()=>{e()},t);this._disposable={dispose:()=>{s.clearInterval(i),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}}},414(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.EventUtils=t.Emitter=void 0;const i=s(426);var r;t.Emitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=(e,t,s)=>{if(this._disposed)return(0,i.toDisposable)(()=>{});const r={fn:e,thisArgs:t};this._listeners=this._listeners.slice(),this._listeners.push(r);const n=(0,i.toDisposable)(()=>{const e=this._listeners.indexOf(r);-1!==e&&(this._listeners=this._listeners.slice(),this._listeners.splice(e,1))});return s&&(Array.isArray(s)?s.push(n):s.add(n)),n}),this._event}fire(e){if(this._disposed||!this._listeners.length)return;if(1===this._listeners.length)return void this._listeners[0].fn.call(this._listeners[0].thisArgs,e);const t=this._listeners;for(let s=0,i=t.length;s<i;++s)t[s].fn.call(t[s].thisArgs,e)}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},function(e){e.forward=function(e,t){return e(e=>t.fire(e))},e.map=function(e,t){return(s,i,r)=>e(e=>s.call(i,t(e)),void 0,r)},e.any=function(...e){return(t,s,r)=>{const n=new i.DisposableStore;for(const i of e)n.add(i(e=>t.call(s,e)));return r&&(Array.isArray(r)?r.push(n):r.add(n)),n}},e.runAndSubscribe=function(e,t,s){return t(s),e(e=>t(e))}}(r||(t.EventUtils=r={}))},426(e,t){function s(e){return{dispose:e}}function i(e){if(!e)return e;if(Array.isArray(e)){for(const t of e)t.dispose();return[]}return e.dispose(),e}Object.defineProperty(t,"__esModule",{value:!0}),t.MutableDisposable=t.Disposable=t.DisposableStore=void 0,t.toDisposable=s,t.dispose=i,t.combinedDisposable=function(...e){return s(()=>i(e))};class r{constructor(){this._disposables=new Set,this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(e){return this._isDisposed?e.dispose():this._disposables.add(e),e}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.clear()}}clear(){for(const e of this._disposables)e.dispose();this._disposables.clear()}}t.DisposableStore=r;class n{constructor(){this._store=new r}dispose(){this._store.dispose()}_register(e){return this._store.add(e)}}t.Disposable=n,n.None=Object.freeze({dispose(){}}),t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}}},864(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationManager=void 0;const i=s(426);class r extends i.Disposable{constructor(e){super(),this._terminal=e,this._highlightDecorations=[],this._highlightedLines=new Set,this._register((0,i.toDisposable)(()=>this.clearHighlightDecorations()))}createHighlightDecorations(e,t){this.clearHighlightDecorations();for(const s of e){const e=this._createResultDecorations(s,t,!1);if(e)for(const t of e)this._storeDecoration(t,s)}}createActiveDecoration(e,t){const s=this._createResultDecorations(e,t,!0);if(s)return{decorations:s,match:e,dispose(){(0,i.dispose)(s)}}}clearHighlightDecorations(){(0,i.dispose)(this._highlightDecorations),this._highlightDecorations=[],this._highlightedLines.clear()}_storeDecoration(e,t){this._highlightedLines.add(e.marker.line),this._highlightDecorations.push({decoration:e,match:t,dispose(){e.dispose()}})}_applyStyles(e,t,s){e.classList.contains("xterm-find-result-decoration")||(e.classList.add("xterm-find-result-decoration"),t&&(e.style.outline=`1px solid ${t}`)),s&&e.classList.add("xterm-find-active-result-decoration")}_createResultDecorations(e,t,s){const r=[];let n=e.col,o=e.size,a=-this._terminal.buffer.active.baseY-this._terminal.buffer.active.cursorY+e.row;for(;o>0;){const e=Math.min(this._terminal.cols-n,o);r.push([a,n,e]),n=0,o-=e,a++}const h=[];for(const e of r){const r=this._terminal.registerMarker(e[0]),n=this._terminal.registerDecoration({marker:r,x:e[1],width:e[2],layer:s?"top":"bottom",backgroundColor:s?t.activeMatchBackground:t.matchBackground,overviewRulerOptions:this._highlightedLines.has(r.line)?void 0:{color:s?t.activeMatchColorOverviewRuler:t.matchOverviewRuler,position:"center"}});if(n){const e=[];e.push(r),e.push(n.onRender(e=>this._applyStyles(e,s?t.activeMatchBorder:t.matchBorder,!1))),e.push(n.onDispose(()=>(0,i.dispose)(e))),h.push(n)}}return 0===h.length?void 0:h}}t.DecorationManager=r},615(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchEngine=void 0,t.SearchEngine=class{constructor(e,t){this._terminal=e,this._lineCache=t}find(e,t,s,i){if(!e||0===e.length)return void this._terminal.clearSelection();if(s>=this._terminal.cols)throw new Error(`Invalid col: ${s} to search in terminal of ${this._terminal.cols} cols`);this._lineCache.initLinesCache();const r={startRow:t,startCol:s};let n=this._findInLine(e,r,i);if(!n)for(let s=t+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(r.startRow=s,r.startCol=0,n=this._findInLine(e,r,i),!n);s++);return n}findNextWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=0,n=0;i&&(s===e?(r=i.end.x,n=i.end.y):(r=i.start.x,n=i.start.y)),this._lineCache.initLinesCache();const o={startRow:n,startCol:r};let a=this._findInLine(e,o,t);if(!a)for(let s=n+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(o.startRow=s,o.startCol=0,a=this._findInLine(e,o,t),!a);s++);if(!a&&0!==n)for(let s=0;s<n&&(o.startRow=s,o.startCol=0,a=this._findInLine(e,o,t),!a);s++);return!a&&i&&(o.startRow=i.start.y,o.startCol=0,a=this._findInLine(e,o,t)),a}findPreviousWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=this._terminal.buffer.active.baseY+this._terminal.rows-1;const n=this._terminal.cols,o=!0;this._lineCache.initLinesCache();const a={startRow:r,startCol:n};let h;if(i&&(a.startRow=r=i.start.y,a.startCol=i.start.x,s!==e&&(h=this._findInLine(e,a,t,!1),h||(a.startRow=r=i.end.y,a.startCol=i.end.x))),h??=this._findInLine(e,a,t,o),!h){a.startCol=Math.max(a.startCol,this._terminal.cols);for(let s=r-1;s>=0&&(a.startRow=s,h=this._findInLine(e,a,t,o),!h);s--);}if(!h&&r!==this._terminal.buffer.active.baseY+this._terminal.rows-1)for(let s=this._terminal.buffer.active.baseY+this._terminal.rows-1;s>=r&&(a.startRow=s,h=this._findInLine(e,a,t,o),!h);s--);return h}_isWholeWord(e,t,s){return(0===e||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e-1]))&&(e+s.length===t.length||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e+s.length]))}_findInLine(e,t,s={},i=!1){const r=t.startRow,n=t.startCol,o=this._terminal.buffer.active.getLine(r);if(o?.isWrapped)return i?void(t.startCol+=this._terminal.cols):(t.startRow--,t.startCol+=this._terminal.cols,this._findInLine(e,t,s));let a=this._lineCache.getLineFromCache(r);a||(a=this._lineCache.translateBufferLineToStringWithWrap(r,!0),this._lineCache.setLineInCache(r,a));const[h,l]=a,c=this._bufferColsToStringOffset(r,n);let d=e,_=h;s.regex||(d=s.caseSensitive?e:e.toLowerCase(),_=s.caseSensitive?h:h.toLowerCase());let u=-1;if(s.regex){const t=RegExp(d,s.caseSensitive?"g":"gi");let r;if(i)for(;r=t.exec(_.slice(0,c));)u=t.lastIndex-r[0].length,e=r[0],t.lastIndex-=e.length-1;else r=t.exec(_.slice(c)),r&&r[0].length>0&&(u=c+(t.lastIndex-r[0].length),e=r[0])}else i?c-d.length>=0&&(u=_.lastIndexOf(d,c-d.length)):u=_.indexOf(d,c);if(u>=0){if(s.wholeWord&&!this._isWholeWord(u,_,e))return;let t=0;for(;t<l.length-1&&u>=l[t+1];)t++;let i=t;for(;i<l.length-1&&u+e.length>=l[i+1];)i++;const n=u-l[t],o=u+e.length-l[i],a=this._stringLengthToBufferSize(r+t,n);return{term:e,col:a,row:r+t,size:this._stringLengthToBufferSize(r+i,o)-a+this._terminal.cols*(i-t)}}}_stringLengthToBufferSize(e,t){const s=this._terminal.buffer.active.getLine(e);if(!s)return 0;for(let e=0;e<t;e++){const i=s.getCell(e);if(!i)break;const r=i.getChars();r.length>1&&(t-=r.length-1);const n=s.getCell(e+1);n&&0===n.getWidth()&&t++}return t}_bufferColsToStringOffset(e,t){let s=e,i=0,r=this._terminal.buffer.active.getLine(s);for(;t>0&&r;){for(let e=0;e<t&&e<this._terminal.cols;e++){const t=r.getCell(e);if(!t)break;t.getWidth()&&(i+=0===t.getCode()?1:t.getChars().length)}if(s++,r=this._terminal.buffer.active.getLine(s),r&&!r.isWrapped)break;t-=this._terminal.cols}return i}}},149(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchLineCache=void 0;const i=s(426),r=s(578);class n extends i.Disposable{constructor(e){super(),this._terminal=e,this._linesCacheTimeout=this._register(new i.MutableDisposable),this._linesCacheDisposables=this._register(new i.MutableDisposable),this._lastAccessTimestamp=0,this._register((0,i.toDisposable)(()=>this._destroyLinesCache()))}initLinesCache(){this._linesCache||(this._linesCache=new Array(this._terminal.buffer.active.length),this._linesCacheDisposables.value=(0,i.combinedDisposable)(this._terminal.onLineFeed(()=>this._destroyLinesCache()),this._terminal.onCursorMove(()=>this._destroyLinesCache()),this._terminal.onResize(()=>this._destroyLinesCache()))),this._lastAccessTimestamp=Date.now(),this._linesCacheTimeout.value||this._scheduleLinesCacheTimeout(15e3)}_destroyLinesCache(){this._linesCache=void 0,this._lastAccessTimestamp=0,this._linesCacheDisposables.clear(),this._linesCacheTimeout.clear()}_scheduleLinesCacheTimeout(e){this._linesCacheTimeout.value=(0,r.disposableTimeout)(()=>{if(!this._linesCache)return;const e=Date.now()-this._lastAccessTimestamp;e>=15e3?this._destroyLinesCache():this._scheduleLinesCacheTimeout(15e3-e)},e)}getLineFromCache(e){return this._linesCache?.[e]}setLineInCache(e,t){this._linesCache&&(this._linesCache[e]=t)}translateBufferLineToStringWithWrap(e,t){const s=[],i=[0];let r=this._terminal.buffer.active.getLine(e);for(;r;){const n=this._terminal.buffer.active.getLine(e+1),o=!!n&&n.isWrapped;let a=r.translateToString(!o&&t);if(o&&n){const e=r.getCell(r.length-1);e&&0===e.getCode()&&1===e.getWidth()&&2===n.getCell(0)?.getWidth()&&(a=a.slice(0,-1))}if(s.push(a),!o)break;i.push(i[i.length-1]+a.length),e++,r=n}return[s.join(""),i]}}t.SearchLineCache=n},438(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultTracker=void 0;const i=s(414),r=s(426);class n extends r.Disposable{constructor(){super(...arguments),this._searchResults=[],this._onDidChangeResults=this._register(new i.Emitter)}get onDidChangeResults(){return this._onDidChangeResults.event}get searchResults(){return this._searchResults}get selectedDecoration(){return this._selectedDecoration}set selectedDecoration(e){this._selectedDecoration=e}updateResults(e,t){this._searchResults=e.slice(0,t)}clearResults(){this._searchResults=[]}clearSelectedDecoration(){this._selectedDecoration&&(this._selectedDecoration.dispose(),this._selectedDecoration=void 0)}findResultIndex(e){for(let t=0;t<this._searchResults.length;t++){const s=this._searchResults[t];if(s.row===e.row&&s.col===e.col&&s.size===e.size)return t}return-1}fireResultsChanged(e){if(!e)return;let t=-1;this._selectedDecoration&&(t=this.findResultIndex(this._selectedDecoration.match)),this._onDidChangeResults.fire({resultIndex:t,resultCount:this._searchResults.length})}reset(){this.clearSelectedDecoration(),this.clearResults()}}t.SearchResultTracker=n},772(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchState=void 0,t.SearchState=class{get cachedSearchTerm(){return this._cachedSearchTerm}set cachedSearchTerm(e){this._cachedSearchTerm=e}get lastSearchOptions(){return this._lastSearchOptions}set lastSearchOptions(e){this._lastSearchOptions=e}isValidSearchTerm(e){return!!(e&&e.length>0)}didOptionsChange(e){return!this._lastSearchOptions||!!e&&(this._lastSearchOptions.caseSensitive!==e.caseSensitive||this._lastSearchOptions.regex!==e.regex||this._lastSearchOptions.wholeWord!==e.wholeWord)}shouldUpdateHighlighting(e,t){return!!t?.decorations&&(void 0===this._cachedSearchTerm||e!==this._cachedSearchTerm||this.didOptionsChange(t))}clearCachedTerm(){this._cachedSearchTerm=void 0}reset(){this._cachedSearchTerm=void 0,this._lastSearchOptions=void 0}}}},t={};function s(i){var r=t[i];if(void 0!==r)return r.exports;var n=t[i]={exports:{}};return e[i](n,n.exports,s),n.exports}var i={};return(()=>{var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.SearchAddon=void 0;const t=s(414),r=s(426),n=s(578),o=s(149),a=s(772),h=s(615),l=s(864),c=s(438);class d extends r.Disposable{get onDidChangeResults(){return this._resultTracker.onDidChangeResults}constructor(e){super(),this._highlightTimeout=this._register(new r.MutableDisposable),this._lineCache=this._register(new r.MutableDisposable),this._state=new a.SearchState,this._resultTracker=this._register(new c.SearchResultTracker),this._onAfterSearch=this._register(new t.Emitter),this.onAfterSearch=this._onAfterSearch.event,this._onBeforeSearch=this._register(new t.Emitter),this.onBeforeSearch=this._onBeforeSearch.event,this._highlightLimit=e?.highlightLimit??1e3}activate(e){this._terminal=e,this._lineCache.value=new o.SearchLineCache(e),this._engine=new h.SearchEngine(e,this._lineCache.value),this._decorationManager=new l.DecorationManager(e),this._register(this._terminal.onWriteParsed(()=>this._updateMatches())),this._register(this._terminal.onResize(()=>this._updateMatches())),this._register((0,r.toDisposable)(()=>this.clearDecorations()))}_updateMatches(){this._highlightTimeout.clear(),this._state.cachedSearchTerm&&this._state.lastSearchOptions?.decorations&&(this._highlightTimeout.value=(0,n.disposableTimeout)(()=>{const e=this._state.cachedSearchTerm;this._state.clearCachedTerm(),this.findPrevious(e,{...this._state.lastSearchOptions,incremental:!0},{noScroll:!0})},200))}clearDecorations(e){this._resultTracker.clearSelectedDecoration(),this._decorationManager?.clearHighlightDecorations(),this._resultTracker.clearResults(),e||this._state.clearCachedTerm()}clearActiveDecoration(){this._resultTracker.clearSelectedDecoration()}findNext(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findNextAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),i}_highlightAllMatches(e,t){if(!this._terminal||!this._engine||!this._decorationManager)throw new Error("Cannot use addon until it has been loaded");if(!this._state.isValidSearchTerm(e))return void this.clearDecorations();this.clearDecorations(!0);const s=[];let i,r=this._engine.find(e,0,0,t);for(;r&&(i?.row!==r.row||i?.col!==r.col)&&!(s.length>=this._highlightLimit);){i=r,s.push(i);const n=this._terminal.cols;let o=i.col+i.size,a=i.row;o>=n&&(a+=Math.floor(o/n),o%=n),r=this._engine.find(e,a,o,t)}this._resultTracker.updateResults(s,this._highlightLimit),t.decorations&&this._decorationManager.createHighlightDecorations(s,t.decorations)}_findNextAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findNextWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}findPrevious(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findPreviousAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),i}_fireResults(e){this._resultTracker.fireResultsChanged(!!e?.decorations)}_findPreviousAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findPreviousWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}_selectResult(e,t,s){if(!this._terminal||!this._decorationManager)return!1;if(this._resultTracker.clearSelectedDecoration(),!e)return this._terminal.clearSelection(),!1;if(this._terminal.select(e.col,e.row,e.size),t){const s=this._decorationManager.createActiveDecoration(e,t);s&&(this._resultTracker.selectedDecoration=s)}if(!s&&(e.row>=this._terminal.buffer.active.viewportY+this._terminal.rows||e.row<this._terminal.buffer.active.viewportY)){let t=e.row-this._terminal.buffer.active.viewportY;t-=Math.floor(this._terminal.rows/2),this._terminal.scrollLines(t)}return!0}}e.SearchAddon=d})(),i})());
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SearchAddon=t():e.SearchAddon=t()}(globalThis,()=>(()=>{"use strict";var e={578(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.IntervalTimer=t.MicrotaskTimer=t.TimeoutTimer=void 0,t.timeout=function(e){return new Promise(t=>setTimeout(t,e))},t.disposableTimeout=function(e,t=0,s){const r=setTimeout(()=>{e(),s&&o.dispose()},t),o=(0,i.toDisposable)(()=>{clearTimeout(r)});return s?.add(o),o};const i=s(426);t.TimeoutTimer=class{constructor(){this._token=-1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){-1!==this._token&&(clearTimeout(this._token),this._token=-1)}cancelAndSet(e,t){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed TimeoutTimer");this.cancel(),this._token=setTimeout(()=>{this._token=-1,e()},t)}setIfNotSet(e,t){if(this._isDisposed)throw new Error("Calling setIfNotSet on a disposed TimeoutTimer");-1===this._token&&(this._token=setTimeout(()=>{this._token=-1,e()},t))}},t.MicrotaskTimer=class{constructor(){this._isScheduled=!1,this._isDisposed=!1}dispose(){this.cancel(),this._isDisposed=!0}cancel(){this._isScheduled=!1}set(e){if(this._isDisposed)throw new Error("Calling set on a disposed MicrotaskTimer");this._isScheduled||(this._isScheduled=!0,queueMicrotask(()=>{this._isScheduled&&(this._isScheduled=!1,e())}))}},t.IntervalTimer=class{constructor(){this._isDisposed=!1}cancel(){this._disposable?.dispose(),this._disposable=void 0}cancelAndSet(e,t,s=globalThis){if(this._isDisposed)throw new Error("Calling cancelAndSet on a disposed IntervalTimer");this.cancel();const i=s.setInterval(()=>{e()},t);this._disposable={dispose:()=>{s.clearInterval(i),this._disposable=void 0}}}dispose(){this.cancel(),this._isDisposed=!0}}},414(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.EventUtils=t.Emitter=void 0;const i=s(426);var r;t.Emitter=class{constructor(){this._listeners=[],this._disposed=!1}get event(){return this._event||(this._event=(e,t,s)=>{if(this._disposed)return(0,i.toDisposable)(()=>{});const r={fn:e,thisArgs:t};this._listeners=this._listeners.slice(),this._listeners.push(r);const o=(0,i.toDisposable)(()=>{const e=this._listeners.indexOf(r);-1!==e&&(this._listeners=this._listeners.slice(),this._listeners.splice(e,1))});return s&&(Array.isArray(s)?s.push(o):s.add(o)),o}),this._event}fire(e){if(this._disposed||!this._listeners.length)return;if(1===this._listeners.length)return void this._listeners[0].fn.call(this._listeners[0].thisArgs,e);const t=this._listeners;for(let s=0,i=t.length;s<i;++s)t[s].fn.call(t[s].thisArgs,e)}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},function(e){e.forward=function(e,t){return e(e=>t.fire(e))},e.map=function(e,t){return(s,i,r)=>e(e=>s.call(i,t(e)),void 0,r)},e.any=function(...e){return(t,s,r)=>{const o=new i.DisposableStore;for(const i of e)o.add(i(e=>t.call(s,e)));return r&&(Array.isArray(r)?r.push(o):r.add(o)),o}},e.runAndSubscribe=function(e,t,s){return t(s),e(e=>t(e))}}(r||(t.EventUtils=r={}))},426(e,t){function s(e){return{dispose:e}}function i(e){if(!e)return e;if(Array.isArray(e)){for(const t of e)t.dispose();return[]}return e.dispose(),e}Object.defineProperty(t,"__esModule",{value:!0}),t.MutableDisposable=t.Disposable=t.DisposableStore=void 0,t.toDisposable=s,t.dispose=i,t.combinedDisposable=function(...e){return s(()=>i(e))};class r{constructor(){this._disposables=new Set,this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(e){return this._isDisposed?e.dispose():this._disposables.add(e),e}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(const e of this._disposables)e.dispose();this._disposables.clear()}}clear(){for(const e of this._disposables)e.dispose();this._disposables.clear()}}t.DisposableStore=r;class o{constructor(){this._store=new r}dispose(){this._store.dispose()}_register(e){return this._store.add(e)}}t.Disposable=o,o.None=Object.freeze({dispose(){}}),t.MutableDisposable=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(e){this._isDisposed||e===this._value||(this._value?.dispose(),this._value=e)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}}},864(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.DecorationManager=void 0;const i=s(426);class r extends i.Disposable{constructor(e){super(),this._terminal=e,this._highlightDecorations=[],this._highlightedLines=new Set,this._register((0,i.toDisposable)(()=>this.clearHighlightDecorations()))}createHighlightDecorations(e,t){this.clearHighlightDecorations();for(const s of e){const e=this._createResultDecorations(s,t,!1);if(e)for(const t of e)this._storeDecoration(t,s)}}createActiveDecoration(e,t){const s=this._createResultDecorations(e,t,!0);if(s)return{decorations:s,match:e,dispose(){(0,i.dispose)(s)}}}clearHighlightDecorations(){(0,i.dispose)(this._highlightDecorations),this._highlightDecorations=[],this._highlightedLines.clear()}_storeDecoration(e,t){this._highlightedLines.add(e.marker.line),this._highlightDecorations.push({decoration:e,match:t,dispose(){e.dispose()}})}_applyStyles(e,t,s){e.classList.contains("xterm-find-result-decoration")||(e.classList.add("xterm-find-result-decoration"),t&&(e.style.outline=`1px solid ${t}`)),s&&e.classList.add("xterm-find-active-result-decoration")}_createResultDecorations(e,t,s){const r=[];let o=e.col,n=e.size,a=-this._terminal.buffer.active.baseY-this._terminal.buffer.active.cursorY+e.row;for(;n>0;){const e=Math.min(this._terminal.cols-o,n);r.push([a,o,e]),o=0,n-=e,a++}const h=[];for(const e of r){const r=this._terminal.registerMarker(e[0]),o=this._terminal.registerDecoration({marker:r,x:e[1],width:e[2],layer:s?"top":"bottom",backgroundColor:s?t.activeMatchBackground:t.matchBackground,overviewRulerOptions:this._highlightedLines.has(r.line)?void 0:{color:s?t.activeMatchColorOverviewRuler:t.matchOverviewRuler,position:"center"}});if(o){const e=[];e.push(r),e.push(o.onRender(e=>this._applyStyles(e,s?t.activeMatchBorder:t.matchBorder,!1))),e.push(o.onDispose(()=>(0,i.dispose)(e))),h.push(o)}}return 0===h.length?void 0:h}}t.DecorationManager=r},615(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchEngine=void 0,t.SearchEngine=class{constructor(e,t){this._terminal=e,this._lineCache=t}find(e,t,s,i){if(!e||0===e.length)return void this._terminal.clearSelection();if(s>=this._terminal.cols)throw new Error(`Invalid col: ${s} to search in terminal of ${this._terminal.cols} cols`);this._lineCache.initLinesCache();const r={startRow:t,startCol:s};let o=this._findInLine(e,r,i);if(!o)for(let s=t+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(this._isRowCoveredByEarlierSearch(s)||(r.startRow=s,r.startCol=0,o=this._findInLine(e,r,i),!o));s++);return o}findNextWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=0,o=0;i&&(s===e?(r=i.end.x,o=i.end.y):(r=i.start.x,o=i.start.y)),this._lineCache.initLinesCache();const n={startRow:o,startCol:r};let a=this._findInLine(e,n,t);if(!a)for(let s=o+1;s<this._terminal.buffer.active.baseY+this._terminal.rows&&(this._isRowCoveredByEarlierSearch(s)||(n.startRow=s,n.startCol=0,a=this._findInLine(e,n,t),!a));s++);if(!a&&0!==o)for(let s=0;s<o&&(s>0&&this._isRowCoveredByEarlierSearch(s)||(n.startRow=s,n.startCol=0,a=this._findInLine(e,n,t),!a));s++);return!a&&i&&(n.startRow=i.start.y,n.startCol=0,a=this._findInLine(e,n,t)),a}findPreviousWithSelection(e,t,s){if(!e||0===e.length)return void this._terminal.clearSelection();const i=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=this._terminal.buffer.active.baseY+this._terminal.rows-1;const o=this._terminal.cols,n=!0;this._lineCache.initLinesCache();const a={startRow:r,startCol:o};let h;if(i&&(a.startRow=r=i.start.y,a.startCol=i.start.x,s!==e&&(h=this._findInLine(e,a,t,!1),h||(a.startRow=r=i.end.y,a.startCol=i.end.x))),h??=this._findInLine(e,a,t,n),!h){a.startCol=Math.max(a.startCol,this._terminal.cols);for(let s=r-1;s>=0&&(a.startRow=s,h=this._findInLine(e,a,t,n),!h);s--);}if(!h&&r!==this._terminal.buffer.active.baseY+this._terminal.rows-1)for(let s=this._terminal.buffer.active.baseY+this._terminal.rows-1;s>=r&&(a.startRow=s,h=this._findInLine(e,a,t,n),!h);s--);return h}_isWholeWord(e,t,s){return(0===e||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e-1]))&&(e+s.length===t.length||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(t[e+s.length]))}_satisfiesWholeWord(e,t,s,i){return!i.wholeWord||this._isWholeWord(e,t,s)}_isRowCoveredByEarlierSearch(e){return!0===this._terminal.buffer.active.getLine(e)?.isWrapped}_findInLine(e,t,s={},i=!1){if(i){if(t.startRow>0&&this._terminal.buffer.active.getLine(t.startRow)?.isWrapped)return void(t.startCol+=this._terminal.cols)}else for(;t.startRow>0&&this._terminal.buffer.active.getLine(t.startRow)?.isWrapped;)t.startRow--,t.startCol+=this._terminal.cols;const r=t.startRow,o=t.startCol;let n=this._lineCache.getLineFromCache(r);n||(n=this._lineCache.translateBufferLineToStringWithWrap(r,!0),this._lineCache.setLineInCache(r,n));const[a,h]=n,l=this._bufferColsToStringOffset(r,o,h);let c=e,d=a;s.regex||(c=s.caseSensitive?e:e.toLowerCase(),d=s.caseSensitive?a:a.toLowerCase());let _=-1;if(s.regex){const t=RegExp(c,s.caseSensitive?"g":"gi");let r;if(i)for(;r=t.exec(d.slice(0,l));){const i=t.lastIndex-r[0].length;r[0].length>0&&this._satisfiesWholeWord(i,d,r[0],s)&&(_=i,e=r[0]),t.lastIndex=i+1}else for(t.lastIndex=l;r=t.exec(d);){const i=t.lastIndex-r[0].length;if(r[0].length>0&&this._satisfiesWholeWord(i,d,r[0],s)){_=i,e=r[0];break}t.lastIndex=i+1}}else if(i){let e=l-c.length>=0?d.lastIndexOf(c,l-c.length):-1;for(;e>=0&&!this._satisfiesWholeWord(e,d,c,s);)e=e>0?d.lastIndexOf(c,e-1):-1;_=e}else{let e=d.indexOf(c,l);for(;e>=0&&!this._satisfiesWholeWord(e,d,c,s);)e=d.indexOf(c,e+1);_=e}if(_>=0){let t=0;for(;t<h.length-1&&_>=h[t+1];)t++;let s=t;for(;s<h.length-1&&_+e.length>=h[s+1];)s++;const i=_-h[t],o=_+e.length-h[s],n=this._stringLengthToBufferSize(r+t,i);return{term:e,col:n,row:r+t,size:this._stringLengthToBufferSize(r+s,o)-n+this._terminal.cols*(s-t)}}}_stringLengthToBufferSize(e,t){const s=this._terminal.buffer.active.getLine(e);if(!s)return 0;for(let e=0;e<t;e++){const i=s.getCell(e);if(!i)break;const r=i.getChars();r.length>1&&(t-=r.length-1);const o=s.getCell(e+1);o&&0===o.getWidth()&&t++}return t}_bufferColsToStringOffset(e,t,s){const i=Math.min(Math.floor(t/this._terminal.cols),s.length-1);let r=s[i];const o=this._terminal.buffer.active.getLine(e+i);if(o){const e=Math.min(t-i*this._terminal.cols,this._terminal.cols);for(let t=0;t<e;t++){const e=o.getCell(t);if(!e)break;e.getWidth()&&(r+=0===e.getCode()?1:e.getChars().length)}}return r}}},149(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchLineCache=void 0;const i=s(426),r=s(578);class o extends i.Disposable{constructor(e){super(),this._terminal=e,this._linesCacheTimeout=this._register(new i.MutableDisposable),this._linesCacheDisposables=this._register(new i.MutableDisposable),this._lastAccessTimestamp=0,this._register((0,i.toDisposable)(()=>this._destroyLinesCache()))}initLinesCache(){this._linesCache||(this._linesCache=new Array(this._terminal.buffer.active.length),this._linesCacheDisposables.value=(0,i.combinedDisposable)(this._terminal.onLineFeed(()=>this._destroyLinesCache()),this._terminal.onCursorMove(()=>this._destroyLinesCache()),this._terminal.onResize(()=>this._destroyLinesCache()))),this._lastAccessTimestamp=Date.now(),this._linesCacheTimeout.value||this._scheduleLinesCacheTimeout(15e3)}_destroyLinesCache(){this._linesCache=void 0,this._lastAccessTimestamp=0,this._linesCacheDisposables.clear(),this._linesCacheTimeout.clear()}_scheduleLinesCacheTimeout(e){this._linesCacheTimeout.value=(0,r.disposableTimeout)(()=>{if(!this._linesCache)return;const e=Date.now()-this._lastAccessTimestamp;e>=15e3?this._destroyLinesCache():this._scheduleLinesCacheTimeout(15e3-e)},e)}getLineFromCache(e){return this._linesCache?.[e]}setLineInCache(e,t){this._linesCache&&(this._linesCache[e]=t)}translateBufferLineToStringWithWrap(e,t){const s=[],i=[0],r=this._terminal.buffer.active.length;let o=this._terminal.buffer.active.getLine(e);for(;o;){const n=e+1<r?this._terminal.buffer.active.getLine(e+1):void 0,a=!!n&&n.isWrapped;let h=o.translateToString(!a&&t);if(a&&n){const e=o.getCell(o.length-1);e&&0===e.getCode()&&1===e.getWidth()&&2===n.getCell(0)?.getWidth()&&(h=h.slice(0,-1))}if(s.push(h),!a)break;i.push(i[i.length-1]+h.length),e++,o=n}return[s.join(""),i]}}t.SearchLineCache=o},438(e,t,s){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchResultTracker=void 0;const i=s(414),r=s(426);class o extends r.Disposable{constructor(){super(...arguments),this._searchResults=[],this._onDidChangeResults=this._register(new i.Emitter)}get onDidChangeResults(){return this._onDidChangeResults.event}get searchResults(){return this._searchResults}get selectedDecoration(){return this._selectedDecoration}set selectedDecoration(e){this._selectedDecoration=e}updateResults(e,t){this._searchResults=e.slice(0,t)}clearResults(){this._searchResults=[]}clearSelectedDecoration(){this._selectedDecoration&&(this._selectedDecoration.dispose(),this._selectedDecoration=void 0)}findResultIndex(e){for(let t=0;t<this._searchResults.length;t++){const s=this._searchResults[t];if(s.row===e.row&&s.col===e.col&&s.size===e.size)return t}return-1}fireResultsChanged(e){if(!e)return;let t=-1;this._selectedDecoration&&(t=this.findResultIndex(this._selectedDecoration.match)),this._onDidChangeResults.fire({resultIndex:t,resultCount:this._searchResults.length})}reset(){this.clearSelectedDecoration(),this.clearResults()}}t.SearchResultTracker=o},772(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.SearchState=void 0,t.SearchState=class{get cachedSearchTerm(){return this._cachedSearchTerm}set cachedSearchTerm(e){this._cachedSearchTerm=e}get lastSearchOptions(){return this._lastSearchOptions}set lastSearchOptions(e){this._lastSearchOptions=e}isValidSearchTerm(e){return!!(e&&e.length>0)}didOptionsChange(e){return!this._lastSearchOptions||!!e&&(this._lastSearchOptions.caseSensitive!==e.caseSensitive||this._lastSearchOptions.regex!==e.regex||this._lastSearchOptions.wholeWord!==e.wholeWord)}shouldUpdateHighlighting(e,t){return!!t?.decorations&&(void 0===this._cachedSearchTerm||e!==this._cachedSearchTerm||this.didOptionsChange(t))}clearCachedTerm(){this._cachedSearchTerm=void 0}reset(){this._cachedSearchTerm=void 0,this._lastSearchOptions=void 0}}}},t={};function s(i){var r=t[i];if(void 0!==r)return r.exports;var o=t[i]={exports:{}};return e[i](o,o.exports,s),o.exports}var i={};return(()=>{var e=i;Object.defineProperty(e,"__esModule",{value:!0}),e.SearchAddon=void 0;const t=s(414),r=s(426),o=s(578),n=s(149),a=s(772),h=s(615),l=s(864),c=s(438);class d extends r.Disposable{get onDidChangeResults(){return this._resultTracker.onDidChangeResults}constructor(e){super(),this._highlightTimeout=this._register(new r.MutableDisposable),this._lineCache=this._register(new r.MutableDisposable),this._state=new a.SearchState,this._resultTracker=this._register(new c.SearchResultTracker),this._onAfterSearch=this._register(new t.Emitter),this.onAfterSearch=this._onAfterSearch.event,this._onBeforeSearch=this._register(new t.Emitter),this.onBeforeSearch=this._onBeforeSearch.event,this._highlightLimit=e?.highlightLimit??1e3}activate(e){this._terminal=e,this._lineCache.value=new n.SearchLineCache(e),this._engine=new h.SearchEngine(e,this._lineCache.value),this._decorationManager=new l.DecorationManager(e),this._register(this._terminal.onWriteParsed(()=>this._updateMatches())),this._register(this._terminal.onResize(()=>this._updateMatches())),this._register((0,r.toDisposable)(()=>this.clearDecorations()))}_updateMatches(){this._highlightTimeout.clear(),this._state.cachedSearchTerm&&this._state.lastSearchOptions?.decorations&&(this._highlightTimeout.value=(0,o.disposableTimeout)(()=>{const e=this._state.cachedSearchTerm;this._state.clearCachedTerm(),this.findPrevious(e,{...this._state.lastSearchOptions,incremental:!0},{noScroll:!0})},200))}clearDecorations(e){this._resultTracker.clearSelectedDecoration(),this._decorationManager?.clearHighlightDecorations(),this._resultTracker.clearResults(),e||this._state.clearCachedTerm()}clearActiveDecoration(){this._resultTracker.clearSelectedDecoration()}findNext(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findNextAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),i}_highlightAllMatches(e,t){if(!this._terminal||!this._engine||!this._decorationManager)throw new Error("Cannot use addon until it has been loaded");if(!this._state.isValidSearchTerm(e))return void this.clearDecorations();this.clearDecorations(!0);const s=[];let i,r=this._engine.find(e,0,0,t);for(;r&&(i?.row!==r.row||i?.col!==r.col)&&!(s.length>=this._highlightLimit);){i=r,s.push(i);const o=this._terminal.cols;let n=i.col+i.size,a=i.row;n>=o&&(a+=Math.floor(n/o),n%=o),r=this._engine.find(e,a,n,t)}this._resultTracker.updateResults(s,this._highlightLimit),t.decorations&&this._decorationManager.createHighlightDecorations(s,t.decorations)}_findNextAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findNextWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}findPrevious(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);const i=this._findPreviousAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),i}_fireResults(e){this._resultTracker.fireResultsChanged(!!e?.decorations)}_findPreviousAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;const i=this._engine.findPreviousWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(i,t?.decorations,s?.noScroll)}_selectResult(e,t,s){if(!this._terminal||!this._decorationManager)return!1;if(this._resultTracker.clearSelectedDecoration(),!e)return this._terminal.clearSelection(),!1;if(this._terminal.select(e.col,e.row,e.size),t){const s=this._decorationManager.createActiveDecoration(e,t);s&&(this._resultTracker.selectedDecoration=s)}if(!s&&(e.row>=this._terminal.buffer.active.viewportY+this._terminal.rows||e.row<this._terminal.buffer.active.viewportY)){let t=e.row-this._terminal.buffer.active.viewportY;t-=Math.floor(this._terminal.rows/2),this._terminal.scrollLines(t)}return!0}}e.SearchAddon=d})(),i})());
//# sourceMappingURL=addon-search.js.map
\ No newline at end of file
diff --git a/lib/addon-search.js.map b/lib/addon-search.js.map
index 6e51b339d995257eb8214e8dd537d5bd429bf907..3b1df89af9eaf103ad5538e74bd53c8a933ddbee 100644
--- a/lib/addon-search.js.map
+++ b/lib/addon-search.js.map
@@ -1 +1 @@
-{"version":3,"file":"addon-search.js","mappings":"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","sources":["webpack://SearchAddon/webpack/universalModuleDefinition","webpack://SearchAddon/../src/common/Async.ts","webpack://SearchAddon/../src/common/Event.ts","webpack://SearchAddon/../src/common/Lifecycle.ts","webpack://SearchAddon/./src/DecorationManager.ts","webpack://SearchAddon/./src/SearchEngine.ts","webpack://SearchAddon/./src/SearchLineCache.ts","webpack://SearchAddon/./src/SearchResultTracker.ts","webpack://SearchAddon/./src/SearchState.ts","webpack://SearchAddon/webpack/bootstrap","webpack://SearchAddon/./src/SearchAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SearchAddon\"] = factory();\n\telse\n\t\troot[\"SearchAddon\"] = factory();\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent<T> {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter<T> {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent<T> | undefined;\n\n public get event(): IEvent<T> {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners = this._listeners.slice();\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners = this._listeners.slice();\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed || !this._listeners.length) {\n return;\n }\n if (this._listeners.length === 1) {\n this._listeners[0].fn.call(this._listeners[0].thisArgs, event);\n return;\n }\n const listeners = this._listeners;\n for (let i = 0, len = listeners.length; i < len; ++i) {\n listeners[i].fn.call(listeners[i].thisArgs, event);\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward<T>(from: IEvent<T>, to: Emitter<T>): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map<I, O>(event: IEvent<I>, map: (i: I) => O): IEvent<O> {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any<T>(...events: IEvent<T>[]): IEvent<T>;\n export function any(...events: IEvent<any>[]): IEvent<void>;\n export function any<T>(...events: IEvent<T>[]): IEvent<T> {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose<T extends IDisposable>(disposable: T): T;\nexport function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;\nexport function dispose<T extends IDisposable>(disposables: T[]): T[];\nexport function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set<IDisposable>();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add<T extends IDisposable>(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register<T extends IDisposable>(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';\nimport type { ISearchDecorationOptions } from '@xterm/addon-search';\nimport { dispose, Disposable, toDisposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a highlight decoration.\n */\ninterface IHighlight extends IDisposable {\n decoration: IDecoration;\n match: ISearchResult;\n}\n\n/**\n * Interface for managing multiple decorations for a single match.\n */\ninterface IMultiHighlight extends IDisposable {\n decorations: IDecoration[];\n match: ISearchResult;\n}\n\n/**\n * Manages visual decorations for search results including highlighting and active selection\n * indicators. This class handles the creation, styling, and disposal of search-related decorations.\n */\nexport class DecorationManager extends Disposable {\n private _highlightDecorations: IHighlight[] = [];\n private _highlightedLines: Set<number> = new Set();\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this.clearHighlightDecorations()));\n }\n\n /**\n * Creates decorations for all provided search results.\n * @param results The search results to create decorations for.\n * @param options The decoration options.\n */\n public createHighlightDecorations(results: ISearchResult[], options: ISearchDecorationOptions): void {\n this.clearHighlightDecorations();\n\n for (const match of results) {\n const decorations = this._createResultDecorations(match, options, false);\n if (decorations) {\n for (const decoration of decorations) {\n this._storeDecoration(decoration, match);\n }\n }\n }\n }\n\n /**\n * Creates decorations for the currently active search result.\n * @param result The active search result.\n * @param options The decoration options.\n * @returns The multi-highlight decoration or undefined if creation failed.\n */\n public createActiveDecoration(result: ISearchResult, options: ISearchDecorationOptions): IMultiHighlight | undefined {\n const decorations = this._createResultDecorations(result, options, true);\n if (decorations) {\n return { decorations, match: result, dispose() { dispose(decorations); } };\n }\n return undefined;\n }\n\n /**\n * Clears all highlight decorations.\n */\n public clearHighlightDecorations(): void {\n dispose(this._highlightDecorations);\n this._highlightDecorations = [];\n this._highlightedLines.clear();\n }\n\n /**\n * Stores a decoration and tracks it for management.\n * @param decoration The decoration to store.\n * @param match The search result this decoration represents.\n */\n private _storeDecoration(decoration: IDecoration, match: ISearchResult): void {\n this._highlightedLines.add(decoration.marker.line);\n this._highlightDecorations.push({ decoration, match, dispose() { decoration.dispose(); } });\n }\n\n /**\n * Applies styles to the decoration when it is rendered.\n * @param element The decoration's element.\n * @param borderColor The border color to apply.\n * @param isActiveResult Whether the element is part of the active search result.\n */\n private _applyStyles(element: HTMLElement, borderColor: string | undefined, isActiveResult: boolean): void {\n if (!element.classList.contains('xterm-find-result-decoration')) {\n element.classList.add('xterm-find-result-decoration');\n if (borderColor) {\n element.style.outline = `1px solid ${borderColor}`;\n }\n }\n if (isActiveResult) {\n element.classList.add('xterm-find-active-result-decoration');\n }\n }\n\n /**\n * Creates a decoration for the result and applies styles\n * @param result the search result for which to create the decoration\n * @param options the options for the decoration\n * @param isActiveResult whether this is the currently active result\n * @returns the decorations or undefined if the marker has already been disposed of\n */\n private _createResultDecorations(result: ISearchResult, options: ISearchDecorationOptions, isActiveResult: boolean): IDecoration[] | undefined {\n // Gather decoration ranges for this match as it could wrap\n const decorationRanges: [number, number, number][] = [];\n let currentCol = result.col;\n let remainingSize = result.size;\n let markerOffset = -this._terminal.buffer.active.baseY - this._terminal.buffer.active.cursorY + result.row;\n while (remainingSize > 0) {\n const amountThisRow = Math.min(this._terminal.cols - currentCol, remainingSize);\n decorationRanges.push([markerOffset, currentCol, amountThisRow]);\n currentCol = 0;\n remainingSize -= amountThisRow;\n markerOffset++;\n }\n\n // Create the decorations\n const decorations: IDecoration[] = [];\n for (const range of decorationRanges) {\n const marker = this._terminal.registerMarker(range[0]);\n const decoration = this._terminal.registerDecoration({\n marker,\n x: range[1],\n width: range[2],\n layer: isActiveResult ? 'top' : 'bottom',\n backgroundColor: isActiveResult ? options.activeMatchBackground : options.matchBackground,\n overviewRulerOptions: this._highlightedLines.has(marker.line) ? undefined : {\n color: isActiveResult ? options.activeMatchColorOverviewRuler : options.matchOverviewRuler,\n position: 'center'\n }\n });\n if (decoration) {\n const disposables: IDisposable[] = [];\n disposables.push(marker);\n disposables.push(decoration.onRender((e) => this._applyStyles(e, isActiveResult ? options.activeMatchBorder : options.matchBorder, false)));\n disposables.push(decoration.onDispose(() => dispose(disposables)));\n decorations.push(decoration);\n }\n }\n\n return decorations.length === 0 ? undefined : decorations;\n }\n}\n\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport type { ISearchOptions } from '@xterm/addon-search';\nimport type { SearchLineCache } from './SearchLineCache';\n\n/**\n * Represents the position to start a search from.\n */\ninterface ISearchPosition {\n startCol: number;\n startRow: number;\n}\n\n/**\n * Represents a search result with its position and content.\n */\nexport interface ISearchResult {\n term: string;\n col: number;\n row: number;\n size: number;\n}\n\n/**\n * Configuration constants for the search engine functionality.\n */\nconst enum Constants {\n /**\n * Characters that are considered non-word characters for search boundary detection. These\n * characters are used to determine word boundaries when performing whole-word searches. Includes\n * common punctuation, symbols, and whitespace characters.\n */\n NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\\\;:\"\\',./<>?'\n}\n\n/**\n * Core search engine that handles finding text within terminal content.\n * This class is responsible for the actual search algorithms and position calculations.\n */\nexport class SearchEngine {\n constructor(\n private readonly _terminal: Terminal,\n private readonly _lineCache: SearchLineCache\n ) {}\n\n /**\n * Find the first occurrence of a term starting from a specific position.\n * @param term The search term.\n * @param startRow The row to start searching from.\n * @param startCol The column to start searching from.\n * @param searchOptions Search options.\n * @returns The search result if found, undefined otherwise.\n */\n public find(term: string, startRow: number, startCol: number, searchOptions?: ISearchOptions): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n if (startCol >= this._terminal.cols) {\n throw new Error(`Invalid col: ${startCol} to search in terminal of ${this._terminal.cols} cols`);\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n return result;\n }\n\n /**\n * Find the next occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine incremental behavior.\n * @returns The search result if found, undefined otherwise.\n */\n public findNextWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startCol = 0;\n let startRow = 0;\n if (prevSelectedPos) {\n if (cachedSearchTerm === term) {\n startCol = prevSelectedPos.end.x;\n startRow = prevSelectedPos.end.y;\n } else {\n startCol = prevSelectedPos.start.x;\n startRow = prevSelectedPos.start.y;\n }\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n // If we hit the bottom and didn't search from the very top wrap back up\n if (!result && startRow !== 0) {\n for (let y = 0; y < startRow; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n\n // If there is only one result, wrap back and return selection if it exists.\n if (!result && prevSelectedPos) {\n searchPosition.startRow = prevSelectedPos.start.y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n }\n\n return result;\n }\n\n /**\n * Find the previous occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine if expansion should occur.\n * @returns The search result if found, undefined otherwise.\n */\n public findPreviousWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startRow = this._terminal.buffer.active.baseY + this._terminal.rows - 1;\n const startCol = this._terminal.cols;\n const isReverseSearch = true;\n\n this._lineCache.initLinesCache();\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n let result: ISearchResult | undefined;\n if (prevSelectedPos) {\n searchPosition.startRow = startRow = prevSelectedPos.start.y;\n searchPosition.startCol = prevSelectedPos.start.x;\n if (cachedSearchTerm !== term) {\n // Try to expand selection to right first.\n result = this._findInLine(term, searchPosition, searchOptions, false);\n if (!result) {\n // If selection was not able to be expanded to the right, then try reverse search\n searchPosition.startRow = startRow = prevSelectedPos.end.y;\n searchPosition.startCol = prevSelectedPos.end.x;\n }\n }\n }\n\n result ??= this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n\n // Search from startRow - 1 to top\n if (!result) {\n searchPosition.startCol = Math.max(searchPosition.startCol, this._terminal.cols);\n for (let y = startRow - 1; y >= 0; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n // If we hit the top and didn't search from the very bottom wrap back down\n if (!result && startRow !== (this._terminal.buffer.active.baseY + this._terminal.rows - 1)) {\n for (let y = (this._terminal.buffer.active.baseY + this._terminal.rows - 1); y >= startRow; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n\n return result;\n }\n\n /**\n * A found substring is a whole word if it doesn't have an alphanumeric character directly\n * adjacent to it.\n * @param searchIndex starting index of the potential whole word substring\n * @param line entire string in which the potential whole word was found\n * @param term the substring that starts at searchIndex\n */\n private _isWholeWord(searchIndex: number, line: string, term: string): boolean {\n return ((searchIndex === 0) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex - 1]))) &&\n (((searchIndex + term.length) === line.length) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex + term.length])));\n }\n\n /**\n * Searches a line for a search term. Takes the provided terminal line and searches the text line,\n * which may contain subsequent terminal lines if the text is wrapped. If the provided line number\n * is part of a wrapped text line that started on an earlier line then it is skipped since it will\n * be properly searched when the terminal line that the text starts on is searched.\n * @param term The search term.\n * @param searchPosition The position to start the search.\n * @param searchOptions Search options.\n * @param isReverseSearch Whether the search should start from the right side of the terminal and\n * search to the left.\n * @returns The search result if it was found.\n */\n private _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {\n const row = searchPosition.startRow;\n const col = searchPosition.startCol;\n\n // Ignore wrapped lines, only consider on unwrapped line (first row of command string).\n const firstLine = this._terminal.buffer.active.getLine(row);\n if (firstLine?.isWrapped) {\n if (isReverseSearch) {\n searchPosition.startCol += this._terminal.cols;\n return;\n }\n\n // This will iterate until we find the line start.\n // When we find it, we will search using the calculated start column.\n searchPosition.startRow--;\n searchPosition.startCol += this._terminal.cols;\n return this._findInLine(term, searchPosition, searchOptions);\n }\n let cache = this._lineCache.getLineFromCache(row);\n if (!cache) {\n cache = this._lineCache.translateBufferLineToStringWithWrap(row, true);\n this._lineCache.setLineInCache(row, cache);\n }\n const [stringLine, offsets] = cache;\n\n const offset = this._bufferColsToStringOffset(row, col);\n let searchTerm = term;\n let searchStringLine = stringLine;\n if (!searchOptions.regex) {\n searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();\n searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();\n }\n\n let resultIndex = -1;\n if (searchOptions.regex) {\n const searchRegex = RegExp(searchTerm, searchOptions.caseSensitive ? 'g' : 'gi');\n let foundTerm: RegExpExecArray | null;\n if (isReverseSearch) {\n // This loop will get the resultIndex of the _last_ regex match in the range 0..offset\n while (foundTerm = searchRegex.exec(searchStringLine.slice(0, offset))) {\n resultIndex = searchRegex.lastIndex - foundTerm[0].length;\n term = foundTerm[0];\n searchRegex.lastIndex -= (term.length - 1);\n }\n } else {\n foundTerm = searchRegex.exec(searchStringLine.slice(offset));\n if (foundTerm && foundTerm[0].length > 0) {\n resultIndex = offset + (searchRegex.lastIndex - foundTerm[0].length);\n term = foundTerm[0];\n }\n }\n } else {\n if (isReverseSearch) {\n if (offset - searchTerm.length >= 0) {\n resultIndex = searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length);\n }\n } else {\n resultIndex = searchStringLine.indexOf(searchTerm, offset);\n }\n }\n\n if (resultIndex >= 0) {\n if (searchOptions.wholeWord && !this._isWholeWord(resultIndex, searchStringLine, term)) {\n return;\n }\n\n // Adjust the row number and search index if needed since a \"line\" of text can span multiple\n // rows\n let startRowOffset = 0;\n while (startRowOffset < offsets.length - 1 && resultIndex >= offsets[startRowOffset + 1]) {\n startRowOffset++;\n }\n let endRowOffset = startRowOffset;\n while (endRowOffset < offsets.length - 1 && resultIndex + term.length >= offsets[endRowOffset + 1]) {\n endRowOffset++;\n }\n const startColOffset = resultIndex - offsets[startRowOffset];\n const endColOffset = resultIndex + term.length - offsets[endRowOffset];\n const startColIndex = this._stringLengthToBufferSize(row + startRowOffset, startColOffset);\n const endColIndex = this._stringLengthToBufferSize(row + endRowOffset, endColOffset);\n const size = endColIndex - startColIndex + this._terminal.cols * (endRowOffset - startRowOffset);\n\n return {\n term,\n col: startColIndex,\n row: row + startRowOffset,\n size\n };\n }\n }\n\n private _stringLengthToBufferSize(row: number, offset: number): number {\n const line = this._terminal.buffer.active.getLine(row);\n if (!line) {\n return 0;\n }\n for (let i = 0; i < offset; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n // Adjust the searchIndex to normalize emoji into single chars\n const char = cell.getChars();\n if (char.length > 1) {\n offset -= char.length - 1;\n }\n // Adjust the searchIndex for empty characters following wide unicode\n // chars (eg. CJK)\n const nextCell = line.getCell(i + 1);\n if (nextCell && nextCell.getWidth() === 0) {\n offset++;\n }\n }\n return offset;\n }\n\n private _bufferColsToStringOffset(startRow: number, cols: number): number {\n let lineIndex = startRow;\n let offset = 0;\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (cols > 0 && line) {\n for (let i = 0; i < cols && i < this._terminal.cols; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n if (cell.getWidth()) {\n // Treat null characters as whitespace to align with the translateToString API\n offset += cell.getCode() === 0 ? 1 : cell.getChars().length;\n }\n }\n lineIndex++;\n line = this._terminal.buffer.active.getLine(lineIndex);\n if (line && !line.isWrapped) {\n break;\n }\n cols -= this._terminal.cols;\n }\n return offset;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\n\nexport type LineCacheEntry = [\n /**\n * The string representation of a line (as opposed to the buffer cell representation).\n */\n lineAsString: string,\n /**\n * The offsets where each line starts when the entry describes a wrapped line.\n */\n lineOffsets: number[]\n];\n\n/**\n * Configuration constants for the search line cache functionality.\n */\nconst enum Constants {\n /**\n * Time-to-live for cached search results in milliseconds. After this duration, cached search\n * results will be invalidated to ensure they remain consistent with terminal content changes.\n */\n LINES_CACHE_TIME_TO_LIVE = 15000\n}\n\nexport class SearchLineCache extends Disposable {\n /**\n * translateBufferLineToStringWithWrap is a fairly expensive call.\n * We memoize the calls into an array that has a time based ttl.\n * _linesCache is also invalidated when the terminal cursor moves.\n */\n private _linesCache: LineCacheEntry[] | undefined;\n private _linesCacheTimeout = this._register(new MutableDisposable());\n private _linesCacheDisposables = this._register(new MutableDisposable());\n // Track access to avoid recreating a timeout on every init call which occurs once per search\n // result (findNext/findPrevious -> _highlightAllMatches -> find loop).\n private _lastAccessTimestamp = 0;\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this._destroyLinesCache()));\n }\n\n /**\n * Sets up a line cache with a ttl\n */\n public initLinesCache(): void {\n if (!this._linesCache) {\n this._linesCache = new Array(this._terminal.buffer.active.length);\n this._linesCacheDisposables.value = combinedDisposable(\n this._terminal.onLineFeed(() => this._destroyLinesCache()),\n this._terminal.onCursorMove(() => this._destroyLinesCache()),\n this._terminal.onResize(() => this._destroyLinesCache())\n );\n }\n\n this._lastAccessTimestamp = Date.now();\n if (!this._linesCacheTimeout.value) {\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE);\n }\n }\n\n private _destroyLinesCache(): void {\n this._linesCache = undefined;\n this._lastAccessTimestamp = 0;\n this._linesCacheDisposables.clear();\n this._linesCacheTimeout.clear();\n }\n\n private _scheduleLinesCacheTimeout(delay: number): void {\n this._linesCacheTimeout.value = disposableTimeout(() => {\n if (!this._linesCache) {\n return;\n }\n const now = Date.now();\n const elapsed = now - this._lastAccessTimestamp;\n if (elapsed >= Constants.LINES_CACHE_TIME_TO_LIVE) {\n this._destroyLinesCache();\n return;\n }\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE - elapsed);\n }, delay);\n }\n\n public getLineFromCache(row: number): LineCacheEntry | undefined {\n return this._linesCache?.[row];\n }\n\n public setLineInCache(row: number, entry: LineCacheEntry): void {\n if (this._linesCache) {\n this._linesCache[row] = entry;\n }\n }\n\n /**\n * Translates a buffer line to a string, including subsequent lines if they are wraps.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n */\n public translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean): LineCacheEntry {\n const strings = [];\n const lineOffsets = [0];\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (line) {\n const nextLine = this._terminal.buffer.active.getLine(lineIndex + 1);\n const lineWrapsToNext = nextLine ? nextLine.isWrapped : false;\n let string = line.translateToString(!lineWrapsToNext && trimRight);\n if (lineWrapsToNext && nextLine) {\n const lastCell = line.getCell(line.length - 1);\n const lastCellIsNull = lastCell && lastCell.getCode() === 0 && lastCell.getWidth() === 1;\n // a wide character wrapped to the next line\n if (lastCellIsNull && nextLine.getCell(0)?.getWidth() === 2) {\n string = string.slice(0, -1);\n }\n }\n strings.push(string);\n if (lineWrapsToNext) {\n lineOffsets.push(lineOffsets[lineOffsets.length - 1] + string.length);\n } else {\n break;\n }\n lineIndex++;\n line = nextLine;\n }\n return [strings.join(''), lineOffsets];\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchResultChangeEvent } from '@xterm/addon-search';\nimport type { IDisposable } from '@xterm/xterm';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a currently selected decoration.\n */\ninterface ISelectedDecoration extends IDisposable {\n match: ISearchResult;\n}\n\n/**\n * Tracks search results, manages result indexing, and fires events when results change.\n * This class provides centralized management of search result state and notifications.\n */\nexport class SearchResultTracker extends Disposable {\n private _searchResults: ISearchResult[] = [];\n private _selectedDecoration: ISelectedDecoration | undefined;\n\n private readonly _onDidChangeResults = this._register(new Emitter<ISearchResultChangeEvent>());\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> { return this._onDidChangeResults.event; }\n\n /**\n * Gets the current search results.\n */\n public get searchResults(): ReadonlyArray<ISearchResult> {\n return this._searchResults;\n }\n\n /**\n * Gets the currently selected decoration.\n */\n public get selectedDecoration(): ISelectedDecoration | undefined {\n return this._selectedDecoration;\n }\n\n /**\n * Sets the currently selected decoration.\n */\n public set selectedDecoration(decoration: ISelectedDecoration | undefined) {\n this._selectedDecoration = decoration;\n }\n\n /**\n * Updates the search results with a new set of results.\n * @param results The new search results.\n * @param maxResults The maximum number of results to track.\n */\n public updateResults(results: ISearchResult[], maxResults: number): void {\n this._searchResults = results.slice(0, maxResults);\n }\n\n /**\n * Clears all search results.\n */\n public clearResults(): void {\n this._searchResults = [];\n }\n\n /**\n * Clears the selected decoration.\n */\n public clearSelectedDecoration(): void {\n if (this._selectedDecoration) {\n this._selectedDecoration.dispose();\n this._selectedDecoration = undefined;\n }\n }\n\n /**\n * Finds the index of a result in the current results array.\n * @param result The result to find.\n * @returns The index of the result, or -1 if not found.\n */\n public findResultIndex(result: ISearchResult): number {\n for (let i = 0; i < this._searchResults.length; i++) {\n const match = this._searchResults[i];\n if (match.row === result.row && match.col === result.col && match.size === result.size) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Fires a result change event with the current state.\n * @param hasDecorations Whether decorations are enabled.\n */\n public fireResultsChanged(hasDecorations: boolean): void {\n if (!hasDecorations) {\n return;\n }\n\n let resultIndex = -1;\n if (this._selectedDecoration) {\n resultIndex = this.findResultIndex(this._selectedDecoration.match);\n }\n\n this._onDidChangeResults.fire({\n resultIndex,\n resultCount: this._searchResults.length\n });\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this.clearSelectedDecoration();\n this.clearResults();\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchOptions } from '@xterm/addon-search';\n\n/**\n * Manages search state including cached search terms, options tracking, and validation.\n * This class provides a centralized way to handle search state consistency and option changes.\n */\nexport class SearchState {\n private _cachedSearchTerm: string | undefined;\n private _lastSearchOptions: ISearchOptions | undefined;\n\n /**\n * Gets the currently cached search term.\n */\n public get cachedSearchTerm(): string | undefined {\n return this._cachedSearchTerm;\n }\n\n /**\n * Sets the cached search term.\n */\n public set cachedSearchTerm(term: string | undefined) {\n this._cachedSearchTerm = term;\n }\n\n /**\n * Gets the last search options used.\n */\n public get lastSearchOptions(): ISearchOptions | undefined {\n return this._lastSearchOptions;\n }\n\n /**\n * Sets the last search options used.\n */\n public set lastSearchOptions(options: ISearchOptions | undefined) {\n this._lastSearchOptions = options;\n }\n\n /**\n * Validates a search term to ensure it's not empty or invalid.\n * @param term The search term to validate.\n * @returns true if the term is valid for searching.\n */\n public isValidSearchTerm(term: string): boolean {\n return !!(term && term.length > 0);\n }\n\n /**\n * Determines if search options have changed compared to the last search.\n * @param newOptions The new search options to compare.\n * @returns true if the options have changed.\n */\n public didOptionsChange(newOptions?: ISearchOptions): boolean {\n if (!this._lastSearchOptions) {\n return true;\n }\n if (!newOptions) {\n return false;\n }\n if (this._lastSearchOptions.caseSensitive !== newOptions.caseSensitive) {\n return true;\n }\n if (this._lastSearchOptions.regex !== newOptions.regex) {\n return true;\n }\n if (this._lastSearchOptions.wholeWord !== newOptions.wholeWord) {\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a new search should trigger highlighting updates.\n * @param term The search term.\n * @param options The search options.\n * @returns true if highlighting should be updated.\n */\n public shouldUpdateHighlighting(term: string, options?: ISearchOptions): boolean {\n if (!options?.decorations) {\n return false;\n }\n return this._cachedSearchTerm === undefined ||\n term !== this._cachedSearchTerm ||\n this.didOptionsChange(options);\n }\n\n /**\n * Clears the cached search term.\n */\n public clearCachedTerm(): void {\n this._cachedSearchTerm = undefined;\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this._cachedSearchTerm = undefined;\n this._lastSearchOptions = undefined;\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';\nimport type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\nimport { SearchLineCache } from './SearchLineCache';\nimport { SearchState } from './SearchState';\nimport { SearchEngine, type ISearchResult } from './SearchEngine';\nimport { DecorationManager } from './DecorationManager';\nimport { SearchResultTracker } from './SearchResultTracker';\n\ninterface IInternalSearchOptions {\n noScroll: boolean;\n}\n\n/**\n * Configuration constants for the search addon functionality.\n */\nconst enum Constants {\n /**\n * Default maximum number of search results to highlight simultaneously. This limit prevents\n * performance degradation when searching for very common terms that would result in excessive\n * highlighting decorations.\n */\n DEFAULT_HIGHLIGHT_LIMIT = 1000\n}\n\nexport class SearchAddon extends Disposable implements ITerminalAddon, ISearchApi {\n private _terminal: Terminal | undefined;\n private _highlightLimit: number;\n private _highlightTimeout = this._register(new MutableDisposable<IDisposable>());\n private _lineCache = this._register(new MutableDisposable<SearchLineCache>());\n\n // Component instances\n private _state = new SearchState();\n private _engine: SearchEngine | undefined;\n private _decorationManager: DecorationManager | undefined;\n private _resultTracker = this._register(new SearchResultTracker());\n\n private readonly _onAfterSearch = this._register(new Emitter<void>());\n public readonly onAfterSearch = this._onAfterSearch.event;\n private readonly _onBeforeSearch = this._register(new Emitter<void>());\n public readonly onBeforeSearch = this._onBeforeSearch.event;\n\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> {\n return this._resultTracker.onDidChangeResults;\n }\n\n constructor(options?: Partial<ISearchAddonOptions>) {\n super();\n\n this._highlightLimit = options?.highlightLimit ?? Constants.DEFAULT_HIGHLIGHT_LIMIT;\n }\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n this._lineCache.value = new SearchLineCache(terminal);\n this._engine = new SearchEngine(terminal, this._lineCache.value);\n this._decorationManager = new DecorationManager(terminal);\n this._register(this._terminal.onWriteParsed(() => this._updateMatches()));\n this._register(this._terminal.onResize(() => this._updateMatches()));\n this._register(toDisposable(() => this.clearDecorations()));\n }\n\n private _updateMatches(): void {\n this._highlightTimeout.clear();\n if (this._state.cachedSearchTerm && this._state.lastSearchOptions?.decorations) {\n this._highlightTimeout.value = disposableTimeout(() => {\n const term = this._state.cachedSearchTerm;\n this._state.clearCachedTerm();\n this.findPrevious(term!, { ...this._state.lastSearchOptions, incremental: true }, { noScroll: true });\n }, 200);\n }\n }\n\n public clearDecorations(retainCachedSearchTerm?: boolean): void {\n this._resultTracker.clearSelectedDecoration();\n this._decorationManager?.clearHighlightDecorations();\n this._resultTracker.clearResults();\n if (!retainCachedSearchTerm) {\n this._state.clearCachedTerm();\n }\n }\n\n public clearActiveDecoration(): void {\n this._resultTracker.clearSelectedDecoration();\n }\n\n /**\n * Find the next instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findNext(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findNextAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _highlightAllMatches(term: string, searchOptions: ISearchOptions): void {\n if (!this._terminal || !this._engine || !this._decorationManager) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n if (!this._state.isValidSearchTerm(term)) {\n this.clearDecorations();\n return;\n }\n\n // new search, clear out the old decorations\n this.clearDecorations(true);\n\n const results: ISearchResult[] = [];\n let prevResult: ISearchResult | undefined = undefined;\n let result = this._engine.find(term, 0, 0, searchOptions);\n\n while (result && (prevResult?.row !== result.row || prevResult?.col !== result.col)) {\n if (results.length >= this._highlightLimit) {\n break;\n }\n prevResult = result;\n results.push(prevResult);\n const cols = this._terminal.cols;\n let nextCol = prevResult.col + prevResult.size;\n let nextRow = prevResult.row;\n if (nextCol >= cols) {\n nextRow += Math.floor(nextCol / cols);\n nextCol = nextCol % cols;\n }\n result = this._engine.find(term, nextRow, nextCol, searchOptions);\n }\n\n this._resultTracker.updateResults(results, this._highlightLimit);\n if (searchOptions.decorations) {\n this._decorationManager.createHighlightDecorations(results, searchOptions.decorations);\n }\n }\n\n private _findNextAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findNextWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Find the previous instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findPrevious(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findPreviousAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _fireResults(searchOptions?: ISearchOptions): void {\n this._resultTracker.fireResultsChanged(!!searchOptions?.decorations);\n }\n\n private _findPreviousAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findPreviousWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Selects and scrolls to a result.\n * @param result The result to select.\n * @returns Whether a result was selected.\n */\n private _selectResult(result: ISearchResult | undefined, options?: ISearchDecorationOptions, noScroll?: boolean): boolean {\n if (!this._terminal || !this._decorationManager) {\n return false;\n }\n\n this._resultTracker.clearSelectedDecoration();\n if (!result) {\n this._terminal.clearSelection();\n return false;\n }\n\n this._terminal.select(result.col, result.row, result.size);\n if (options) {\n const activeDecoration = this._decorationManager.createActiveDecoration(result, options);\n if (activeDecoration) {\n this._resultTracker.selectedDecoration = activeDecoration;\n }\n }\n\n if (!noScroll) {\n // If it is not in the viewport then we scroll else it just gets selected\n if (result.row >= (this._terminal.buffer.active.viewportY + this._terminal.rows) || result.row < this._terminal.buffer.active.viewportY) {\n let scroll = result.row - this._terminal.buffer.active.viewportY;\n scroll -= Math.floor(this._terminal.rows / 2);\n this._terminal.scrollLines(scroll);\n }\n }\n return true;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","millis","Promise","resolve","setTimeout","handler","timeout","store","timer","disposable","dispose","Lifecycle_1","toDisposable","clearTimeout","add","__webpack_require__","constructor","this","_token","_isDisposed","cancel","cancelAndSet","runner","Error","setIfNotSet","_isScheduled","set","queueMicrotask","_disposable","undefined","interval","context","handle","setInterval","clearInterval","EventUtils","_listeners","_disposed","event","_event","listener","thisArgs","disposables","entry","fn","slice","push","result","idx","indexOf","splice","Array","isArray","fire","length","call","listeners","i","len","forward","from","to","e","map","any","events","DisposableStore","runAndSubscribe","initial","arg","d","_disposables","Set","isDisposed","o","clear","Disposable","_store","_register","None","Object","freeze","value","_value","DecorationManager","_terminal","super","_highlightDecorations","_highlightedLines","clearHighlightDecorations","createHighlightDecorations","results","options","match","decorations","_createResultDecorations","decoration","_storeDecoration","createActiveDecoration","marker","line","_applyStyles","element","borderColor","isActiveResult","classList","contains","style","outline","decorationRanges","currentCol","col","remainingSize","size","markerOffset","buffer","active","baseY","cursorY","row","amountThisRow","Math","min","cols","range","registerMarker","registerDecoration","x","width","layer","backgroundColor","activeMatchBackground","matchBackground","overviewRulerOptions","has","color","activeMatchColorOverviewRuler","matchOverviewRuler","position","onRender","activeMatchBorder","matchBorder","onDispose","_lineCache","find","term","startRow","startCol","searchOptions","clearSelection","initLinesCache","searchPosition","_findInLine","y","rows","findNextWithSelection","cachedSearchTerm","prevSelectedPos","getSelectionPosition","end","start","findPreviousWithSelection","isReverseSearch","max","_isWholeWord","searchIndex","includes","firstLine","getLine","isWrapped","cache","getLineFromCache","translateBufferLineToStringWithWrap","setLineInCache","stringLine","offsets","offset","_bufferColsToStringOffset","searchTerm","searchStringLine","regex","caseSensitive","toLowerCase","resultIndex","searchRegex","RegExp","foundTerm","exec","lastIndex","lastIndexOf","wholeWord","startRowOffset","endRowOffset","startColOffset","endColOffset","startColIndex","_stringLengthToBufferSize","cell","getCell","char","getChars","nextCell","getWidth","lineIndex","getCode","Async_1","SearchLineCache","_linesCacheTimeout","MutableDisposable","_linesCacheDisposables","_lastAccessTimestamp","_destroyLinesCache","_linesCache","combinedDisposable","onLineFeed","onCursorMove","onResize","Date","now","_scheduleLinesCacheTimeout","delay","disposableTimeout","elapsed","trimRight","strings","lineOffsets","nextLine","lineWrapsToNext","string","translateToString","lastCell","join","Event_1","SearchResultTracker","_searchResults","_onDidChangeResults","Emitter","onDidChangeResults","searchResults","selectedDecoration","_selectedDecoration","updateResults","maxResults","clearResults","clearSelectedDecoration","findResultIndex","fireResultsChanged","hasDecorations","resultCount","reset","_cachedSearchTerm","lastSearchOptions","_lastSearchOptions","isValidSearchTerm","didOptionsChange","newOptions","shouldUpdateHighlighting","clearCachedTerm","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","SearchLineCache_1","SearchState_1","SearchEngine_1","DecorationManager_1","SearchResultTracker_1","SearchAddon","_resultTracker","_highlightTimeout","_state","SearchState","_onAfterSearch","onAfterSearch","_onBeforeSearch","onBeforeSearch","_highlightLimit","highlightLimit","activate","terminal","_engine","SearchEngine","_decorationManager","onWriteParsed","_updateMatches","clearDecorations","findPrevious","incremental","noScroll","retainCachedSearchTerm","clearActiveDecoration","findNext","internalSearchOptions","_highlightAllMatches","found","_findNextAndSelect","_fireResults","prevResult","nextCol","nextRow","floor","_selectResult","_findPreviousAndSelect","select","activeDecoration","viewportY","scroll","scrollLines"],"sourceRoot":""}
\ No newline at end of file
+{"version":3,"file":"addon-search.js","mappings":"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","sources":["webpack://SearchAddon/webpack/universalModuleDefinition","webpack://SearchAddon/../src/common/Async.ts","webpack://SearchAddon/../src/common/Event.ts","webpack://SearchAddon/../src/common/Lifecycle.ts","webpack://SearchAddon/./src/DecorationManager.ts","webpack://SearchAddon/./src/SearchEngine.ts","webpack://SearchAddon/./src/SearchLineCache.ts","webpack://SearchAddon/./src/SearchResultTracker.ts","webpack://SearchAddon/./src/SearchState.ts","webpack://SearchAddon/webpack/bootstrap","webpack://SearchAddon/./src/SearchAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SearchAddon\"] = factory();\n\telse\n\t\troot[\"SearchAddon\"] = factory();\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent<T> {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter<T> {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent<T> | undefined;\n\n public get event(): IEvent<T> {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners = this._listeners.slice();\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners = this._listeners.slice();\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed || !this._listeners.length) {\n return;\n }\n if (this._listeners.length === 1) {\n this._listeners[0].fn.call(this._listeners[0].thisArgs, event);\n return;\n }\n const listeners = this._listeners;\n for (let i = 0, len = listeners.length; i < len; ++i) {\n listeners[i].fn.call(listeners[i].thisArgs, event);\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward<T>(from: IEvent<T>, to: Emitter<T>): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map<I, O>(event: IEvent<I>, map: (i: I) => O): IEvent<O> {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any<T>(...events: IEvent<T>[]): IEvent<T>;\n export function any(...events: IEvent<any>[]): IEvent<void>;\n export function any<T>(...events: IEvent<T>[]): IEvent<T> {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n","/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose<T extends IDisposable>(disposable: T): T;\nexport function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;\nexport function dispose<T extends IDisposable>(disposables: T[]): T[];\nexport function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set<IDisposable>();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add<T extends IDisposable>(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register<T extends IDisposable>(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';\nimport type { ISearchDecorationOptions } from '@xterm/addon-search';\nimport { dispose, Disposable, toDisposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a highlight decoration.\n */\ninterface IHighlight extends IDisposable {\n decoration: IDecoration;\n match: ISearchResult;\n}\n\n/**\n * Interface for managing multiple decorations for a single match.\n */\ninterface IMultiHighlight extends IDisposable {\n decorations: IDecoration[];\n match: ISearchResult;\n}\n\n/**\n * Manages visual decorations for search results including highlighting and active selection\n * indicators. This class handles the creation, styling, and disposal of search-related decorations.\n */\nexport class DecorationManager extends Disposable {\n private _highlightDecorations: IHighlight[] = [];\n private _highlightedLines: Set<number> = new Set();\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this.clearHighlightDecorations()));\n }\n\n /**\n * Creates decorations for all provided search results.\n * @param results The search results to create decorations for.\n * @param options The decoration options.\n */\n public createHighlightDecorations(results: ISearchResult[], options: ISearchDecorationOptions): void {\n this.clearHighlightDecorations();\n\n for (const match of results) {\n const decorations = this._createResultDecorations(match, options, false);\n if (decorations) {\n for (const decoration of decorations) {\n this._storeDecoration(decoration, match);\n }\n }\n }\n }\n\n /**\n * Creates decorations for the currently active search result.\n * @param result The active search result.\n * @param options The decoration options.\n * @returns The multi-highlight decoration or undefined if creation failed.\n */\n public createActiveDecoration(result: ISearchResult, options: ISearchDecorationOptions): IMultiHighlight | undefined {\n const decorations = this._createResultDecorations(result, options, true);\n if (decorations) {\n return { decorations, match: result, dispose() { dispose(decorations); } };\n }\n return undefined;\n }\n\n /**\n * Clears all highlight decorations.\n */\n public clearHighlightDecorations(): void {\n dispose(this._highlightDecorations);\n this._highlightDecorations = [];\n this._highlightedLines.clear();\n }\n\n /**\n * Stores a decoration and tracks it for management.\n * @param decoration The decoration to store.\n * @param match The search result this decoration represents.\n */\n private _storeDecoration(decoration: IDecoration, match: ISearchResult): void {\n this._highlightedLines.add(decoration.marker.line);\n this._highlightDecorations.push({ decoration, match, dispose() { decoration.dispose(); } });\n }\n\n /**\n * Applies styles to the decoration when it is rendered.\n * @param element The decoration's element.\n * @param borderColor The border color to apply.\n * @param isActiveResult Whether the element is part of the active search result.\n */\n private _applyStyles(element: HTMLElement, borderColor: string | undefined, isActiveResult: boolean): void {\n if (!element.classList.contains('xterm-find-result-decoration')) {\n element.classList.add('xterm-find-result-decoration');\n if (borderColor) {\n element.style.outline = `1px solid ${borderColor}`;\n }\n }\n if (isActiveResult) {\n element.classList.add('xterm-find-active-result-decoration');\n }\n }\n\n /**\n * Creates a decoration for the result and applies styles\n * @param result the search result for which to create the decoration\n * @param options the options for the decoration\n * @param isActiveResult whether this is the currently active result\n * @returns the decorations or undefined if the marker has already been disposed of\n */\n private _createResultDecorations(result: ISearchResult, options: ISearchDecorationOptions, isActiveResult: boolean): IDecoration[] | undefined {\n // Gather decoration ranges for this match as it could wrap\n const decorationRanges: [number, number, number][] = [];\n let currentCol = result.col;\n let remainingSize = result.size;\n let markerOffset = -this._terminal.buffer.active.baseY - this._terminal.buffer.active.cursorY + result.row;\n while (remainingSize > 0) {\n const amountThisRow = Math.min(this._terminal.cols - currentCol, remainingSize);\n decorationRanges.push([markerOffset, currentCol, amountThisRow]);\n currentCol = 0;\n remainingSize -= amountThisRow;\n markerOffset++;\n }\n\n // Create the decorations\n const decorations: IDecoration[] = [];\n for (const range of decorationRanges) {\n const marker = this._terminal.registerMarker(range[0]);\n const decoration = this._terminal.registerDecoration({\n marker,\n x: range[1],\n width: range[2],\n layer: isActiveResult ? 'top' : 'bottom',\n backgroundColor: isActiveResult ? options.activeMatchBackground : options.matchBackground,\n overviewRulerOptions: this._highlightedLines.has(marker.line) ? undefined : {\n color: isActiveResult ? options.activeMatchColorOverviewRuler : options.matchOverviewRuler,\n position: 'center'\n }\n });\n if (decoration) {\n const disposables: IDisposable[] = [];\n disposables.push(marker);\n disposables.push(decoration.onRender((e) => this._applyStyles(e, isActiveResult ? options.activeMatchBorder : options.matchBorder, false)));\n disposables.push(decoration.onDispose(() => dispose(disposables)));\n decorations.push(decoration);\n }\n }\n\n return decorations.length === 0 ? undefined : decorations;\n }\n}\n\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport type { ISearchOptions } from '@xterm/addon-search';\nimport type { SearchLineCache } from './SearchLineCache';\n\n/**\n * Represents the position to start a search from.\n */\ninterface ISearchPosition {\n startCol: number;\n startRow: number;\n}\n\n/**\n * Represents a search result with its position and content.\n */\nexport interface ISearchResult {\n term: string;\n col: number;\n row: number;\n size: number;\n}\n\n/**\n * Configuration constants for the search engine functionality.\n */\nconst enum Constants {\n /**\n * Characters that are considered non-word characters for search boundary detection. These\n * characters are used to determine word boundaries when performing whole-word searches. Includes\n * common punctuation, symbols, and whitespace characters.\n */\n NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\\\;:\"\\',./<>?'\n}\n\n/**\n * Core search engine that handles finding text within terminal content.\n * This class is responsible for the actual search algorithms and position calculations.\n */\nexport class SearchEngine {\n constructor(\n private readonly _terminal: Terminal,\n private readonly _lineCache: SearchLineCache\n ) {}\n\n /**\n * Find the first occurrence of a term starting from a specific position.\n * @param term The search term.\n * @param startRow The row to start searching from.\n * @param startCol The column to start searching from.\n * @param searchOptions Search options.\n * @returns The search result if found, undefined otherwise.\n */\n public find(term: string, startRow: number, startCol: number, searchOptions?: ISearchOptions): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n if (startCol >= this._terminal.cols) {\n throw new Error(`Invalid col: ${startCol} to search in terminal of ${this._terminal.cols} cols`);\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n if (this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n return result;\n }\n\n /**\n * Find the next occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine incremental behavior.\n * @returns The search result if found, undefined otherwise.\n */\n public findNextWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startCol = 0;\n let startRow = 0;\n if (prevSelectedPos) {\n if (cachedSearchTerm === term) {\n startCol = prevSelectedPos.end.x;\n startRow = prevSelectedPos.end.y;\n } else {\n startCol = prevSelectedPos.start.x;\n startRow = prevSelectedPos.start.y;\n }\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n if (this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n // If we hit the bottom and didn't search from the very top wrap back up\n if (!result && startRow !== 0) {\n for (let y = 0; y < startRow; y++) {\n // Row 0 is never skipped: it can be a continuation whose line start was trimmed from the\n // scrollback, and nothing earlier in this loop has searched it.\n if (y > 0 && this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n\n // If there is only one result, wrap back and return selection if it exists.\n if (!result && prevSelectedPos) {\n searchPosition.startRow = prevSelectedPos.start.y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n }\n\n return result;\n }\n\n /**\n * Find the previous occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine if expansion should occur.\n * @returns The search result if found, undefined otherwise.\n */\n public findPreviousWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startRow = this._terminal.buffer.active.baseY + this._terminal.rows - 1;\n const startCol = this._terminal.cols;\n const isReverseSearch = true;\n\n this._lineCache.initLinesCache();\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n let result: ISearchResult | undefined;\n if (prevSelectedPos) {\n searchPosition.startRow = startRow = prevSelectedPos.start.y;\n searchPosition.startCol = prevSelectedPos.start.x;\n if (cachedSearchTerm !== term) {\n // Try to expand selection to right first.\n result = this._findInLine(term, searchPosition, searchOptions, false);\n if (!result) {\n // If selection was not able to be expanded to the right, then try reverse search\n searchPosition.startRow = startRow = prevSelectedPos.end.y;\n searchPosition.startCol = prevSelectedPos.end.x;\n }\n }\n }\n\n result ??= this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n\n // Search from startRow - 1 to top\n if (!result) {\n searchPosition.startCol = Math.max(searchPosition.startCol, this._terminal.cols);\n for (let y = startRow - 1; y >= 0; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n // If we hit the top and didn't search from the very bottom wrap back down\n if (!result && startRow !== (this._terminal.buffer.active.baseY + this._terminal.rows - 1)) {\n for (let y = (this._terminal.buffer.active.baseY + this._terminal.rows - 1); y >= startRow; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n\n return result;\n }\n\n /**\n * A found substring is a whole word if it doesn't have an alphanumeric character directly\n * adjacent to it.\n * @param searchIndex starting index of the potential whole word substring\n * @param line entire string in which the potential whole word was found\n * @param term the substring that starts at searchIndex\n */\n private _isWholeWord(searchIndex: number, line: string, term: string): boolean {\n return ((searchIndex === 0) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex - 1]))) &&\n (((searchIndex + term.length) === line.length) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex + term.length])));\n }\n\n /** `_isWholeWord` gated on the option, so a rejected hit can be stepped past instead of ending the scan. */\n private _satisfiesWholeWord(searchIndex: number, line: string, term: string, searchOptions: ISearchOptions): boolean {\n return !searchOptions.wholeWord || this._isWholeWord(searchIndex, line, term);\n }\n\n /**\n * Whether an earlier `_findInLine` in this same call already scanned this row's line from an\n * equal or lower offset, which makes rescanning it pure O(rows^2) work on one long line. Sound\n * for every option because `_findInLine` returns the first accepted match at or after its\n * offset, which is monotone in that offset. Only valid once such a search has happened — the\n * wrap-around loop starts at row 0, whose line start may have been trimmed from the scrollback.\n */\n private _isRowCoveredByEarlierSearch(row: number): boolean {\n return this._terminal.buffer.active.getLine(row)?.isWrapped === true;\n }\n\n /**\n * Searches a line for a search term. Takes the provided terminal line and searches the text line,\n * which may contain subsequent terminal lines if the text is wrapped. If the provided line number\n * is part of a wrapped text line that started on an earlier line then it is skipped since it will\n * be properly searched when the terminal line that the text starts on is searched.\n * @param term The search term.\n * @param searchPosition The position to start the search.\n * @param searchOptions Search options.\n * @param isReverseSearch Whether the search should start from the right side of the terminal and\n * search to the left.\n * @returns The search result if it was found.\n */\n private _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {\n // Ignore wrapped lines, only consider on unwrapped line (first row of command string).\n if (isReverseSearch) {\n // Reverse search never rewinds: its caller carries startCol down the rows of the line. Row 0\n // is searched even when wrapped, since its line start may have been trimmed from the scrollback.\n if (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {\n searchPosition.startCol += this._terminal.cols;\n return;\n }\n } else {\n // A loop rather than recursion: one frame per wrapped row overflows the stack on a line long\n // enough to fill the scrollback. Bounded at row 0 because after a reflow the buffer's ring\n // holds stale entries at negative indices, so `getLine(-1)` answers with a wrapped line.\n while (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {\n searchPosition.startRow--;\n searchPosition.startCol += this._terminal.cols;\n }\n }\n const row = searchPosition.startRow;\n const col = searchPosition.startCol;\n\n let cache = this._lineCache.getLineFromCache(row);\n if (!cache) {\n cache = this._lineCache.translateBufferLineToStringWithWrap(row, true);\n this._lineCache.setLineInCache(row, cache);\n }\n const [stringLine, offsets] = cache;\n\n const offset = this._bufferColsToStringOffset(row, col, offsets);\n let searchTerm = term;\n let searchStringLine = stringLine;\n if (!searchOptions.regex) {\n searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();\n searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();\n }\n\n let resultIndex = -1;\n if (searchOptions.regex) {\n const searchRegex = RegExp(searchTerm, searchOptions.caseSensitive ? 'g' : 'gi');\n let foundTerm: RegExpExecArray | null;\n if (isReverseSearch) {\n // This loop will get the resultIndex of the _last_ regex match in the range 0..offset\n while (foundTerm = searchRegex.exec(searchStringLine.slice(0, offset))) {\n const matchIndex = searchRegex.lastIndex - foundTerm[0].length;\n if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {\n resultIndex = matchIndex;\n term = foundTerm[0];\n }\n searchRegex.lastIndex = matchIndex + 1;\n }\n } else {\n // Driven over the whole line from `offset` rather than over `slice(offset)`: a slice\n // re-anchors ^ and \\b at whatever column the row happened to wrap at, and only\n // first-accepted-match-at-or-after-offset is monotone in `offset`, which is what lets\n // `_isRowCoveredByEarlierSearch` skip a wrapped row an earlier scan already covered.\n searchRegex.lastIndex = offset;\n while (foundTerm = searchRegex.exec(searchStringLine)) {\n const matchIndex = searchRegex.lastIndex - foundTerm[0].length;\n if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {\n resultIndex = matchIndex;\n term = foundTerm[0];\n break;\n }\n // A zero-length or rejected match would otherwise repeat forever.\n searchRegex.lastIndex = matchIndex + 1;\n }\n }\n } else if (isReverseSearch) {\n let matchIndex = offset - searchTerm.length >= 0 ? searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length) : -1;\n // `lastIndexOf` clamps a negative fromIndex to 0, so index 0 has to end the walk.\n while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {\n matchIndex = matchIndex > 0 ? searchStringLine.lastIndexOf(searchTerm, matchIndex - 1) : -1;\n }\n resultIndex = matchIndex;\n } else {\n let matchIndex = searchStringLine.indexOf(searchTerm, offset);\n while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {\n matchIndex = searchStringLine.indexOf(searchTerm, matchIndex + 1);\n }\n resultIndex = matchIndex;\n }\n\n if (resultIndex >= 0) {\n // Adjust the row number and search index if needed since a \"line\" of text can span multiple\n // rows\n let startRowOffset = 0;\n while (startRowOffset < offsets.length - 1 && resultIndex >= offsets[startRowOffset + 1]) {\n startRowOffset++;\n }\n let endRowOffset = startRowOffset;\n while (endRowOffset < offsets.length - 1 && resultIndex + term.length >= offsets[endRowOffset + 1]) {\n endRowOffset++;\n }\n const startColOffset = resultIndex - offsets[startRowOffset];\n const endColOffset = resultIndex + term.length - offsets[endRowOffset];\n const startColIndex = this._stringLengthToBufferSize(row + startRowOffset, startColOffset);\n const endColIndex = this._stringLengthToBufferSize(row + endRowOffset, endColOffset);\n const size = endColIndex - startColIndex + this._terminal.cols * (endRowOffset - startRowOffset);\n\n return {\n term,\n col: startColIndex,\n row: row + startRowOffset,\n size\n };\n }\n }\n\n private _stringLengthToBufferSize(row: number, offset: number): number {\n const line = this._terminal.buffer.active.getLine(row);\n if (!line) {\n return 0;\n }\n for (let i = 0; i < offset; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n // Adjust the searchIndex to normalize emoji into single chars\n const char = cell.getChars();\n if (char.length > 1) {\n offset -= char.length - 1;\n }\n // Adjust the searchIndex for empty characters following wide unicode\n // chars (eg. CJK)\n const nextCell = line.getCell(i + 1);\n if (nextCell && nextCell.getWidth() === 0) {\n offset++;\n }\n }\n return offset;\n }\n\n /**\n * `cols` counts from the start of the logical line, so summing the cells of every row before the\n * resume point costs O(line) per call and the highlight-all pass makes one call per match.\n * `lineOffsets` already holds the string offset each wrapped row starts at — the same map used\n * above to turn a match index back into a row — so only the last, partial row needs cells. It is\n * also the map the row a match lands on is read from, which the cell sum disagreed with by one\n * for a row whose trailing cell is the null placeholder of a wide character that wrapped.\n */\n private _bufferColsToStringOffset(startRow: number, cols: number, lineOffsets: number[]): number {\n const rowsBack = Math.min(Math.floor(cols / this._terminal.cols), lineOffsets.length - 1);\n let offset = lineOffsets[rowsBack];\n const line = this._terminal.buffer.active.getLine(startRow + rowsBack);\n if (line) {\n const colsInRow = Math.min(cols - rowsBack * this._terminal.cols, this._terminal.cols);\n for (let i = 0; i < colsInRow; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n if (cell.getWidth()) {\n // Treat null characters as whitespace to align with the translateToString API\n offset += cell.getCode() === 0 ? 1 : cell.getChars().length;\n }\n }\n }\n return offset;\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\n\nexport type LineCacheEntry = [\n /**\n * The string representation of a line (as opposed to the buffer cell representation).\n */\n lineAsString: string,\n /**\n * The offsets where each line starts when the entry describes a wrapped line.\n */\n lineOffsets: number[]\n];\n\n/**\n * Configuration constants for the search line cache functionality.\n */\nconst enum Constants {\n /**\n * Time-to-live for cached search results in milliseconds. After this duration, cached search\n * results will be invalidated to ensure they remain consistent with terminal content changes.\n */\n LINES_CACHE_TIME_TO_LIVE = 15000\n}\n\nexport class SearchLineCache extends Disposable {\n /**\n * translateBufferLineToStringWithWrap is a fairly expensive call.\n * We memoize the calls into an array that has a time based ttl.\n * _linesCache is also invalidated when the terminal cursor moves.\n */\n private _linesCache: LineCacheEntry[] | undefined;\n private _linesCacheTimeout = this._register(new MutableDisposable());\n private _linesCacheDisposables = this._register(new MutableDisposable());\n // Track access to avoid recreating a timeout on every init call which occurs once per search\n // result (findNext/findPrevious -> _highlightAllMatches -> find loop).\n private _lastAccessTimestamp = 0;\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this._destroyLinesCache()));\n }\n\n /**\n * Sets up a line cache with a ttl\n */\n public initLinesCache(): void {\n if (!this._linesCache) {\n this._linesCache = new Array(this._terminal.buffer.active.length);\n this._linesCacheDisposables.value = combinedDisposable(\n this._terminal.onLineFeed(() => this._destroyLinesCache()),\n this._terminal.onCursorMove(() => this._destroyLinesCache()),\n this._terminal.onResize(() => this._destroyLinesCache())\n );\n }\n\n this._lastAccessTimestamp = Date.now();\n if (!this._linesCacheTimeout.value) {\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE);\n }\n }\n\n private _destroyLinesCache(): void {\n this._linesCache = undefined;\n this._lastAccessTimestamp = 0;\n this._linesCacheDisposables.clear();\n this._linesCacheTimeout.clear();\n }\n\n private _scheduleLinesCacheTimeout(delay: number): void {\n this._linesCacheTimeout.value = disposableTimeout(() => {\n if (!this._linesCache) {\n return;\n }\n const now = Date.now();\n const elapsed = now - this._lastAccessTimestamp;\n if (elapsed >= Constants.LINES_CACHE_TIME_TO_LIVE) {\n this._destroyLinesCache();\n return;\n }\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE - elapsed);\n }, delay);\n }\n\n public getLineFromCache(row: number): LineCacheEntry | undefined {\n return this._linesCache?.[row];\n }\n\n public setLineInCache(row: number, entry: LineCacheEntry): void {\n if (this._linesCache) {\n this._linesCache[row] = entry;\n }\n }\n\n /**\n * Translates a buffer line to a string, including subsequent lines if they are wraps.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n */\n public translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean): LineCacheEntry {\n const strings = [];\n const lineOffsets = [0];\n // A single line longer than the whole scrollback leaves every buffer row wrapped, and the\n // buffer's ring answers an out-of-range row by cycling back to the start, so an unbounded walk\n // never reaches an unwrapped line.\n const bufferLength = this._terminal.buffer.active.length;\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (line) {\n const nextLine = lineIndex + 1 < bufferLength ? this._terminal.buffer.active.getLine(lineIndex + 1) : undefined;\n const lineWrapsToNext = nextLine ? nextLine.isWrapped : false;\n let string = line.translateToString(!lineWrapsToNext && trimRight);\n if (lineWrapsToNext && nextLine) {\n const lastCell = line.getCell(line.length - 1);\n const lastCellIsNull = lastCell && lastCell.getCode() === 0 && lastCell.getWidth() === 1;\n // a wide character wrapped to the next line\n if (lastCellIsNull && nextLine.getCell(0)?.getWidth() === 2) {\n string = string.slice(0, -1);\n }\n }\n strings.push(string);\n if (lineWrapsToNext) {\n lineOffsets.push(lineOffsets[lineOffsets.length - 1] + string.length);\n } else {\n break;\n }\n lineIndex++;\n line = nextLine;\n }\n return [strings.join(''), lineOffsets];\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchResultChangeEvent } from '@xterm/addon-search';\nimport type { IDisposable } from '@xterm/xterm';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a currently selected decoration.\n */\ninterface ISelectedDecoration extends IDisposable {\n match: ISearchResult;\n}\n\n/**\n * Tracks search results, manages result indexing, and fires events when results change.\n * This class provides centralized management of search result state and notifications.\n */\nexport class SearchResultTracker extends Disposable {\n private _searchResults: ISearchResult[] = [];\n private _selectedDecoration: ISelectedDecoration | undefined;\n\n private readonly _onDidChangeResults = this._register(new Emitter<ISearchResultChangeEvent>());\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> { return this._onDidChangeResults.event; }\n\n /**\n * Gets the current search results.\n */\n public get searchResults(): ReadonlyArray<ISearchResult> {\n return this._searchResults;\n }\n\n /**\n * Gets the currently selected decoration.\n */\n public get selectedDecoration(): ISelectedDecoration | undefined {\n return this._selectedDecoration;\n }\n\n /**\n * Sets the currently selected decoration.\n */\n public set selectedDecoration(decoration: ISelectedDecoration | undefined) {\n this._selectedDecoration = decoration;\n }\n\n /**\n * Updates the search results with a new set of results.\n * @param results The new search results.\n * @param maxResults The maximum number of results to track.\n */\n public updateResults(results: ISearchResult[], maxResults: number): void {\n this._searchResults = results.slice(0, maxResults);\n }\n\n /**\n * Clears all search results.\n */\n public clearResults(): void {\n this._searchResults = [];\n }\n\n /**\n * Clears the selected decoration.\n */\n public clearSelectedDecoration(): void {\n if (this._selectedDecoration) {\n this._selectedDecoration.dispose();\n this._selectedDecoration = undefined;\n }\n }\n\n /**\n * Finds the index of a result in the current results array.\n * @param result The result to find.\n * @returns The index of the result, or -1 if not found.\n */\n public findResultIndex(result: ISearchResult): number {\n for (let i = 0; i < this._searchResults.length; i++) {\n const match = this._searchResults[i];\n if (match.row === result.row && match.col === result.col && match.size === result.size) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Fires a result change event with the current state.\n * @param hasDecorations Whether decorations are enabled.\n */\n public fireResultsChanged(hasDecorations: boolean): void {\n if (!hasDecorations) {\n return;\n }\n\n let resultIndex = -1;\n if (this._selectedDecoration) {\n resultIndex = this.findResultIndex(this._selectedDecoration.match);\n }\n\n this._onDidChangeResults.fire({\n resultIndex,\n resultCount: this._searchResults.length\n });\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this.clearSelectedDecoration();\n this.clearResults();\n }\n}\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchOptions } from '@xterm/addon-search';\n\n/**\n * Manages search state including cached search terms, options tracking, and validation.\n * This class provides a centralized way to handle search state consistency and option changes.\n */\nexport class SearchState {\n private _cachedSearchTerm: string | undefined;\n private _lastSearchOptions: ISearchOptions | undefined;\n\n /**\n * Gets the currently cached search term.\n */\n public get cachedSearchTerm(): string | undefined {\n return this._cachedSearchTerm;\n }\n\n /**\n * Sets the cached search term.\n */\n public set cachedSearchTerm(term: string | undefined) {\n this._cachedSearchTerm = term;\n }\n\n /**\n * Gets the last search options used.\n */\n public get lastSearchOptions(): ISearchOptions | undefined {\n return this._lastSearchOptions;\n }\n\n /**\n * Sets the last search options used.\n */\n public set lastSearchOptions(options: ISearchOptions | undefined) {\n this._lastSearchOptions = options;\n }\n\n /**\n * Validates a search term to ensure it's not empty or invalid.\n * @param term The search term to validate.\n * @returns true if the term is valid for searching.\n */\n public isValidSearchTerm(term: string): boolean {\n return !!(term && term.length > 0);\n }\n\n /**\n * Determines if search options have changed compared to the last search.\n * @param newOptions The new search options to compare.\n * @returns true if the options have changed.\n */\n public didOptionsChange(newOptions?: ISearchOptions): boolean {\n if (!this._lastSearchOptions) {\n return true;\n }\n if (!newOptions) {\n return false;\n }\n if (this._lastSearchOptions.caseSensitive !== newOptions.caseSensitive) {\n return true;\n }\n if (this._lastSearchOptions.regex !== newOptions.regex) {\n return true;\n }\n if (this._lastSearchOptions.wholeWord !== newOptions.wholeWord) {\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a new search should trigger highlighting updates.\n * @param term The search term.\n * @param options The search options.\n * @returns true if highlighting should be updated.\n */\n public shouldUpdateHighlighting(term: string, options?: ISearchOptions): boolean {\n if (!options?.decorations) {\n return false;\n }\n return this._cachedSearchTerm === undefined ||\n term !== this._cachedSearchTerm ||\n this.didOptionsChange(options);\n }\n\n /**\n * Clears the cached search term.\n */\n public clearCachedTerm(): void {\n this._cachedSearchTerm = undefined;\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this._cachedSearchTerm = undefined;\n this._lastSearchOptions = undefined;\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';\nimport type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\nimport { SearchLineCache } from './SearchLineCache';\nimport { SearchState } from './SearchState';\nimport { SearchEngine, type ISearchResult } from './SearchEngine';\nimport { DecorationManager } from './DecorationManager';\nimport { SearchResultTracker } from './SearchResultTracker';\n\ninterface IInternalSearchOptions {\n noScroll: boolean;\n}\n\n/**\n * Configuration constants for the search addon functionality.\n */\nconst enum Constants {\n /**\n * Default maximum number of search results to highlight simultaneously. This limit prevents\n * performance degradation when searching for very common terms that would result in excessive\n * highlighting decorations.\n */\n DEFAULT_HIGHLIGHT_LIMIT = 1000\n}\n\nexport class SearchAddon extends Disposable implements ITerminalAddon, ISearchApi {\n private _terminal: Terminal | undefined;\n private _highlightLimit: number;\n private _highlightTimeout = this._register(new MutableDisposable<IDisposable>());\n private _lineCache = this._register(new MutableDisposable<SearchLineCache>());\n\n // Component instances\n private _state = new SearchState();\n private _engine: SearchEngine | undefined;\n private _decorationManager: DecorationManager | undefined;\n private _resultTracker = this._register(new SearchResultTracker());\n\n private readonly _onAfterSearch = this._register(new Emitter<void>());\n public readonly onAfterSearch = this._onAfterSearch.event;\n private readonly _onBeforeSearch = this._register(new Emitter<void>());\n public readonly onBeforeSearch = this._onBeforeSearch.event;\n\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> {\n return this._resultTracker.onDidChangeResults;\n }\n\n constructor(options?: Partial<ISearchAddonOptions>) {\n super();\n\n this._highlightLimit = options?.highlightLimit ?? Constants.DEFAULT_HIGHLIGHT_LIMIT;\n }\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n this._lineCache.value = new SearchLineCache(terminal);\n this._engine = new SearchEngine(terminal, this._lineCache.value);\n this._decorationManager = new DecorationManager(terminal);\n this._register(this._terminal.onWriteParsed(() => this._updateMatches()));\n this._register(this._terminal.onResize(() => this._updateMatches()));\n this._register(toDisposable(() => this.clearDecorations()));\n }\n\n private _updateMatches(): void {\n this._highlightTimeout.clear();\n if (this._state.cachedSearchTerm && this._state.lastSearchOptions?.decorations) {\n this._highlightTimeout.value = disposableTimeout(() => {\n const term = this._state.cachedSearchTerm;\n this._state.clearCachedTerm();\n this.findPrevious(term!, { ...this._state.lastSearchOptions, incremental: true }, { noScroll: true });\n }, 200);\n }\n }\n\n public clearDecorations(retainCachedSearchTerm?: boolean): void {\n this._resultTracker.clearSelectedDecoration();\n this._decorationManager?.clearHighlightDecorations();\n this._resultTracker.clearResults();\n if (!retainCachedSearchTerm) {\n this._state.clearCachedTerm();\n }\n }\n\n public clearActiveDecoration(): void {\n this._resultTracker.clearSelectedDecoration();\n }\n\n /**\n * Find the next instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findNext(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findNextAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _highlightAllMatches(term: string, searchOptions: ISearchOptions): void {\n if (!this._terminal || !this._engine || !this._decorationManager) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n if (!this._state.isValidSearchTerm(term)) {\n this.clearDecorations();\n return;\n }\n\n // new search, clear out the old decorations\n this.clearDecorations(true);\n\n const results: ISearchResult[] = [];\n let prevResult: ISearchResult | undefined = undefined;\n let result = this._engine.find(term, 0, 0, searchOptions);\n\n while (result && (prevResult?.row !== result.row || prevResult?.col !== result.col)) {\n if (results.length >= this._highlightLimit) {\n break;\n }\n prevResult = result;\n results.push(prevResult);\n const cols = this._terminal.cols;\n let nextCol = prevResult.col + prevResult.size;\n let nextRow = prevResult.row;\n if (nextCol >= cols) {\n nextRow += Math.floor(nextCol / cols);\n nextCol = nextCol % cols;\n }\n result = this._engine.find(term, nextRow, nextCol, searchOptions);\n }\n\n this._resultTracker.updateResults(results, this._highlightLimit);\n if (searchOptions.decorations) {\n this._decorationManager.createHighlightDecorations(results, searchOptions.decorations);\n }\n }\n\n private _findNextAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findNextWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Find the previous instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findPrevious(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findPreviousAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _fireResults(searchOptions?: ISearchOptions): void {\n this._resultTracker.fireResultsChanged(!!searchOptions?.decorations);\n }\n\n private _findPreviousAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findPreviousWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Selects and scrolls to a result.\n * @param result The result to select.\n * @returns Whether a result was selected.\n */\n private _selectResult(result: ISearchResult | undefined, options?: ISearchDecorationOptions, noScroll?: boolean): boolean {\n if (!this._terminal || !this._decorationManager) {\n return false;\n }\n\n this._resultTracker.clearSelectedDecoration();\n if (!result) {\n this._terminal.clearSelection();\n return false;\n }\n\n this._terminal.select(result.col, result.row, result.size);\n if (options) {\n const activeDecoration = this._decorationManager.createActiveDecoration(result, options);\n if (activeDecoration) {\n this._resultTracker.selectedDecoration = activeDecoration;\n }\n }\n\n if (!noScroll) {\n // If it is not in the viewport then we scroll else it just gets selected\n if (result.row >= (this._terminal.buffer.active.viewportY + this._terminal.rows) || result.row < this._terminal.buffer.active.viewportY) {\n let scroll = result.row - this._terminal.buffer.active.viewportY;\n scroll -= Math.floor(this._terminal.rows / 2);\n this._terminal.scrollLines(scroll);\n }\n }\n return true;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","millis","Promise","resolve","setTimeout","handler","timeout","store","timer","disposable","dispose","Lifecycle_1","toDisposable","clearTimeout","add","__webpack_require__","constructor","this","_token","_isDisposed","cancel","cancelAndSet","runner","Error","setIfNotSet","_isScheduled","set","queueMicrotask","_disposable","undefined","interval","context","handle","setInterval","clearInterval","EventUtils","_listeners","_disposed","event","_event","listener","thisArgs","disposables","entry","fn","slice","push","result","idx","indexOf","splice","Array","isArray","fire","length","call","listeners","i","len","forward","from","to","e","map","any","events","DisposableStore","runAndSubscribe","initial","arg","d","_disposables","Set","isDisposed","o","clear","Disposable","_store","_register","None","Object","freeze","value","_value","DecorationManager","_terminal","super","_highlightDecorations","_highlightedLines","clearHighlightDecorations","createHighlightDecorations","results","options","match","decorations","_createResultDecorations","decoration","_storeDecoration","createActiveDecoration","marker","line","_applyStyles","element","borderColor","isActiveResult","classList","contains","style","outline","decorationRanges","currentCol","col","remainingSize","size","markerOffset","buffer","active","baseY","cursorY","row","amountThisRow","Math","min","cols","range","registerMarker","registerDecoration","x","width","layer","backgroundColor","activeMatchBackground","matchBackground","overviewRulerOptions","has","color","activeMatchColorOverviewRuler","matchOverviewRuler","position","onRender","activeMatchBorder","matchBorder","onDispose","_lineCache","find","term","startRow","startCol","searchOptions","clearSelection","initLinesCache","searchPosition","_findInLine","y","rows","_isRowCoveredByEarlierSearch","findNextWithSelection","cachedSearchTerm","prevSelectedPos","getSelectionPosition","end","start","findPreviousWithSelection","isReverseSearch","max","_isWholeWord","searchIndex","includes","_satisfiesWholeWord","wholeWord","getLine","isWrapped","cache","getLineFromCache","translateBufferLineToStringWithWrap","setLineInCache","stringLine","offsets","offset","_bufferColsToStringOffset","searchTerm","searchStringLine","regex","caseSensitive","toLowerCase","resultIndex","searchRegex","RegExp","foundTerm","exec","matchIndex","lastIndex","lastIndexOf","startRowOffset","endRowOffset","startColOffset","endColOffset","startColIndex","_stringLengthToBufferSize","cell","getCell","char","getChars","nextCell","getWidth","lineOffsets","rowsBack","floor","colsInRow","getCode","Async_1","SearchLineCache","_linesCacheTimeout","MutableDisposable","_linesCacheDisposables","_lastAccessTimestamp","_destroyLinesCache","_linesCache","combinedDisposable","onLineFeed","onCursorMove","onResize","Date","now","_scheduleLinesCacheTimeout","delay","disposableTimeout","elapsed","lineIndex","trimRight","strings","bufferLength","nextLine","lineWrapsToNext","string","translateToString","lastCell","join","Event_1","SearchResultTracker","_searchResults","_onDidChangeResults","Emitter","onDidChangeResults","searchResults","selectedDecoration","_selectedDecoration","updateResults","maxResults","clearResults","clearSelectedDecoration","findResultIndex","fireResultsChanged","hasDecorations","resultCount","reset","_cachedSearchTerm","lastSearchOptions","_lastSearchOptions","isValidSearchTerm","didOptionsChange","newOptions","shouldUpdateHighlighting","clearCachedTerm","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","SearchLineCache_1","SearchState_1","SearchEngine_1","DecorationManager_1","SearchResultTracker_1","SearchAddon","_resultTracker","_highlightTimeout","_state","SearchState","_onAfterSearch","onAfterSearch","_onBeforeSearch","onBeforeSearch","_highlightLimit","highlightLimit","activate","terminal","_engine","SearchEngine","_decorationManager","onWriteParsed","_updateMatches","clearDecorations","findPrevious","incremental","noScroll","retainCachedSearchTerm","clearActiveDecoration","findNext","internalSearchOptions","_highlightAllMatches","found","_findNextAndSelect","_fireResults","prevResult","nextCol","nextRow","_selectResult","_findPreviousAndSelect","select","activeDecoration","viewportY","scroll","scrollLines"],"sourceRoot":""}
\ No newline at end of file
diff --git a/lib/addon-search.mjs b/lib/addon-search.mjs
index 5cf231a96b56284705711faebe6b0c492f133546..f2b8b804ac733d737a9bff22b4e1d24778a807c8 100644
--- a/lib/addon-search.mjs
+++ b/lib/addon-search.mjs
@@ -14,5 +14,5 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-function _(c){return{dispose:c}}function D(c){if(!c)return c;if(Array.isArray(c)){for(let i of c)i.dispose();return[]}return c.dispose(),c}function E(...c){return _(()=>D(c))}var S=class{constructor(){this._disposables=new Set;this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(i){return this._isDisposed?i.dispose():this._disposables.add(i),i}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(let i of this._disposables)i.dispose();this._disposables.clear()}}clear(){for(let i of this._disposables)i.dispose();this._disposables.clear()}},b=class{constructor(){this._store=new S}dispose(){this._store.dispose()}_register(i){return this._store.add(i)}};b.None=Object.freeze({dispose(){}});var v=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(i){this._isDisposed||i===this._value||(this._value?.dispose(),this._value=i)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}};var I=class{constructor(){this._listeners=[];this._disposed=!1}get event(){return this._event?this._event:(this._event=(i,e,t)=>{if(this._disposed)return _(()=>{});let r={fn:i,thisArgs:e};this._listeners=this._listeners.slice(),this._listeners.push(r);let s=_(()=>{let n=this._listeners.indexOf(r);n!==-1&&(this._listeners=this._listeners.slice(),this._listeners.splice(n,1))});return t&&(Array.isArray(t)?t.push(s):t.add(s)),s},this._event)}fire(i){if(this._disposed||!this._listeners.length)return;if(this._listeners.length===1){this._listeners[0].fn.call(this._listeners[0].thisArgs,i);return}let e=this._listeners;for(let t=0,r=e.length;t<r;++t)e[t].fn.call(e[t].thisArgs,i)}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},W;(r=>{function c(s,n){return s(a=>n.fire(a))}r.forward=c;function i(s,n){return(a,o,l)=>s(h=>a.call(o,n(h)),void 0,l)}r.map=i;function e(...s){return(n,a,o)=>{let l=new S;for(let h of s)l.add(h(p=>n.call(a,p)));return o&&(Array.isArray(o)?o.push(l):o.add(l)),l}}r.any=e;function t(s,n,a){return n(a),s(o=>n(o))}r.runAndSubscribe=t})(W||={});function T(c,i=0,e){let t=setTimeout(()=>{c(),e&&r.dispose()},i),r=_(()=>{clearTimeout(t)});return e?.add(r),r}var C=class extends b{constructor(e){super();this._terminal=e;this._linesCacheTimeout=this._register(new v);this._linesCacheDisposables=this._register(new v);this._lastAccessTimestamp=0;this._register(_(()=>this._destroyLinesCache()))}initLinesCache(){this._linesCache||(this._linesCache=new Array(this._terminal.buffer.active.length),this._linesCacheDisposables.value=E(this._terminal.onLineFeed(()=>this._destroyLinesCache()),this._terminal.onCursorMove(()=>this._destroyLinesCache()),this._terminal.onResize(()=>this._destroyLinesCache()))),this._lastAccessTimestamp=Date.now(),this._linesCacheTimeout.value||this._scheduleLinesCacheTimeout(15e3)}_destroyLinesCache(){this._linesCache=void 0,this._lastAccessTimestamp=0,this._linesCacheDisposables.clear(),this._linesCacheTimeout.clear()}_scheduleLinesCacheTimeout(e){this._linesCacheTimeout.value=T(()=>{if(!this._linesCache)return;let r=Date.now()-this._lastAccessTimestamp;if(r>=15e3){this._destroyLinesCache();return}this._scheduleLinesCacheTimeout(15e3-r)},e)}getLineFromCache(e){return this._linesCache?.[e]}setLineInCache(e,t){this._linesCache&&(this._linesCache[e]=t)}translateBufferLineToStringWithWrap(e,t){let r=[],s=[0],n=this._terminal.buffer.active.getLine(e);for(;n;){let a=this._terminal.buffer.active.getLine(e+1),o=a?a.isWrapped:!1,l=n.translateToString(!o&&t);if(o&&a){let h=n.getCell(n.length-1);h&&h.getCode()===0&&h.getWidth()===1&&a.getCell(0)?.getWidth()===2&&(l=l.slice(0,-1))}if(r.push(l),o)s.push(s[s.length-1]+l.length);else break;e++,n=a}return[r.join(""),s]}};var x=class{get cachedSearchTerm(){return this._cachedSearchTerm}set cachedSearchTerm(i){this._cachedSearchTerm=i}get lastSearchOptions(){return this._lastSearchOptions}set lastSearchOptions(i){this._lastSearchOptions=i}isValidSearchTerm(i){return!!(i&&i.length>0)}didOptionsChange(i){return this._lastSearchOptions?i?this._lastSearchOptions.caseSensitive!==i.caseSensitive||this._lastSearchOptions.regex!==i.regex||this._lastSearchOptions.wholeWord!==i.wholeWord:!1:!0}shouldUpdateHighlighting(i,e){return e?.decorations?this._cachedSearchTerm===void 0||i!==this._cachedSearchTerm||this.didOptionsChange(e):!1}clearCachedTerm(){this._cachedSearchTerm=void 0}reset(){this._cachedSearchTerm=void 0,this._lastSearchOptions=void 0}};var R=class{constructor(i,e){this._terminal=i;this._lineCache=e}find(i,e,t,r){if(!i||i.length===0){this._terminal.clearSelection();return}if(t>=this._terminal.cols)throw new Error(`Invalid col: ${t} to search in terminal of ${this._terminal.cols} cols`);this._lineCache.initLinesCache();let s={startRow:e,startCol:t},n=this._findInLine(i,s,r);if(!n)for(let a=e+1;a<this._terminal.buffer.active.baseY+this._terminal.rows&&(s.startRow=a,s.startCol=0,n=this._findInLine(i,s,r),!n);a++);return n}findNextWithSelection(i,e,t){if(!i||i.length===0){this._terminal.clearSelection();return}let r=this._terminal.getSelectionPosition();this._terminal.clearSelection();let s=0,n=0;r&&(t===i?(s=r.end.x,n=r.end.y):(s=r.start.x,n=r.start.y)),this._lineCache.initLinesCache();let a={startRow:n,startCol:s},o=this._findInLine(i,a,e);if(!o)for(let l=n+1;l<this._terminal.buffer.active.baseY+this._terminal.rows&&(a.startRow=l,a.startCol=0,o=this._findInLine(i,a,e),!o);l++);if(!o&&n!==0)for(let l=0;l<n&&(a.startRow=l,a.startCol=0,o=this._findInLine(i,a,e),!o);l++);return!o&&r&&(a.startRow=r.start.y,a.startCol=0,o=this._findInLine(i,a,e)),o}findPreviousWithSelection(i,e,t){if(!i||i.length===0){this._terminal.clearSelection();return}let r=this._terminal.getSelectionPosition();this._terminal.clearSelection();let s=this._terminal.buffer.active.baseY+this._terminal.rows-1,n=this._terminal.cols,a=!0;this._lineCache.initLinesCache();let o={startRow:s,startCol:n},l;if(r&&(o.startRow=s=r.start.y,o.startCol=r.start.x,t!==i&&(l=this._findInLine(i,o,e,!1),l||(o.startRow=s=r.end.y,o.startCol=r.end.x))),l??=this._findInLine(i,o,e,a),!l){o.startCol=Math.max(o.startCol,this._terminal.cols);for(let h=s-1;h>=0&&(o.startRow=h,l=this._findInLine(i,o,e,a),!l);h--);}if(!l&&s!==this._terminal.buffer.active.baseY+this._terminal.rows-1)for(let h=this._terminal.buffer.active.baseY+this._terminal.rows-1;h>=s&&(o.startRow=h,l=this._findInLine(i,o,e,a),!l);h--);return l}_isWholeWord(i,e,t){return(i===0||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(e[i-1]))&&(i+t.length===e.length||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(e[i+t.length]))}_findInLine(i,e,t={},r=!1){let s=e.startRow,n=e.startCol;if(this._terminal.buffer.active.getLine(s)?.isWrapped){if(r){e.startCol+=this._terminal.cols;return}return e.startRow--,e.startCol+=this._terminal.cols,this._findInLine(i,e,t)}let o=this._lineCache.getLineFromCache(s);o||(o=this._lineCache.translateBufferLineToStringWithWrap(s,!0),this._lineCache.setLineInCache(s,o));let[l,h]=o,p=this._bufferColsToStringOffset(s,n),m=i,g=l;t.regex||(m=t.caseSensitive?i:i.toLowerCase(),g=t.caseSensitive?l:l.toLowerCase());let f=-1;if(t.regex){let u=RegExp(m,t.caseSensitive?"g":"gi"),d;if(r)for(;d=u.exec(g.slice(0,p));)f=u.lastIndex-d[0].length,i=d[0],u.lastIndex-=i.length-1;else d=u.exec(g.slice(p)),d&&d[0].length>0&&(f=p+(u.lastIndex-d[0].length),i=d[0])}else r?p-m.length>=0&&(f=g.lastIndexOf(m,p-m.length)):f=g.indexOf(m,p);if(f>=0){if(t.wholeWord&&!this._isWholeWord(f,g,i))return;let u=0;for(;u<h.length-1&&f>=h[u+1];)u++;let d=u;for(;d<h.length-1&&f+i.length>=h[d+1];)d++;let O=f-h[u],k=f+i.length-h[d],y=this._stringLengthToBufferSize(s+u,O),M=this._stringLengthToBufferSize(s+d,k)-y+this._terminal.cols*(d-u);return{term:i,col:y,row:s+u,size:M}}}_stringLengthToBufferSize(i,e){let t=this._terminal.buffer.active.getLine(i);if(!t)return 0;for(let r=0;r<e;r++){let s=t.getCell(r);if(!s)break;let n=s.getChars();n.length>1&&(e-=n.length-1);let a=t.getCell(r+1);a&&a.getWidth()===0&&e++}return e}_bufferColsToStringOffset(i,e){let t=i,r=0,s=this._terminal.buffer.active.getLine(t);for(;e>0&&s;){for(let n=0;n<e&&n<this._terminal.cols;n++){let a=s.getCell(n);if(!a)break;a.getWidth()&&(r+=a.getCode()===0?1:a.getChars().length)}if(t++,s=this._terminal.buffer.active.getLine(t),s&&!s.isWrapped)break;e-=this._terminal.cols}return r}};var w=class extends b{constructor(e){super();this._terminal=e;this._highlightDecorations=[];this._highlightedLines=new Set;this._register(_(()=>this.clearHighlightDecorations()))}createHighlightDecorations(e,t){this.clearHighlightDecorations();for(let r of e){let s=this._createResultDecorations(r,t,!1);if(s)for(let n of s)this._storeDecoration(n,r)}}createActiveDecoration(e,t){let r=this._createResultDecorations(e,t,!0);if(r)return{decorations:r,match:e,dispose(){D(r)}}}clearHighlightDecorations(){D(this._highlightDecorations),this._highlightDecorations=[],this._highlightedLines.clear()}_storeDecoration(e,t){this._highlightedLines.add(e.marker.line),this._highlightDecorations.push({decoration:e,match:t,dispose(){e.dispose()}})}_applyStyles(e,t,r){e.classList.contains("xterm-find-result-decoration")||(e.classList.add("xterm-find-result-decoration"),t&&(e.style.outline=`1px solid ${t}`)),r&&e.classList.add("xterm-find-active-result-decoration")}_createResultDecorations(e,t,r){let s=[],n=e.col,a=e.size,o=-this._terminal.buffer.active.baseY-this._terminal.buffer.active.cursorY+e.row;for(;a>0;){let h=Math.min(this._terminal.cols-n,a);s.push([o,n,h]),n=0,a-=h,o++}let l=[];for(let h of s){let p=this._terminal.registerMarker(h[0]),m=this._terminal.registerDecoration({marker:p,x:h[1],width:h[2],layer:r?"top":"bottom",backgroundColor:r?t.activeMatchBackground:t.matchBackground,overviewRulerOptions:this._highlightedLines.has(p.line)?void 0:{color:r?t.activeMatchColorOverviewRuler:t.matchOverviewRuler,position:"center"}});if(m){let g=[];g.push(p),g.push(m.onRender(f=>this._applyStyles(f,r?t.activeMatchBorder:t.matchBorder,!1))),g.push(m.onDispose(()=>D(g))),l.push(m)}}return l.length===0?void 0:l}};var L=class extends b{constructor(){super(...arguments);this._searchResults=[];this._onDidChangeResults=this._register(new I)}get onDidChangeResults(){return this._onDidChangeResults.event}get searchResults(){return this._searchResults}get selectedDecoration(){return this._selectedDecoration}set selectedDecoration(e){this._selectedDecoration=e}updateResults(e,t){this._searchResults=e.slice(0,t)}clearResults(){this._searchResults=[]}clearSelectedDecoration(){this._selectedDecoration&&(this._selectedDecoration.dispose(),this._selectedDecoration=void 0)}findResultIndex(e){for(let t=0;t<this._searchResults.length;t++){let r=this._searchResults[t];if(r.row===e.row&&r.col===e.col&&r.size===e.size)return t}return-1}fireResultsChanged(e){if(!e)return;let t=-1;this._selectedDecoration&&(t=this.findResultIndex(this._selectedDecoration.match)),this._onDidChangeResults.fire({resultIndex:t,resultCount:this._searchResults.length})}reset(){this.clearSelectedDecoration(),this.clearResults()}};var A=class extends b{constructor(e){super();this._highlightTimeout=this._register(new v);this._lineCache=this._register(new v);this._state=new x;this._resultTracker=this._register(new L);this._onAfterSearch=this._register(new I);this.onAfterSearch=this._onAfterSearch.event;this._onBeforeSearch=this._register(new I);this.onBeforeSearch=this._onBeforeSearch.event;this._highlightLimit=e?.highlightLimit??1e3}get onDidChangeResults(){return this._resultTracker.onDidChangeResults}activate(e){this._terminal=e,this._lineCache.value=new C(e),this._engine=new R(e,this._lineCache.value),this._decorationManager=new w(e),this._register(this._terminal.onWriteParsed(()=>this._updateMatches())),this._register(this._terminal.onResize(()=>this._updateMatches())),this._register(_(()=>this.clearDecorations()))}_updateMatches(){this._highlightTimeout.clear(),this._state.cachedSearchTerm&&this._state.lastSearchOptions?.decorations&&(this._highlightTimeout.value=T(()=>{let e=this._state.cachedSearchTerm;this._state.clearCachedTerm(),this.findPrevious(e,{...this._state.lastSearchOptions,incremental:!0},{noScroll:!0})},200))}clearDecorations(e){this._resultTracker.clearSelectedDecoration(),this._decorationManager?.clearHighlightDecorations(),this._resultTracker.clearResults(),e||this._state.clearCachedTerm()}clearActiveDecoration(){this._resultTracker.clearSelectedDecoration()}findNext(e,t,r){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);let s=this._findNextAndSelect(e,t,r);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),s}_highlightAllMatches(e,t){if(!this._terminal||!this._engine||!this._decorationManager)throw new Error("Cannot use addon until it has been loaded");if(!this._state.isValidSearchTerm(e)){this.clearDecorations();return}this.clearDecorations(!0);let r=[],s,n=this._engine.find(e,0,0,t);for(;n&&(s?.row!==n.row||s?.col!==n.col)&&!(r.length>=this._highlightLimit);){s=n,r.push(s);let a=this._terminal.cols,o=s.col+s.size,l=s.row;o>=a&&(l+=Math.floor(o/a),o=o%a),n=this._engine.find(e,l,o,t)}this._resultTracker.updateResults(r,this._highlightLimit),t.decorations&&this._decorationManager.createHighlightDecorations(r,t.decorations)}_findNextAndSelect(e,t,r){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;let s=this._engine.findNextWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(s,t?.decorations,r?.noScroll)}findPrevious(e,t,r){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);let s=this._findPreviousAndSelect(e,t,r);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),s}_fireResults(e){this._resultTracker.fireResultsChanged(!!e?.decorations)}_findPreviousAndSelect(e,t,r){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;let s=this._engine.findPreviousWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(s,t?.decorations,r?.noScroll)}_selectResult(e,t,r){if(!this._terminal||!this._decorationManager)return!1;if(this._resultTracker.clearSelectedDecoration(),!e)return this._terminal.clearSelection(),!1;if(this._terminal.select(e.col,e.row,e.size),t){let s=this._decorationManager.createActiveDecoration(e,t);s&&(this._resultTracker.selectedDecoration=s)}if(!r&&(e.row>=this._terminal.buffer.active.viewportY+this._terminal.rows||e.row<this._terminal.buffer.active.viewportY)){let s=e.row-this._terminal.buffer.active.viewportY;s-=Math.floor(this._terminal.rows/2),this._terminal.scrollLines(s)}return!0}};export{A as SearchAddon};
+function m(d){return{dispose:d}}function D(d){if(!d)return d;if(Array.isArray(d)){for(let i of d)i.dispose();return[]}return d.dispose(),d}function E(...d){return m(()=>D(d))}var S=class{constructor(){this._disposables=new Set;this._isDisposed=!1}get isDisposed(){return this._isDisposed}add(i){return this._isDisposed?i.dispose():this._disposables.add(i),i}dispose(){if(!this._isDisposed){this._isDisposed=!0;for(let i of this._disposables)i.dispose();this._disposables.clear()}}clear(){for(let i of this._disposables)i.dispose();this._disposables.clear()}},g=class{constructor(){this._store=new S}dispose(){this._store.dispose()}_register(i){return this._store.add(i)}};g.None=Object.freeze({dispose(){}});var v=class{constructor(){this._isDisposed=!1}get value(){return this._isDisposed?void 0:this._value}set value(i){this._isDisposed||i===this._value||(this._value?.dispose(),this._value=i)}clear(){this.value=void 0}dispose(){this._isDisposed=!0,this._value?.dispose(),this._value=void 0}};var I=class{constructor(){this._listeners=[];this._disposed=!1}get event(){return this._event?this._event:(this._event=(i,e,t)=>{if(this._disposed)return m(()=>{});let s={fn:i,thisArgs:e};this._listeners=this._listeners.slice(),this._listeners.push(s);let r=m(()=>{let l=this._listeners.indexOf(s);l!==-1&&(this._listeners=this._listeners.slice(),this._listeners.splice(l,1))});return t&&(Array.isArray(t)?t.push(r):t.add(r)),r},this._event)}fire(i){if(this._disposed||!this._listeners.length)return;if(this._listeners.length===1){this._listeners[0].fn.call(this._listeners[0].thisArgs,i);return}let e=this._listeners;for(let t=0,s=e.length;t<s;++t)e[t].fn.call(e[t].thisArgs,i)}dispose(){this._disposed||(this._disposed=!0,this._listeners.length=0)}},k;(s=>{function d(r,l){return r(o=>l.fire(o))}s.forward=d;function i(r,l){return(o,n,a)=>r(c=>o.call(n,l(c)),void 0,a)}s.map=i;function e(...r){return(l,o,n)=>{let a=new S;for(let c of r)a.add(c(u=>l.call(o,u)));return n&&(Array.isArray(n)?n.push(a):n.add(a)),a}}s.any=e;function t(r,l,o){return l(o),r(n=>l(n))}s.runAndSubscribe=t})(k||={});function T(d,i=0,e){let t=setTimeout(()=>{d(),e&&s.dispose()},i),s=m(()=>{clearTimeout(t)});return e?.add(s),s}var C=class extends g{constructor(e){super();this._terminal=e;this._linesCacheTimeout=this._register(new v);this._linesCacheDisposables=this._register(new v);this._lastAccessTimestamp=0;this._register(m(()=>this._destroyLinesCache()))}initLinesCache(){this._linesCache||(this._linesCache=new Array(this._terminal.buffer.active.length),this._linesCacheDisposables.value=E(this._terminal.onLineFeed(()=>this._destroyLinesCache()),this._terminal.onCursorMove(()=>this._destroyLinesCache()),this._terminal.onResize(()=>this._destroyLinesCache()))),this._lastAccessTimestamp=Date.now(),this._linesCacheTimeout.value||this._scheduleLinesCacheTimeout(15e3)}_destroyLinesCache(){this._linesCache=void 0,this._lastAccessTimestamp=0,this._linesCacheDisposables.clear(),this._linesCacheTimeout.clear()}_scheduleLinesCacheTimeout(e){this._linesCacheTimeout.value=T(()=>{if(!this._linesCache)return;let s=Date.now()-this._lastAccessTimestamp;if(s>=15e3){this._destroyLinesCache();return}this._scheduleLinesCacheTimeout(15e3-s)},e)}getLineFromCache(e){return this._linesCache?.[e]}setLineInCache(e,t){this._linesCache&&(this._linesCache[e]=t)}translateBufferLineToStringWithWrap(e,t){let s=[],r=[0],l=this._terminal.buffer.active.length,o=this._terminal.buffer.active.getLine(e);for(;o;){let n=e+1<l?this._terminal.buffer.active.getLine(e+1):void 0,a=n?n.isWrapped:!1,c=o.translateToString(!a&&t);if(a&&n){let u=o.getCell(o.length-1);u&&u.getCode()===0&&u.getWidth()===1&&n.getCell(0)?.getWidth()===2&&(c=c.slice(0,-1))}if(s.push(c),a)r.push(r[r.length-1]+c.length);else break;e++,o=n}return[s.join(""),r]}};var x=class{get cachedSearchTerm(){return this._cachedSearchTerm}set cachedSearchTerm(i){this._cachedSearchTerm=i}get lastSearchOptions(){return this._lastSearchOptions}set lastSearchOptions(i){this._lastSearchOptions=i}isValidSearchTerm(i){return!!(i&&i.length>0)}didOptionsChange(i){return this._lastSearchOptions?i?this._lastSearchOptions.caseSensitive!==i.caseSensitive||this._lastSearchOptions.regex!==i.regex||this._lastSearchOptions.wholeWord!==i.wholeWord:!1:!0}shouldUpdateHighlighting(i,e){return e?.decorations?this._cachedSearchTerm===void 0||i!==this._cachedSearchTerm||this.didOptionsChange(e):!1}clearCachedTerm(){this._cachedSearchTerm=void 0}reset(){this._cachedSearchTerm=void 0,this._lastSearchOptions=void 0}};var w=class{constructor(i,e){this._terminal=i;this._lineCache=e}find(i,e,t,s){if(!i||i.length===0){this._terminal.clearSelection();return}if(t>=this._terminal.cols)throw new Error(`Invalid col: ${t} to search in terminal of ${this._terminal.cols} cols`);this._lineCache.initLinesCache();let r={startRow:e,startCol:t},l=this._findInLine(i,r,s);if(!l)for(let o=e+1;o<this._terminal.buffer.active.baseY+this._terminal.rows&&!(!this._isRowCoveredByEarlierSearch(o)&&(r.startRow=o,r.startCol=0,l=this._findInLine(i,r,s),l));o++);return l}findNextWithSelection(i,e,t){if(!i||i.length===0){this._terminal.clearSelection();return}let s=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=0,l=0;s&&(t===i?(r=s.end.x,l=s.end.y):(r=s.start.x,l=s.start.y)),this._lineCache.initLinesCache();let o={startRow:l,startCol:r},n=this._findInLine(i,o,e);if(!n)for(let a=l+1;a<this._terminal.buffer.active.baseY+this._terminal.rows&&!(!this._isRowCoveredByEarlierSearch(a)&&(o.startRow=a,o.startCol=0,n=this._findInLine(i,o,e),n));a++);if(!n&&l!==0)for(let a=0;a<l&&!(!(a>0&&this._isRowCoveredByEarlierSearch(a))&&(o.startRow=a,o.startCol=0,n=this._findInLine(i,o,e),n));a++);return!n&&s&&(o.startRow=s.start.y,o.startCol=0,n=this._findInLine(i,o,e)),n}findPreviousWithSelection(i,e,t){if(!i||i.length===0){this._terminal.clearSelection();return}let s=this._terminal.getSelectionPosition();this._terminal.clearSelection();let r=this._terminal.buffer.active.baseY+this._terminal.rows-1,l=this._terminal.cols,o=!0;this._lineCache.initLinesCache();let n={startRow:r,startCol:l},a;if(s&&(n.startRow=r=s.start.y,n.startCol=s.start.x,t!==i&&(a=this._findInLine(i,n,e,!1),a||(n.startRow=r=s.end.y,n.startCol=s.end.x))),a??=this._findInLine(i,n,e,o),!a){n.startCol=Math.max(n.startCol,this._terminal.cols);for(let c=r-1;c>=0&&(n.startRow=c,a=this._findInLine(i,n,e,o),!a);c--);}if(!a&&r!==this._terminal.buffer.active.baseY+this._terminal.rows-1)for(let c=this._terminal.buffer.active.baseY+this._terminal.rows-1;c>=r&&(n.startRow=c,a=this._findInLine(i,n,e,o),!a);c--);return a}_isWholeWord(i,e,t){return(i===0||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(e[i-1]))&&(i+t.length===e.length||" ~!@#$%^&*()+`-=[]{}|\\;:\"',./<>?".includes(e[i+t.length]))}_satisfiesWholeWord(i,e,t,s){return!s.wholeWord||this._isWholeWord(i,e,t)}_isRowCoveredByEarlierSearch(i){return this._terminal.buffer.active.getLine(i)?.isWrapped===!0}_findInLine(i,e,t={},s=!1){if(s){if(e.startRow>0&&this._terminal.buffer.active.getLine(e.startRow)?.isWrapped){e.startCol+=this._terminal.cols;return}}else for(;e.startRow>0&&this._terminal.buffer.active.getLine(e.startRow)?.isWrapped;)e.startRow--,e.startCol+=this._terminal.cols;let r=e.startRow,l=e.startCol,o=this._lineCache.getLineFromCache(r);o||(o=this._lineCache.translateBufferLineToStringWithWrap(r,!0),this._lineCache.setLineInCache(r,o));let[n,a]=o,c=this._bufferColsToStringOffset(r,l,a),u=i,f=n;t.regex||(u=t.caseSensitive?i:i.toLowerCase(),f=t.caseSensitive?n:n.toLowerCase());let _=-1;if(t.regex){let h=RegExp(u,t.caseSensitive?"g":"gi"),p;if(s)for(;p=h.exec(f.slice(0,c));){let b=h.lastIndex-p[0].length;p[0].length>0&&this._satisfiesWholeWord(b,f,p[0],t)&&(_=b,i=p[0]),h.lastIndex=b+1}else for(h.lastIndex=c;p=h.exec(f);){let b=h.lastIndex-p[0].length;if(p[0].length>0&&this._satisfiesWholeWord(b,f,p[0],t)){_=b,i=p[0];break}h.lastIndex=b+1}}else if(s){let h=c-u.length>=0?f.lastIndexOf(u,c-u.length):-1;for(;h>=0&&!this._satisfiesWholeWord(h,f,u,t);)h=h>0?f.lastIndexOf(u,h-1):-1;_=h}else{let h=f.indexOf(u,c);for(;h>=0&&!this._satisfiesWholeWord(h,f,u,t);)h=f.indexOf(u,h+1);_=h}if(_>=0){let h=0;for(;h<a.length-1&&_>=a[h+1];)h++;let p=h;for(;p<a.length-1&&_+i.length>=a[p+1];)p++;let b=_-a[h],O=_+i.length-a[p],L=this._stringLengthToBufferSize(r+h,b),W=this._stringLengthToBufferSize(r+p,O)-L+this._terminal.cols*(p-h);return{term:i,col:L,row:r+h,size:W}}}_stringLengthToBufferSize(i,e){let t=this._terminal.buffer.active.getLine(i);if(!t)return 0;for(let s=0;s<e;s++){let r=t.getCell(s);if(!r)break;let l=r.getChars();l.length>1&&(e-=l.length-1);let o=t.getCell(s+1);o&&o.getWidth()===0&&e++}return e}_bufferColsToStringOffset(i,e,t){let s=Math.min(Math.floor(e/this._terminal.cols),t.length-1),r=t[s],l=this._terminal.buffer.active.getLine(i+s);if(l){let o=Math.min(e-s*this._terminal.cols,this._terminal.cols);for(let n=0;n<o;n++){let a=l.getCell(n);if(!a)break;a.getWidth()&&(r+=a.getCode()===0?1:a.getChars().length)}}return r}};var R=class extends g{constructor(e){super();this._terminal=e;this._highlightDecorations=[];this._highlightedLines=new Set;this._register(m(()=>this.clearHighlightDecorations()))}createHighlightDecorations(e,t){this.clearHighlightDecorations();for(let s of e){let r=this._createResultDecorations(s,t,!1);if(r)for(let l of r)this._storeDecoration(l,s)}}createActiveDecoration(e,t){let s=this._createResultDecorations(e,t,!0);if(s)return{decorations:s,match:e,dispose(){D(s)}}}clearHighlightDecorations(){D(this._highlightDecorations),this._highlightDecorations=[],this._highlightedLines.clear()}_storeDecoration(e,t){this._highlightedLines.add(e.marker.line),this._highlightDecorations.push({decoration:e,match:t,dispose(){e.dispose()}})}_applyStyles(e,t,s){e.classList.contains("xterm-find-result-decoration")||(e.classList.add("xterm-find-result-decoration"),t&&(e.style.outline=`1px solid ${t}`)),s&&e.classList.add("xterm-find-active-result-decoration")}_createResultDecorations(e,t,s){let r=[],l=e.col,o=e.size,n=-this._terminal.buffer.active.baseY-this._terminal.buffer.active.cursorY+e.row;for(;o>0;){let c=Math.min(this._terminal.cols-l,o);r.push([n,l,c]),l=0,o-=c,n++}let a=[];for(let c of r){let u=this._terminal.registerMarker(c[0]),f=this._terminal.registerDecoration({marker:u,x:c[1],width:c[2],layer:s?"top":"bottom",backgroundColor:s?t.activeMatchBackground:t.matchBackground,overviewRulerOptions:this._highlightedLines.has(u.line)?void 0:{color:s?t.activeMatchColorOverviewRuler:t.matchOverviewRuler,position:"center"}});if(f){let _=[];_.push(u),_.push(f.onRender(h=>this._applyStyles(h,s?t.activeMatchBorder:t.matchBorder,!1))),_.push(f.onDispose(()=>D(_))),a.push(f)}}return a.length===0?void 0:a}};var y=class extends g{constructor(){super(...arguments);this._searchResults=[];this._onDidChangeResults=this._register(new I)}get onDidChangeResults(){return this._onDidChangeResults.event}get searchResults(){return this._searchResults}get selectedDecoration(){return this._selectedDecoration}set selectedDecoration(e){this._selectedDecoration=e}updateResults(e,t){this._searchResults=e.slice(0,t)}clearResults(){this._searchResults=[]}clearSelectedDecoration(){this._selectedDecoration&&(this._selectedDecoration.dispose(),this._selectedDecoration=void 0)}findResultIndex(e){for(let t=0;t<this._searchResults.length;t++){let s=this._searchResults[t];if(s.row===e.row&&s.col===e.col&&s.size===e.size)return t}return-1}fireResultsChanged(e){if(!e)return;let t=-1;this._selectedDecoration&&(t=this.findResultIndex(this._selectedDecoration.match)),this._onDidChangeResults.fire({resultIndex:t,resultCount:this._searchResults.length})}reset(){this.clearSelectedDecoration(),this.clearResults()}};var A=class extends g{constructor(e){super();this._highlightTimeout=this._register(new v);this._lineCache=this._register(new v);this._state=new x;this._resultTracker=this._register(new y);this._onAfterSearch=this._register(new I);this.onAfterSearch=this._onAfterSearch.event;this._onBeforeSearch=this._register(new I);this.onBeforeSearch=this._onBeforeSearch.event;this._highlightLimit=e?.highlightLimit??1e3}get onDidChangeResults(){return this._resultTracker.onDidChangeResults}activate(e){this._terminal=e,this._lineCache.value=new C(e),this._engine=new w(e,this._lineCache.value),this._decorationManager=new R(e),this._register(this._terminal.onWriteParsed(()=>this._updateMatches())),this._register(this._terminal.onResize(()=>this._updateMatches())),this._register(m(()=>this.clearDecorations()))}_updateMatches(){this._highlightTimeout.clear(),this._state.cachedSearchTerm&&this._state.lastSearchOptions?.decorations&&(this._highlightTimeout.value=T(()=>{let e=this._state.cachedSearchTerm;this._state.clearCachedTerm(),this.findPrevious(e,{...this._state.lastSearchOptions,incremental:!0},{noScroll:!0})},200))}clearDecorations(e){this._resultTracker.clearSelectedDecoration(),this._decorationManager?.clearHighlightDecorations(),this._resultTracker.clearResults(),e||this._state.clearCachedTerm()}clearActiveDecoration(){this._resultTracker.clearSelectedDecoration()}findNext(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);let r=this._findNextAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),r}_highlightAllMatches(e,t){if(!this._terminal||!this._engine||!this._decorationManager)throw new Error("Cannot use addon until it has been loaded");if(!this._state.isValidSearchTerm(e)){this.clearDecorations();return}this.clearDecorations(!0);let s=[],r,l=this._engine.find(e,0,0,t);for(;l&&(r?.row!==l.row||r?.col!==l.col)&&!(s.length>=this._highlightLimit);){r=l,s.push(r);let o=this._terminal.cols,n=r.col+r.size,a=r.row;n>=o&&(a+=Math.floor(n/o),n=n%o),l=this._engine.find(e,a,n,t)}this._resultTracker.updateResults(s,this._highlightLimit),t.decorations&&this._decorationManager.createHighlightDecorations(s,t.decorations)}_findNextAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;let r=this._engine.findNextWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(r,t?.decorations,s?.noScroll)}findPrevious(e,t,s){if(!this._terminal||!this._engine)throw new Error("Cannot use addon until it has been loaded");this._onBeforeSearch.fire(),this._state.lastSearchOptions=t,this._state.shouldUpdateHighlighting(e,t)&&this._highlightAllMatches(e,t);let r=this._findPreviousAndSelect(e,t,s);return this._fireResults(t),this._state.cachedSearchTerm=e,this._onAfterSearch.fire(),r}_fireResults(e){this._resultTracker.fireResultsChanged(!!e?.decorations)}_findPreviousAndSelect(e,t,s){if(!this._terminal||!this._engine)return!1;if(!this._state.isValidSearchTerm(e))return this._terminal.clearSelection(),this.clearDecorations(),!1;let r=this._engine.findPreviousWithSelection(e,t,this._state.cachedSearchTerm);return this._selectResult(r,t?.decorations,s?.noScroll)}_selectResult(e,t,s){if(!this._terminal||!this._decorationManager)return!1;if(this._resultTracker.clearSelectedDecoration(),!e)return this._terminal.clearSelection(),!1;if(this._terminal.select(e.col,e.row,e.size),t){let r=this._decorationManager.createActiveDecoration(e,t);r&&(this._resultTracker.selectedDecoration=r)}if(!s&&(e.row>=this._terminal.buffer.active.viewportY+this._terminal.rows||e.row<this._terminal.buffer.active.viewportY)){let r=e.row-this._terminal.buffer.active.viewportY;r-=Math.floor(this._terminal.rows/2),this._terminal.scrollLines(r)}return!0}};export{A as SearchAddon};
//# sourceMappingURL=addon-search.mjs.map
diff --git a/lib/addon-search.mjs.map b/lib/addon-search.mjs.map
index 5fe7b562c2705f76de7a5a30efe249caf4fb4403..5cfe8405e47378e3158e89ee143bf22193501bf0 100644
--- a/lib/addon-search.mjs.map
+++ b/lib/addon-search.mjs.map
@@ -1,7 +1,7 @@
{
"version": 3,
"sources": ["../../../src/common/Lifecycle.ts", "../../../src/common/Event.ts", "../../../src/common/Async.ts", "../src/SearchLineCache.ts", "../src/SearchState.ts", "../src/SearchEngine.ts", "../src/DecorationManager.ts", "../src/SearchResultTracker.ts", "../src/SearchAddon.ts"],
- "sourcesContent": ["/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose<T extends IDisposable>(disposable: T): T;\nexport function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;\nexport function dispose<T extends IDisposable>(disposables: T[]): T[];\nexport function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set<IDisposable>();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add<T extends IDisposable>(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register<T extends IDisposable>(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent<T> {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter<T> {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent<T> | undefined;\n\n public get event(): IEvent<T> {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners = this._listeners.slice();\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners = this._listeners.slice();\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed || !this._listeners.length) {\n return;\n }\n if (this._listeners.length === 1) {\n this._listeners[0].fn.call(this._listeners[0].thisArgs, event);\n return;\n }\n const listeners = this._listeners;\n for (let i = 0, len = listeners.length; i < len; ++i) {\n listeners[i].fn.call(listeners[i].thisArgs, event);\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward<T>(from: IEvent<T>, to: Emitter<T>): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map<I, O>(event: IEvent<I>, map: (i: I) => O): IEvent<O> {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any<T>(...events: IEvent<T>[]): IEvent<T>;\n export function any(...events: IEvent<any>[]): IEvent<void>;\n export function any<T>(...events: IEvent<T>[]): IEvent<T> {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\n\nexport type LineCacheEntry = [\n /**\n * The string representation of a line (as opposed to the buffer cell representation).\n */\n lineAsString: string,\n /**\n * The offsets where each line starts when the entry describes a wrapped line.\n */\n lineOffsets: number[]\n];\n\n/**\n * Configuration constants for the search line cache functionality.\n */\nconst enum Constants {\n /**\n * Time-to-live for cached search results in milliseconds. After this duration, cached search\n * results will be invalidated to ensure they remain consistent with terminal content changes.\n */\n LINES_CACHE_TIME_TO_LIVE = 15000\n}\n\nexport class SearchLineCache extends Disposable {\n /**\n * translateBufferLineToStringWithWrap is a fairly expensive call.\n * We memoize the calls into an array that has a time based ttl.\n * _linesCache is also invalidated when the terminal cursor moves.\n */\n private _linesCache: LineCacheEntry[] | undefined;\n private _linesCacheTimeout = this._register(new MutableDisposable());\n private _linesCacheDisposables = this._register(new MutableDisposable());\n // Track access to avoid recreating a timeout on every init call which occurs once per search\n // result (findNext/findPrevious -> _highlightAllMatches -> find loop).\n private _lastAccessTimestamp = 0;\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this._destroyLinesCache()));\n }\n\n /**\n * Sets up a line cache with a ttl\n */\n public initLinesCache(): void {\n if (!this._linesCache) {\n this._linesCache = new Array(this._terminal.buffer.active.length);\n this._linesCacheDisposables.value = combinedDisposable(\n this._terminal.onLineFeed(() => this._destroyLinesCache()),\n this._terminal.onCursorMove(() => this._destroyLinesCache()),\n this._terminal.onResize(() => this._destroyLinesCache())\n );\n }\n\n this._lastAccessTimestamp = Date.now();\n if (!this._linesCacheTimeout.value) {\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE);\n }\n }\n\n private _destroyLinesCache(): void {\n this._linesCache = undefined;\n this._lastAccessTimestamp = 0;\n this._linesCacheDisposables.clear();\n this._linesCacheTimeout.clear();\n }\n\n private _scheduleLinesCacheTimeout(delay: number): void {\n this._linesCacheTimeout.value = disposableTimeout(() => {\n if (!this._linesCache) {\n return;\n }\n const now = Date.now();\n const elapsed = now - this._lastAccessTimestamp;\n if (elapsed >= Constants.LINES_CACHE_TIME_TO_LIVE) {\n this._destroyLinesCache();\n return;\n }\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE - elapsed);\n }, delay);\n }\n\n public getLineFromCache(row: number): LineCacheEntry | undefined {\n return this._linesCache?.[row];\n }\n\n public setLineInCache(row: number, entry: LineCacheEntry): void {\n if (this._linesCache) {\n this._linesCache[row] = entry;\n }\n }\n\n /**\n * Translates a buffer line to a string, including subsequent lines if they are wraps.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n */\n public translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean): LineCacheEntry {\n const strings = [];\n const lineOffsets = [0];\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (line) {\n const nextLine = this._terminal.buffer.active.getLine(lineIndex + 1);\n const lineWrapsToNext = nextLine ? nextLine.isWrapped : false;\n let string = line.translateToString(!lineWrapsToNext && trimRight);\n if (lineWrapsToNext && nextLine) {\n const lastCell = line.getCell(line.length - 1);\n const lastCellIsNull = lastCell && lastCell.getCode() === 0 && lastCell.getWidth() === 1;\n // a wide character wrapped to the next line\n if (lastCellIsNull && nextLine.getCell(0)?.getWidth() === 2) {\n string = string.slice(0, -1);\n }\n }\n strings.push(string);\n if (lineWrapsToNext) {\n lineOffsets.push(lineOffsets[lineOffsets.length - 1] + string.length);\n } else {\n break;\n }\n lineIndex++;\n line = nextLine;\n }\n return [strings.join(''), lineOffsets];\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchOptions } from '@xterm/addon-search';\n\n/**\n * Manages search state including cached search terms, options tracking, and validation.\n * This class provides a centralized way to handle search state consistency and option changes.\n */\nexport class SearchState {\n private _cachedSearchTerm: string | undefined;\n private _lastSearchOptions: ISearchOptions | undefined;\n\n /**\n * Gets the currently cached search term.\n */\n public get cachedSearchTerm(): string | undefined {\n return this._cachedSearchTerm;\n }\n\n /**\n * Sets the cached search term.\n */\n public set cachedSearchTerm(term: string | undefined) {\n this._cachedSearchTerm = term;\n }\n\n /**\n * Gets the last search options used.\n */\n public get lastSearchOptions(): ISearchOptions | undefined {\n return this._lastSearchOptions;\n }\n\n /**\n * Sets the last search options used.\n */\n public set lastSearchOptions(options: ISearchOptions | undefined) {\n this._lastSearchOptions = options;\n }\n\n /**\n * Validates a search term to ensure it's not empty or invalid.\n * @param term The search term to validate.\n * @returns true if the term is valid for searching.\n */\n public isValidSearchTerm(term: string): boolean {\n return !!(term && term.length > 0);\n }\n\n /**\n * Determines if search options have changed compared to the last search.\n * @param newOptions The new search options to compare.\n * @returns true if the options have changed.\n */\n public didOptionsChange(newOptions?: ISearchOptions): boolean {\n if (!this._lastSearchOptions) {\n return true;\n }\n if (!newOptions) {\n return false;\n }\n if (this._lastSearchOptions.caseSensitive !== newOptions.caseSensitive) {\n return true;\n }\n if (this._lastSearchOptions.regex !== newOptions.regex) {\n return true;\n }\n if (this._lastSearchOptions.wholeWord !== newOptions.wholeWord) {\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a new search should trigger highlighting updates.\n * @param term The search term.\n * @param options The search options.\n * @returns true if highlighting should be updated.\n */\n public shouldUpdateHighlighting(term: string, options?: ISearchOptions): boolean {\n if (!options?.decorations) {\n return false;\n }\n return this._cachedSearchTerm === undefined ||\n term !== this._cachedSearchTerm ||\n this.didOptionsChange(options);\n }\n\n /**\n * Clears the cached search term.\n */\n public clearCachedTerm(): void {\n this._cachedSearchTerm = undefined;\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this._cachedSearchTerm = undefined;\n this._lastSearchOptions = undefined;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport type { ISearchOptions } from '@xterm/addon-search';\nimport type { SearchLineCache } from './SearchLineCache';\n\n/**\n * Represents the position to start a search from.\n */\ninterface ISearchPosition {\n startCol: number;\n startRow: number;\n}\n\n/**\n * Represents a search result with its position and content.\n */\nexport interface ISearchResult {\n term: string;\n col: number;\n row: number;\n size: number;\n}\n\n/**\n * Configuration constants for the search engine functionality.\n */\nconst enum Constants {\n /**\n * Characters that are considered non-word characters for search boundary detection. These\n * characters are used to determine word boundaries when performing whole-word searches. Includes\n * common punctuation, symbols, and whitespace characters.\n */\n NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\\\;:\"\\',./<>?'\n}\n\n/**\n * Core search engine that handles finding text within terminal content.\n * This class is responsible for the actual search algorithms and position calculations.\n */\nexport class SearchEngine {\n constructor(\n private readonly _terminal: Terminal,\n private readonly _lineCache: SearchLineCache\n ) {}\n\n /**\n * Find the first occurrence of a term starting from a specific position.\n * @param term The search term.\n * @param startRow The row to start searching from.\n * @param startCol The column to start searching from.\n * @param searchOptions Search options.\n * @returns The search result if found, undefined otherwise.\n */\n public find(term: string, startRow: number, startCol: number, searchOptions?: ISearchOptions): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n if (startCol >= this._terminal.cols) {\n throw new Error(`Invalid col: ${startCol} to search in terminal of ${this._terminal.cols} cols`);\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n return result;\n }\n\n /**\n * Find the next occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine incremental behavior.\n * @returns The search result if found, undefined otherwise.\n */\n public findNextWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startCol = 0;\n let startRow = 0;\n if (prevSelectedPos) {\n if (cachedSearchTerm === term) {\n startCol = prevSelectedPos.end.x;\n startRow = prevSelectedPos.end.y;\n } else {\n startCol = prevSelectedPos.start.x;\n startRow = prevSelectedPos.start.y;\n }\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n // If we hit the bottom and didn't search from the very top wrap back up\n if (!result && startRow !== 0) {\n for (let y = 0; y < startRow; y++) {\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n\n // If there is only one result, wrap back and return selection if it exists.\n if (!result && prevSelectedPos) {\n searchPosition.startRow = prevSelectedPos.start.y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n }\n\n return result;\n }\n\n /**\n * Find the previous occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine if expansion should occur.\n * @returns The search result if found, undefined otherwise.\n */\n public findPreviousWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startRow = this._terminal.buffer.active.baseY + this._terminal.rows - 1;\n const startCol = this._terminal.cols;\n const isReverseSearch = true;\n\n this._lineCache.initLinesCache();\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n let result: ISearchResult | undefined;\n if (prevSelectedPos) {\n searchPosition.startRow = startRow = prevSelectedPos.start.y;\n searchPosition.startCol = prevSelectedPos.start.x;\n if (cachedSearchTerm !== term) {\n // Try to expand selection to right first.\n result = this._findInLine(term, searchPosition, searchOptions, false);\n if (!result) {\n // If selection was not able to be expanded to the right, then try reverse search\n searchPosition.startRow = startRow = prevSelectedPos.end.y;\n searchPosition.startCol = prevSelectedPos.end.x;\n }\n }\n }\n\n result ??= this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n\n // Search from startRow - 1 to top\n if (!result) {\n searchPosition.startCol = Math.max(searchPosition.startCol, this._terminal.cols);\n for (let y = startRow - 1; y >= 0; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n // If we hit the top and didn't search from the very bottom wrap back down\n if (!result && startRow !== (this._terminal.buffer.active.baseY + this._terminal.rows - 1)) {\n for (let y = (this._terminal.buffer.active.baseY + this._terminal.rows - 1); y >= startRow; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n\n return result;\n }\n\n /**\n * A found substring is a whole word if it doesn't have an alphanumeric character directly\n * adjacent to it.\n * @param searchIndex starting index of the potential whole word substring\n * @param line entire string in which the potential whole word was found\n * @param term the substring that starts at searchIndex\n */\n private _isWholeWord(searchIndex: number, line: string, term: string): boolean {\n return ((searchIndex === 0) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex - 1]))) &&\n (((searchIndex + term.length) === line.length) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex + term.length])));\n }\n\n /**\n * Searches a line for a search term. Takes the provided terminal line and searches the text line,\n * which may contain subsequent terminal lines if the text is wrapped. If the provided line number\n * is part of a wrapped text line that started on an earlier line then it is skipped since it will\n * be properly searched when the terminal line that the text starts on is searched.\n * @param term The search term.\n * @param searchPosition The position to start the search.\n * @param searchOptions Search options.\n * @param isReverseSearch Whether the search should start from the right side of the terminal and\n * search to the left.\n * @returns The search result if it was found.\n */\n private _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {\n const row = searchPosition.startRow;\n const col = searchPosition.startCol;\n\n // Ignore wrapped lines, only consider on unwrapped line (first row of command string).\n const firstLine = this._terminal.buffer.active.getLine(row);\n if (firstLine?.isWrapped) {\n if (isReverseSearch) {\n searchPosition.startCol += this._terminal.cols;\n return;\n }\n\n // This will iterate until we find the line start.\n // When we find it, we will search using the calculated start column.\n searchPosition.startRow--;\n searchPosition.startCol += this._terminal.cols;\n return this._findInLine(term, searchPosition, searchOptions);\n }\n let cache = this._lineCache.getLineFromCache(row);\n if (!cache) {\n cache = this._lineCache.translateBufferLineToStringWithWrap(row, true);\n this._lineCache.setLineInCache(row, cache);\n }\n const [stringLine, offsets] = cache;\n\n const offset = this._bufferColsToStringOffset(row, col);\n let searchTerm = term;\n let searchStringLine = stringLine;\n if (!searchOptions.regex) {\n searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();\n searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();\n }\n\n let resultIndex = -1;\n if (searchOptions.regex) {\n const searchRegex = RegExp(searchTerm, searchOptions.caseSensitive ? 'g' : 'gi');\n let foundTerm: RegExpExecArray | null;\n if (isReverseSearch) {\n // This loop will get the resultIndex of the _last_ regex match in the range 0..offset\n while (foundTerm = searchRegex.exec(searchStringLine.slice(0, offset))) {\n resultIndex = searchRegex.lastIndex - foundTerm[0].length;\n term = foundTerm[0];\n searchRegex.lastIndex -= (term.length - 1);\n }\n } else {\n foundTerm = searchRegex.exec(searchStringLine.slice(offset));\n if (foundTerm && foundTerm[0].length > 0) {\n resultIndex = offset + (searchRegex.lastIndex - foundTerm[0].length);\n term = foundTerm[0];\n }\n }\n } else {\n if (isReverseSearch) {\n if (offset - searchTerm.length >= 0) {\n resultIndex = searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length);\n }\n } else {\n resultIndex = searchStringLine.indexOf(searchTerm, offset);\n }\n }\n\n if (resultIndex >= 0) {\n if (searchOptions.wholeWord && !this._isWholeWord(resultIndex, searchStringLine, term)) {\n return;\n }\n\n // Adjust the row number and search index if needed since a \"line\" of text can span multiple\n // rows\n let startRowOffset = 0;\n while (startRowOffset < offsets.length - 1 && resultIndex >= offsets[startRowOffset + 1]) {\n startRowOffset++;\n }\n let endRowOffset = startRowOffset;\n while (endRowOffset < offsets.length - 1 && resultIndex + term.length >= offsets[endRowOffset + 1]) {\n endRowOffset++;\n }\n const startColOffset = resultIndex - offsets[startRowOffset];\n const endColOffset = resultIndex + term.length - offsets[endRowOffset];\n const startColIndex = this._stringLengthToBufferSize(row + startRowOffset, startColOffset);\n const endColIndex = this._stringLengthToBufferSize(row + endRowOffset, endColOffset);\n const size = endColIndex - startColIndex + this._terminal.cols * (endRowOffset - startRowOffset);\n\n return {\n term,\n col: startColIndex,\n row: row + startRowOffset,\n size\n };\n }\n }\n\n private _stringLengthToBufferSize(row: number, offset: number): number {\n const line = this._terminal.buffer.active.getLine(row);\n if (!line) {\n return 0;\n }\n for (let i = 0; i < offset; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n // Adjust the searchIndex to normalize emoji into single chars\n const char = cell.getChars();\n if (char.length > 1) {\n offset -= char.length - 1;\n }\n // Adjust the searchIndex for empty characters following wide unicode\n // chars (eg. CJK)\n const nextCell = line.getCell(i + 1);\n if (nextCell && nextCell.getWidth() === 0) {\n offset++;\n }\n }\n return offset;\n }\n\n private _bufferColsToStringOffset(startRow: number, cols: number): number {\n let lineIndex = startRow;\n let offset = 0;\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (cols > 0 && line) {\n for (let i = 0; i < cols && i < this._terminal.cols; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n if (cell.getWidth()) {\n // Treat null characters as whitespace to align with the translateToString API\n offset += cell.getCode() === 0 ? 1 : cell.getChars().length;\n }\n }\n lineIndex++;\n line = this._terminal.buffer.active.getLine(lineIndex);\n if (line && !line.isWrapped) {\n break;\n }\n cols -= this._terminal.cols;\n }\n return offset;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';\nimport type { ISearchDecorationOptions } from '@xterm/addon-search';\nimport { dispose, Disposable, toDisposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a highlight decoration.\n */\ninterface IHighlight extends IDisposable {\n decoration: IDecoration;\n match: ISearchResult;\n}\n\n/**\n * Interface for managing multiple decorations for a single match.\n */\ninterface IMultiHighlight extends IDisposable {\n decorations: IDecoration[];\n match: ISearchResult;\n}\n\n/**\n * Manages visual decorations for search results including highlighting and active selection\n * indicators. This class handles the creation, styling, and disposal of search-related decorations.\n */\nexport class DecorationManager extends Disposable {\n private _highlightDecorations: IHighlight[] = [];\n private _highlightedLines: Set<number> = new Set();\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this.clearHighlightDecorations()));\n }\n\n /**\n * Creates decorations for all provided search results.\n * @param results The search results to create decorations for.\n * @param options The decoration options.\n */\n public createHighlightDecorations(results: ISearchResult[], options: ISearchDecorationOptions): void {\n this.clearHighlightDecorations();\n\n for (const match of results) {\n const decorations = this._createResultDecorations(match, options, false);\n if (decorations) {\n for (const decoration of decorations) {\n this._storeDecoration(decoration, match);\n }\n }\n }\n }\n\n /**\n * Creates decorations for the currently active search result.\n * @param result The active search result.\n * @param options The decoration options.\n * @returns The multi-highlight decoration or undefined if creation failed.\n */\n public createActiveDecoration(result: ISearchResult, options: ISearchDecorationOptions): IMultiHighlight | undefined {\n const decorations = this._createResultDecorations(result, options, true);\n if (decorations) {\n return { decorations, match: result, dispose() { dispose(decorations); } };\n }\n return undefined;\n }\n\n /**\n * Clears all highlight decorations.\n */\n public clearHighlightDecorations(): void {\n dispose(this._highlightDecorations);\n this._highlightDecorations = [];\n this._highlightedLines.clear();\n }\n\n /**\n * Stores a decoration and tracks it for management.\n * @param decoration The decoration to store.\n * @param match The search result this decoration represents.\n */\n private _storeDecoration(decoration: IDecoration, match: ISearchResult): void {\n this._highlightedLines.add(decoration.marker.line);\n this._highlightDecorations.push({ decoration, match, dispose() { decoration.dispose(); } });\n }\n\n /**\n * Applies styles to the decoration when it is rendered.\n * @param element The decoration's element.\n * @param borderColor The border color to apply.\n * @param isActiveResult Whether the element is part of the active search result.\n */\n private _applyStyles(element: HTMLElement, borderColor: string | undefined, isActiveResult: boolean): void {\n if (!element.classList.contains('xterm-find-result-decoration')) {\n element.classList.add('xterm-find-result-decoration');\n if (borderColor) {\n element.style.outline = `1px solid ${borderColor}`;\n }\n }\n if (isActiveResult) {\n element.classList.add('xterm-find-active-result-decoration');\n }\n }\n\n /**\n * Creates a decoration for the result and applies styles\n * @param result the search result for which to create the decoration\n * @param options the options for the decoration\n * @param isActiveResult whether this is the currently active result\n * @returns the decorations or undefined if the marker has already been disposed of\n */\n private _createResultDecorations(result: ISearchResult, options: ISearchDecorationOptions, isActiveResult: boolean): IDecoration[] | undefined {\n // Gather decoration ranges for this match as it could wrap\n const decorationRanges: [number, number, number][] = [];\n let currentCol = result.col;\n let remainingSize = result.size;\n let markerOffset = -this._terminal.buffer.active.baseY - this._terminal.buffer.active.cursorY + result.row;\n while (remainingSize > 0) {\n const amountThisRow = Math.min(this._terminal.cols - currentCol, remainingSize);\n decorationRanges.push([markerOffset, currentCol, amountThisRow]);\n currentCol = 0;\n remainingSize -= amountThisRow;\n markerOffset++;\n }\n\n // Create the decorations\n const decorations: IDecoration[] = [];\n for (const range of decorationRanges) {\n const marker = this._terminal.registerMarker(range[0]);\n const decoration = this._terminal.registerDecoration({\n marker,\n x: range[1],\n width: range[2],\n layer: isActiveResult ? 'top' : 'bottom',\n backgroundColor: isActiveResult ? options.activeMatchBackground : options.matchBackground,\n overviewRulerOptions: this._highlightedLines.has(marker.line) ? undefined : {\n color: isActiveResult ? options.activeMatchColorOverviewRuler : options.matchOverviewRuler,\n position: 'center'\n }\n });\n if (decoration) {\n const disposables: IDisposable[] = [];\n disposables.push(marker);\n disposables.push(decoration.onRender((e) => this._applyStyles(e, isActiveResult ? options.activeMatchBorder : options.matchBorder, false)));\n disposables.push(decoration.onDispose(() => dispose(disposables)));\n decorations.push(decoration);\n }\n }\n\n return decorations.length === 0 ? undefined : decorations;\n }\n}\n\n\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchResultChangeEvent } from '@xterm/addon-search';\nimport type { IDisposable } from '@xterm/xterm';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a currently selected decoration.\n */\ninterface ISelectedDecoration extends IDisposable {\n match: ISearchResult;\n}\n\n/**\n * Tracks search results, manages result indexing, and fires events when results change.\n * This class provides centralized management of search result state and notifications.\n */\nexport class SearchResultTracker extends Disposable {\n private _searchResults: ISearchResult[] = [];\n private _selectedDecoration: ISelectedDecoration | undefined;\n\n private readonly _onDidChangeResults = this._register(new Emitter<ISearchResultChangeEvent>());\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> { return this._onDidChangeResults.event; }\n\n /**\n * Gets the current search results.\n */\n public get searchResults(): ReadonlyArray<ISearchResult> {\n return this._searchResults;\n }\n\n /**\n * Gets the currently selected decoration.\n */\n public get selectedDecoration(): ISelectedDecoration | undefined {\n return this._selectedDecoration;\n }\n\n /**\n * Sets the currently selected decoration.\n */\n public set selectedDecoration(decoration: ISelectedDecoration | undefined) {\n this._selectedDecoration = decoration;\n }\n\n /**\n * Updates the search results with a new set of results.\n * @param results The new search results.\n * @param maxResults The maximum number of results to track.\n */\n public updateResults(results: ISearchResult[], maxResults: number): void {\n this._searchResults = results.slice(0, maxResults);\n }\n\n /**\n * Clears all search results.\n */\n public clearResults(): void {\n this._searchResults = [];\n }\n\n /**\n * Clears the selected decoration.\n */\n public clearSelectedDecoration(): void {\n if (this._selectedDecoration) {\n this._selectedDecoration.dispose();\n this._selectedDecoration = undefined;\n }\n }\n\n /**\n * Finds the index of a result in the current results array.\n * @param result The result to find.\n * @returns The index of the result, or -1 if not found.\n */\n public findResultIndex(result: ISearchResult): number {\n for (let i = 0; i < this._searchResults.length; i++) {\n const match = this._searchResults[i];\n if (match.row === result.row && match.col === result.col && match.size === result.size) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Fires a result change event with the current state.\n * @param hasDecorations Whether decorations are enabled.\n */\n public fireResultsChanged(hasDecorations: boolean): void {\n if (!hasDecorations) {\n return;\n }\n\n let resultIndex = -1;\n if (this._selectedDecoration) {\n resultIndex = this.findResultIndex(this._selectedDecoration.match);\n }\n\n this._onDidChangeResults.fire({\n resultIndex,\n resultCount: this._searchResults.length\n });\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this.clearSelectedDecoration();\n this.clearResults();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';\nimport type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\nimport { SearchLineCache } from './SearchLineCache';\nimport { SearchState } from './SearchState';\nimport { SearchEngine, type ISearchResult } from './SearchEngine';\nimport { DecorationManager } from './DecorationManager';\nimport { SearchResultTracker } from './SearchResultTracker';\n\ninterface IInternalSearchOptions {\n noScroll: boolean;\n}\n\n/**\n * Configuration constants for the search addon functionality.\n */\nconst enum Constants {\n /**\n * Default maximum number of search results to highlight simultaneously. This limit prevents\n * performance degradation when searching for very common terms that would result in excessive\n * highlighting decorations.\n */\n DEFAULT_HIGHLIGHT_LIMIT = 1000\n}\n\nexport class SearchAddon extends Disposable implements ITerminalAddon, ISearchApi {\n private _terminal: Terminal | undefined;\n private _highlightLimit: number;\n private _highlightTimeout = this._register(new MutableDisposable<IDisposable>());\n private _lineCache = this._register(new MutableDisposable<SearchLineCache>());\n\n // Component instances\n private _state = new SearchState();\n private _engine: SearchEngine | undefined;\n private _decorationManager: DecorationManager | undefined;\n private _resultTracker = this._register(new SearchResultTracker());\n\n private readonly _onAfterSearch = this._register(new Emitter<void>());\n public readonly onAfterSearch = this._onAfterSearch.event;\n private readonly _onBeforeSearch = this._register(new Emitter<void>());\n public readonly onBeforeSearch = this._onBeforeSearch.event;\n\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> {\n return this._resultTracker.onDidChangeResults;\n }\n\n constructor(options?: Partial<ISearchAddonOptions>) {\n super();\n\n this._highlightLimit = options?.highlightLimit ?? Constants.DEFAULT_HIGHLIGHT_LIMIT;\n }\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n this._lineCache.value = new SearchLineCache(terminal);\n this._engine = new SearchEngine(terminal, this._lineCache.value);\n this._decorationManager = new DecorationManager(terminal);\n this._register(this._terminal.onWriteParsed(() => this._updateMatches()));\n this._register(this._terminal.onResize(() => this._updateMatches()));\n this._register(toDisposable(() => this.clearDecorations()));\n }\n\n private _updateMatches(): void {\n this._highlightTimeout.clear();\n if (this._state.cachedSearchTerm && this._state.lastSearchOptions?.decorations) {\n this._highlightTimeout.value = disposableTimeout(() => {\n const term = this._state.cachedSearchTerm;\n this._state.clearCachedTerm();\n this.findPrevious(term!, { ...this._state.lastSearchOptions, incremental: true }, { noScroll: true });\n }, 200);\n }\n }\n\n public clearDecorations(retainCachedSearchTerm?: boolean): void {\n this._resultTracker.clearSelectedDecoration();\n this._decorationManager?.clearHighlightDecorations();\n this._resultTracker.clearResults();\n if (!retainCachedSearchTerm) {\n this._state.clearCachedTerm();\n }\n }\n\n public clearActiveDecoration(): void {\n this._resultTracker.clearSelectedDecoration();\n }\n\n /**\n * Find the next instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findNext(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findNextAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _highlightAllMatches(term: string, searchOptions: ISearchOptions): void {\n if (!this._terminal || !this._engine || !this._decorationManager) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n if (!this._state.isValidSearchTerm(term)) {\n this.clearDecorations();\n return;\n }\n\n // new search, clear out the old decorations\n this.clearDecorations(true);\n\n const results: ISearchResult[] = [];\n let prevResult: ISearchResult | undefined = undefined;\n let result = this._engine.find(term, 0, 0, searchOptions);\n\n while (result && (prevResult?.row !== result.row || prevResult?.col !== result.col)) {\n if (results.length >= this._highlightLimit) {\n break;\n }\n prevResult = result;\n results.push(prevResult);\n const cols = this._terminal.cols;\n let nextCol = prevResult.col + prevResult.size;\n let nextRow = prevResult.row;\n if (nextCol >= cols) {\n nextRow += Math.floor(nextCol / cols);\n nextCol = nextCol % cols;\n }\n result = this._engine.find(term, nextRow, nextCol, searchOptions);\n }\n\n this._resultTracker.updateResults(results, this._highlightLimit);\n if (searchOptions.decorations) {\n this._decorationManager.createHighlightDecorations(results, searchOptions.decorations);\n }\n }\n\n private _findNextAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findNextWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Find the previous instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findPrevious(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findPreviousAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _fireResults(searchOptions?: ISearchOptions): void {\n this._resultTracker.fireResultsChanged(!!searchOptions?.decorations);\n }\n\n private _findPreviousAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findPreviousWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Selects and scrolls to a result.\n * @param result The result to select.\n * @returns Whether a result was selected.\n */\n private _selectResult(result: ISearchResult | undefined, options?: ISearchDecorationOptions, noScroll?: boolean): boolean {\n if (!this._terminal || !this._decorationManager) {\n return false;\n }\n\n this._resultTracker.clearSelectedDecoration();\n if (!result) {\n this._terminal.clearSelection();\n return false;\n }\n\n this._terminal.select(result.col, result.row, result.size);\n if (options) {\n const activeDecoration = this._decorationManager.createActiveDecoration(result, options);\n if (activeDecoration) {\n this._resultTracker.selectedDecoration = activeDecoration;\n }\n }\n\n if (!noScroll) {\n // If it is not in the viewport then we scroll else it just gets selected\n if (result.row >= (this._terminal.buffer.active.viewportY + this._terminal.rows) || result.row < this._terminal.buffer.active.viewportY) {\n let scroll = result.row - this._terminal.buffer.active.viewportY;\n scroll -= Math.floor(this._terminal.rows / 2);\n this._terminal.scrollLines(scroll);\n }\n }\n return true;\n }\n}\n"],
- "mappings": "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",
- "names": ["toDisposable", "fn", "dispose", "arg", "d", "combinedDisposable", "disposables", "DisposableStore", "o", "Disposable", "MutableDisposable", "value", "Emitter", "listener", "thisArgs", "disposables", "toDisposable", "entry", "result", "idx", "event", "listeners", "i", "len", "EventUtils", "forward", "from", "to", "e", "map", "any", "events", "store", "DisposableStore", "runAndSubscribe", "handler", "initial", "disposableTimeout", "handler", "timeout", "store", "timer", "disposable", "toDisposable", "SearchLineCache", "Disposable", "_terminal", "MutableDisposable", "toDisposable", "combinedDisposable", "delay", "disposableTimeout", "elapsed", "row", "entry", "lineIndex", "trimRight", "strings", "lineOffsets", "line", "nextLine", "lineWrapsToNext", "string", "lastCell", "SearchState", "term", "options", "newOptions", "SearchEngine", "_terminal", "_lineCache", "term", "startRow", "startCol", "searchOptions", "searchPosition", "result", "y", "cachedSearchTerm", "prevSelectedPos", "isReverseSearch", "searchIndex", "line", "row", "col", "cache", "stringLine", "offsets", "offset", "searchTerm", "searchStringLine", "resultIndex", "searchRegex", "foundTerm", "startRowOffset", "endRowOffset", "startColOffset", "endColOffset", "startColIndex", "size", "i", "cell", "char", "nextCell", "cols", "lineIndex", "DecorationManager", "Disposable", "_terminal", "toDisposable", "results", "options", "match", "decorations", "decoration", "result", "dispose", "element", "borderColor", "isActiveResult", "decorationRanges", "currentCol", "remainingSize", "markerOffset", "amountThisRow", "range", "marker", "disposables", "e", "SearchResultTracker", "Disposable", "Emitter", "decoration", "results", "maxResults", "result", "i", "match", "hasDecorations", "resultIndex", "SearchAddon", "Disposable", "options", "MutableDisposable", "SearchState", "SearchResultTracker", "Emitter", "terminal", "SearchLineCache", "SearchEngine", "DecorationManager", "toDisposable", "disposableTimeout", "term", "retainCachedSearchTerm", "searchOptions", "internalSearchOptions", "found", "results", "prevResult", "result", "cols", "nextCol", "nextRow", "noScroll", "activeDecoration", "scroll"]
+ "sourcesContent": ["/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal lifecycle utilities for xterm.js core.\n * Simplified from VS Code's lifecycle.ts - no tracking/leak detection.\n */\n\nexport interface IDisposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): IDisposable {\n return { dispose: fn };\n}\n\nexport function dispose<T extends IDisposable>(disposable: T): T;\nexport function dispose<T extends IDisposable>(disposable: T | undefined): T | undefined;\nexport function dispose<T extends IDisposable>(disposables: T[]): T[];\nexport function dispose<T extends IDisposable>(arg: T | T[] | undefined): T | T[] | undefined {\n if (!arg) {\n return arg;\n }\n if (Array.isArray(arg)) {\n for (const d of arg) {\n d.dispose();\n }\n return [];\n }\n arg.dispose();\n return arg;\n}\n\nexport function combinedDisposable(...disposables: IDisposable[]): IDisposable {\n return toDisposable(() => dispose(disposables));\n}\n\nexport class DisposableStore implements IDisposable {\n private readonly _disposables = new Set<IDisposable>();\n private _isDisposed = false;\n\n public get isDisposed(): boolean {\n return this._isDisposed;\n }\n\n public add<T extends IDisposable>(o: T): T {\n if (this._isDisposed) {\n o.dispose();\n } else {\n this._disposables.add(o);\n }\n return o;\n }\n\n public dispose(): void {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n\n public clear(): void {\n for (const d of this._disposables) {\n d.dispose();\n }\n this._disposables.clear();\n }\n}\n\nexport abstract class Disposable implements IDisposable {\n public static readonly None: IDisposable = Object.freeze({ dispose() { } });\n\n protected readonly _store = new DisposableStore();\n\n public dispose(): void {\n this._store.dispose();\n }\n\n protected _register<T extends IDisposable>(o: T): T {\n return this._store.add(o);\n }\n}\n\nexport class MutableDisposable<T extends IDisposable> implements IDisposable {\n private _value: T | undefined;\n private _isDisposed = false;\n\n public get value(): T | undefined {\n return this._isDisposed ? undefined : this._value;\n }\n\n public set value(value: T | undefined) {\n if (this._isDisposed || value === this._value) {\n return;\n }\n this._value?.dispose();\n this._value = value;\n }\n\n public clear(): void {\n this.value = undefined;\n }\n\n public dispose(): void {\n this._isDisposed = true;\n this._value?.dispose();\n this._value = undefined;\n }\n}\n", "/**\n * Copyright (c) 2024-2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal event utilities for xterm.js core.\n * Simplified from VS Code's event.ts - no leak detection/profiling.\n */\n\nimport { IDisposable, DisposableStore, toDisposable } from './Lifecycle';\n\nexport interface IEvent<T> {\n (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore): IDisposable;\n}\n\nexport class Emitter<T> {\n private _listeners: { fn: (e: T) => any, thisArgs: any }[] = [];\n private _disposed = false;\n private _event: IEvent<T> | undefined;\n\n public get event(): IEvent<T> {\n if (this._event) {\n return this._event;\n }\n this._event = (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n if (this._disposed) {\n return toDisposable(() => {});\n }\n\n const entry = { fn: listener, thisArgs };\n this._listeners = this._listeners.slice();\n this._listeners.push(entry);\n\n const result = toDisposable(() => {\n const idx = this._listeners.indexOf(entry);\n if (idx !== -1) {\n this._listeners = this._listeners.slice();\n this._listeners.splice(idx, 1);\n }\n });\n\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(result);\n } else {\n disposables.add(result);\n }\n }\n\n return result;\n };\n return this._event;\n }\n\n public fire(event: T): void {\n if (this._disposed || !this._listeners.length) {\n return;\n }\n if (this._listeners.length === 1) {\n this._listeners[0].fn.call(this._listeners[0].thisArgs, event);\n return;\n }\n const listeners = this._listeners;\n for (let i = 0, len = listeners.length; i < len; ++i) {\n listeners[i].fn.call(listeners[i].thisArgs, event);\n }\n }\n\n public dispose(): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n this._listeners.length = 0;\n }\n}\n\nexport namespace EventUtils {\n export function forward<T>(from: IEvent<T>, to: Emitter<T>): IDisposable {\n return from(e => to.fire(e));\n }\n\n export function map<I, O>(event: IEvent<I>, map: (i: I) => O): IEvent<O> {\n return (listener: (e: O) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n return event(i => listener.call(thisArgs, map(i)), undefined, disposables);\n };\n }\n\n export function any<T>(...events: IEvent<T>[]): IEvent<T>;\n export function any(...events: IEvent<any>[]): IEvent<void>;\n export function any<T>(...events: IEvent<T>[]): IEvent<T> {\n return (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[] | DisposableStore) => {\n const store = new DisposableStore();\n for (const event of events) {\n store.add(event(e => listener.call(thisArgs, e)));\n }\n if (disposables) {\n if (Array.isArray(disposables)) {\n disposables.push(store);\n } else {\n disposables.add(store);\n }\n }\n return store;\n };\n }\n\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T) => void, initial: T): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void): IDisposable;\n export function runAndSubscribe<T>(event: IEvent<T>, handler: (e: T | undefined) => void, initial?: T): IDisposable {\n handler(initial);\n return event(e => handler(e));\n }\n}\n", "/**\n * Copyright (c) 2026 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Minimal async helpers for xterm.js core.\n */\n\nimport { DisposableStore, IDisposable, toDisposable } from './Lifecycle';\n\nexport function timeout(millis: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, millis));\n}\n\n/**\n * Creates a timeout that can be disposed using its returned value.\n * @param handler The timeout handler.\n * @param timeout An optional timeout in milliseconds.\n * @param store An optional {@link DisposableStore} that will have the timeout disposable managed\n * automatically.\n */\nexport function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {\n const timer = setTimeout(() => {\n handler();\n if (store) {\n disposable.dispose();\n }\n }, timeout);\n const disposable = toDisposable(() => {\n clearTimeout(timer);\n });\n store?.add(disposable);\n return disposable;\n}\n\nexport class TimeoutTimer implements IDisposable {\n private _token: any = -1;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n if (this._token !== -1) {\n clearTimeout(this._token);\n this._token = -1;\n }\n }\n\n public cancelAndSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');\n }\n this.cancel();\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n\n public setIfNotSet(runner: () => void, timeout: number): void {\n if (this._isDisposed) {\n throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');\n }\n if (this._token !== -1) {\n return;\n }\n this._token = setTimeout(() => {\n this._token = -1;\n runner();\n }, timeout);\n }\n}\n\n/**\n * Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled\n * microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not\n * run yet.\n */\nexport class MicrotaskTimer implements IDisposable {\n private _isScheduled = false;\n private _isDisposed = false;\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n\n public cancel(): void {\n this._isScheduled = false;\n }\n\n public set(runner: () => void): void {\n if (this._isDisposed) {\n throw new Error('Calling set on a disposed MicrotaskTimer');\n }\n if (this._isScheduled) {\n return;\n }\n this._isScheduled = true;\n queueMicrotask(() => {\n if (!this._isScheduled) {\n return;\n }\n this._isScheduled = false;\n runner();\n });\n }\n}\n\nexport class IntervalTimer implements IDisposable {\n private _disposable: IDisposable | undefined;\n private _isDisposed = false;\n\n public cancel(): void {\n this._disposable?.dispose();\n this._disposable = undefined;\n }\n\n public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {\n if (this._isDisposed) {\n throw new Error('Calling cancelAndSet on a disposed IntervalTimer');\n }\n this.cancel();\n const handle = context.setInterval(() => {\n runner();\n }, interval);\n this._disposable = {\n dispose: () => {\n context.clearInterval(handle as any);\n this._disposable = undefined;\n }\n };\n }\n\n public dispose(): void {\n this.cancel();\n this._isDisposed = true;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\n\nexport type LineCacheEntry = [\n /**\n * The string representation of a line (as opposed to the buffer cell representation).\n */\n lineAsString: string,\n /**\n * The offsets where each line starts when the entry describes a wrapped line.\n */\n lineOffsets: number[]\n];\n\n/**\n * Configuration constants for the search line cache functionality.\n */\nconst enum Constants {\n /**\n * Time-to-live for cached search results in milliseconds. After this duration, cached search\n * results will be invalidated to ensure they remain consistent with terminal content changes.\n */\n LINES_CACHE_TIME_TO_LIVE = 15000\n}\n\nexport class SearchLineCache extends Disposable {\n /**\n * translateBufferLineToStringWithWrap is a fairly expensive call.\n * We memoize the calls into an array that has a time based ttl.\n * _linesCache is also invalidated when the terminal cursor moves.\n */\n private _linesCache: LineCacheEntry[] | undefined;\n private _linesCacheTimeout = this._register(new MutableDisposable());\n private _linesCacheDisposables = this._register(new MutableDisposable());\n // Track access to avoid recreating a timeout on every init call which occurs once per search\n // result (findNext/findPrevious -> _highlightAllMatches -> find loop).\n private _lastAccessTimestamp = 0;\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this._destroyLinesCache()));\n }\n\n /**\n * Sets up a line cache with a ttl\n */\n public initLinesCache(): void {\n if (!this._linesCache) {\n this._linesCache = new Array(this._terminal.buffer.active.length);\n this._linesCacheDisposables.value = combinedDisposable(\n this._terminal.onLineFeed(() => this._destroyLinesCache()),\n this._terminal.onCursorMove(() => this._destroyLinesCache()),\n this._terminal.onResize(() => this._destroyLinesCache())\n );\n }\n\n this._lastAccessTimestamp = Date.now();\n if (!this._linesCacheTimeout.value) {\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE);\n }\n }\n\n private _destroyLinesCache(): void {\n this._linesCache = undefined;\n this._lastAccessTimestamp = 0;\n this._linesCacheDisposables.clear();\n this._linesCacheTimeout.clear();\n }\n\n private _scheduleLinesCacheTimeout(delay: number): void {\n this._linesCacheTimeout.value = disposableTimeout(() => {\n if (!this._linesCache) {\n return;\n }\n const now = Date.now();\n const elapsed = now - this._lastAccessTimestamp;\n if (elapsed >= Constants.LINES_CACHE_TIME_TO_LIVE) {\n this._destroyLinesCache();\n return;\n }\n this._scheduleLinesCacheTimeout(Constants.LINES_CACHE_TIME_TO_LIVE - elapsed);\n }, delay);\n }\n\n public getLineFromCache(row: number): LineCacheEntry | undefined {\n return this._linesCache?.[row];\n }\n\n public setLineInCache(row: number, entry: LineCacheEntry): void {\n if (this._linesCache) {\n this._linesCache[row] = entry;\n }\n }\n\n /**\n * Translates a buffer line to a string, including subsequent lines if they are wraps.\n * Wide characters will count as two columns in the resulting string. This\n * function is useful for getting the actual text underneath the raw selection\n * position.\n * @param lineIndex The index of the line being translated.\n * @param trimRight Whether to trim whitespace to the right.\n */\n public translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean): LineCacheEntry {\n const strings = [];\n const lineOffsets = [0];\n // A single line longer than the whole scrollback leaves every buffer row wrapped, and the\n // buffer's ring answers an out-of-range row by cycling back to the start, so an unbounded walk\n // never reaches an unwrapped line.\n const bufferLength = this._terminal.buffer.active.length;\n let line = this._terminal.buffer.active.getLine(lineIndex);\n while (line) {\n const nextLine = lineIndex + 1 < bufferLength ? this._terminal.buffer.active.getLine(lineIndex + 1) : undefined;\n const lineWrapsToNext = nextLine ? nextLine.isWrapped : false;\n let string = line.translateToString(!lineWrapsToNext && trimRight);\n if (lineWrapsToNext && nextLine) {\n const lastCell = line.getCell(line.length - 1);\n const lastCellIsNull = lastCell && lastCell.getCode() === 0 && lastCell.getWidth() === 1;\n // a wide character wrapped to the next line\n if (lastCellIsNull && nextLine.getCell(0)?.getWidth() === 2) {\n string = string.slice(0, -1);\n }\n }\n strings.push(string);\n if (lineWrapsToNext) {\n lineOffsets.push(lineOffsets[lineOffsets.length - 1] + string.length);\n } else {\n break;\n }\n lineIndex++;\n line = nextLine;\n }\n return [strings.join(''), lineOffsets];\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchOptions } from '@xterm/addon-search';\n\n/**\n * Manages search state including cached search terms, options tracking, and validation.\n * This class provides a centralized way to handle search state consistency and option changes.\n */\nexport class SearchState {\n private _cachedSearchTerm: string | undefined;\n private _lastSearchOptions: ISearchOptions | undefined;\n\n /**\n * Gets the currently cached search term.\n */\n public get cachedSearchTerm(): string | undefined {\n return this._cachedSearchTerm;\n }\n\n /**\n * Sets the cached search term.\n */\n public set cachedSearchTerm(term: string | undefined) {\n this._cachedSearchTerm = term;\n }\n\n /**\n * Gets the last search options used.\n */\n public get lastSearchOptions(): ISearchOptions | undefined {\n return this._lastSearchOptions;\n }\n\n /**\n * Sets the last search options used.\n */\n public set lastSearchOptions(options: ISearchOptions | undefined) {\n this._lastSearchOptions = options;\n }\n\n /**\n * Validates a search term to ensure it's not empty or invalid.\n * @param term The search term to validate.\n * @returns true if the term is valid for searching.\n */\n public isValidSearchTerm(term: string): boolean {\n return !!(term && term.length > 0);\n }\n\n /**\n * Determines if search options have changed compared to the last search.\n * @param newOptions The new search options to compare.\n * @returns true if the options have changed.\n */\n public didOptionsChange(newOptions?: ISearchOptions): boolean {\n if (!this._lastSearchOptions) {\n return true;\n }\n if (!newOptions) {\n return false;\n }\n if (this._lastSearchOptions.caseSensitive !== newOptions.caseSensitive) {\n return true;\n }\n if (this._lastSearchOptions.regex !== newOptions.regex) {\n return true;\n }\n if (this._lastSearchOptions.wholeWord !== newOptions.wholeWord) {\n return true;\n }\n return false;\n }\n\n /**\n * Determines if a new search should trigger highlighting updates.\n * @param term The search term.\n * @param options The search options.\n * @returns true if highlighting should be updated.\n */\n public shouldUpdateHighlighting(term: string, options?: ISearchOptions): boolean {\n if (!options?.decorations) {\n return false;\n }\n return this._cachedSearchTerm === undefined ||\n term !== this._cachedSearchTerm ||\n this.didOptionsChange(options);\n }\n\n /**\n * Clears the cached search term.\n */\n public clearCachedTerm(): void {\n this._cachedSearchTerm = undefined;\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this._cachedSearchTerm = undefined;\n this._lastSearchOptions = undefined;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal } from '@xterm/xterm';\nimport type { ISearchOptions } from '@xterm/addon-search';\nimport type { SearchLineCache } from './SearchLineCache';\n\n/**\n * Represents the position to start a search from.\n */\ninterface ISearchPosition {\n startCol: number;\n startRow: number;\n}\n\n/**\n * Represents a search result with its position and content.\n */\nexport interface ISearchResult {\n term: string;\n col: number;\n row: number;\n size: number;\n}\n\n/**\n * Configuration constants for the search engine functionality.\n */\nconst enum Constants {\n /**\n * Characters that are considered non-word characters for search boundary detection. These\n * characters are used to determine word boundaries when performing whole-word searches. Includes\n * common punctuation, symbols, and whitespace characters.\n */\n NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\\\;:\"\\',./<>?'\n}\n\n/**\n * Core search engine that handles finding text within terminal content.\n * This class is responsible for the actual search algorithms and position calculations.\n */\nexport class SearchEngine {\n constructor(\n private readonly _terminal: Terminal,\n private readonly _lineCache: SearchLineCache\n ) {}\n\n /**\n * Find the first occurrence of a term starting from a specific position.\n * @param term The search term.\n * @param startRow The row to start searching from.\n * @param startCol The column to start searching from.\n * @param searchOptions Search options.\n * @returns The search result if found, undefined otherwise.\n */\n public find(term: string, startRow: number, startCol: number, searchOptions?: ISearchOptions): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n if (startCol >= this._terminal.cols) {\n throw new Error(`Invalid col: ${startCol} to search in terminal of ${this._terminal.cols} cols`);\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n if (this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n return result;\n }\n\n /**\n * Find the next occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine incremental behavior.\n * @returns The search result if found, undefined otherwise.\n */\n public findNextWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startCol = 0;\n let startRow = 0;\n if (prevSelectedPos) {\n if (cachedSearchTerm === term) {\n startCol = prevSelectedPos.end.x;\n startRow = prevSelectedPos.end.y;\n } else {\n startCol = prevSelectedPos.start.x;\n startRow = prevSelectedPos.start.y;\n }\n }\n\n this._lineCache.initLinesCache();\n\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n // Search startRow\n let result = this._findInLine(term, searchPosition, searchOptions);\n // Search from startRow + 1 to end\n if (!result) {\n for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {\n if (this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n // If we hit the bottom and didn't search from the very top wrap back up\n if (!result && startRow !== 0) {\n for (let y = 0; y < startRow; y++) {\n // Row 0 is never skipped: it can be a continuation whose line start was trimmed from the\n // scrollback, and nothing earlier in this loop has searched it.\n if (y > 0 && this._isRowCoveredByEarlierSearch(y)) {\n continue;\n }\n searchPosition.startRow = y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n if (result) {\n break;\n }\n }\n }\n\n // If there is only one result, wrap back and return selection if it exists.\n if (!result && prevSelectedPos) {\n searchPosition.startRow = prevSelectedPos.start.y;\n searchPosition.startCol = 0;\n result = this._findInLine(term, searchPosition, searchOptions);\n }\n\n return result;\n }\n\n /**\n * Find the previous occurrence of a term with wrapping and selection management.\n * @param term The search term.\n * @param searchOptions Search options.\n * @param cachedSearchTerm The cached search term to determine if expansion should occur.\n * @returns The search result if found, undefined otherwise.\n */\n public findPreviousWithSelection(term: string, searchOptions?: ISearchOptions, cachedSearchTerm?: string): ISearchResult | undefined {\n if (!term || term.length === 0) {\n this._terminal.clearSelection();\n return undefined;\n }\n\n const prevSelectedPos = this._terminal.getSelectionPosition();\n this._terminal.clearSelection();\n\n let startRow = this._terminal.buffer.active.baseY + this._terminal.rows - 1;\n const startCol = this._terminal.cols;\n const isReverseSearch = true;\n\n this._lineCache.initLinesCache();\n const searchPosition: ISearchPosition = {\n startRow,\n startCol\n };\n\n let result: ISearchResult | undefined;\n if (prevSelectedPos) {\n searchPosition.startRow = startRow = prevSelectedPos.start.y;\n searchPosition.startCol = prevSelectedPos.start.x;\n if (cachedSearchTerm !== term) {\n // Try to expand selection to right first.\n result = this._findInLine(term, searchPosition, searchOptions, false);\n if (!result) {\n // If selection was not able to be expanded to the right, then try reverse search\n searchPosition.startRow = startRow = prevSelectedPos.end.y;\n searchPosition.startCol = prevSelectedPos.end.x;\n }\n }\n }\n\n result ??= this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n\n // Search from startRow - 1 to top\n if (!result) {\n searchPosition.startCol = Math.max(searchPosition.startCol, this._terminal.cols);\n for (let y = startRow - 1; y >= 0; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n // If we hit the top and didn't search from the very bottom wrap back down\n if (!result && startRow !== (this._terminal.buffer.active.baseY + this._terminal.rows - 1)) {\n for (let y = (this._terminal.buffer.active.baseY + this._terminal.rows - 1); y >= startRow; y--) {\n searchPosition.startRow = y;\n result = this._findInLine(term, searchPosition, searchOptions, isReverseSearch);\n if (result) {\n break;\n }\n }\n }\n\n return result;\n }\n\n /**\n * A found substring is a whole word if it doesn't have an alphanumeric character directly\n * adjacent to it.\n * @param searchIndex starting index of the potential whole word substring\n * @param line entire string in which the potential whole word was found\n * @param term the substring that starts at searchIndex\n */\n private _isWholeWord(searchIndex: number, line: string, term: string): boolean {\n return ((searchIndex === 0) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex - 1]))) &&\n (((searchIndex + term.length) === line.length) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex + term.length])));\n }\n\n /** `_isWholeWord` gated on the option, so a rejected hit can be stepped past instead of ending the scan. */\n private _satisfiesWholeWord(searchIndex: number, line: string, term: string, searchOptions: ISearchOptions): boolean {\n return !searchOptions.wholeWord || this._isWholeWord(searchIndex, line, term);\n }\n\n /**\n * Whether an earlier `_findInLine` in this same call already scanned this row's line from an\n * equal or lower offset, which makes rescanning it pure O(rows^2) work on one long line. Sound\n * for every option because `_findInLine` returns the first accepted match at or after its\n * offset, which is monotone in that offset. Only valid once such a search has happened \u2014 the\n * wrap-around loop starts at row 0, whose line start may have been trimmed from the scrollback.\n */\n private _isRowCoveredByEarlierSearch(row: number): boolean {\n return this._terminal.buffer.active.getLine(row)?.isWrapped === true;\n }\n\n /**\n * Searches a line for a search term. Takes the provided terminal line and searches the text line,\n * which may contain subsequent terminal lines if the text is wrapped. If the provided line number\n * is part of a wrapped text line that started on an earlier line then it is skipped since it will\n * be properly searched when the terminal line that the text starts on is searched.\n * @param term The search term.\n * @param searchPosition The position to start the search.\n * @param searchOptions Search options.\n * @param isReverseSearch Whether the search should start from the right side of the terminal and\n * search to the left.\n * @returns The search result if it was found.\n */\n private _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {\n // Ignore wrapped lines, only consider on unwrapped line (first row of command string).\n if (isReverseSearch) {\n // Reverse search never rewinds: its caller carries startCol down the rows of the line. Row 0\n // is searched even when wrapped, since its line start may have been trimmed from the scrollback.\n if (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {\n searchPosition.startCol += this._terminal.cols;\n return;\n }\n } else {\n // A loop rather than recursion: one frame per wrapped row overflows the stack on a line long\n // enough to fill the scrollback. Bounded at row 0 because after a reflow the buffer's ring\n // holds stale entries at negative indices, so `getLine(-1)` answers with a wrapped line.\n while (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {\n searchPosition.startRow--;\n searchPosition.startCol += this._terminal.cols;\n }\n }\n const row = searchPosition.startRow;\n const col = searchPosition.startCol;\n\n let cache = this._lineCache.getLineFromCache(row);\n if (!cache) {\n cache = this._lineCache.translateBufferLineToStringWithWrap(row, true);\n this._lineCache.setLineInCache(row, cache);\n }\n const [stringLine, offsets] = cache;\n\n const offset = this._bufferColsToStringOffset(row, col, offsets);\n let searchTerm = term;\n let searchStringLine = stringLine;\n if (!searchOptions.regex) {\n searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();\n searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();\n }\n\n let resultIndex = -1;\n if (searchOptions.regex) {\n const searchRegex = RegExp(searchTerm, searchOptions.caseSensitive ? 'g' : 'gi');\n let foundTerm: RegExpExecArray | null;\n if (isReverseSearch) {\n // This loop will get the resultIndex of the _last_ regex match in the range 0..offset\n while (foundTerm = searchRegex.exec(searchStringLine.slice(0, offset))) {\n const matchIndex = searchRegex.lastIndex - foundTerm[0].length;\n if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {\n resultIndex = matchIndex;\n term = foundTerm[0];\n }\n searchRegex.lastIndex = matchIndex + 1;\n }\n } else {\n // Driven over the whole line from `offset` rather than over `slice(offset)`: a slice\n // re-anchors ^ and \\b at whatever column the row happened to wrap at, and only\n // first-accepted-match-at-or-after-offset is monotone in `offset`, which is what lets\n // `_isRowCoveredByEarlierSearch` skip a wrapped row an earlier scan already covered.\n searchRegex.lastIndex = offset;\n while (foundTerm = searchRegex.exec(searchStringLine)) {\n const matchIndex = searchRegex.lastIndex - foundTerm[0].length;\n if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {\n resultIndex = matchIndex;\n term = foundTerm[0];\n break;\n }\n // A zero-length or rejected match would otherwise repeat forever.\n searchRegex.lastIndex = matchIndex + 1;\n }\n }\n } else if (isReverseSearch) {\n let matchIndex = offset - searchTerm.length >= 0 ? searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length) : -1;\n // `lastIndexOf` clamps a negative fromIndex to 0, so index 0 has to end the walk.\n while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {\n matchIndex = matchIndex > 0 ? searchStringLine.lastIndexOf(searchTerm, matchIndex - 1) : -1;\n }\n resultIndex = matchIndex;\n } else {\n let matchIndex = searchStringLine.indexOf(searchTerm, offset);\n while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {\n matchIndex = searchStringLine.indexOf(searchTerm, matchIndex + 1);\n }\n resultIndex = matchIndex;\n }\n\n if (resultIndex >= 0) {\n // Adjust the row number and search index if needed since a \"line\" of text can span multiple\n // rows\n let startRowOffset = 0;\n while (startRowOffset < offsets.length - 1 && resultIndex >= offsets[startRowOffset + 1]) {\n startRowOffset++;\n }\n let endRowOffset = startRowOffset;\n while (endRowOffset < offsets.length - 1 && resultIndex + term.length >= offsets[endRowOffset + 1]) {\n endRowOffset++;\n }\n const startColOffset = resultIndex - offsets[startRowOffset];\n const endColOffset = resultIndex + term.length - offsets[endRowOffset];\n const startColIndex = this._stringLengthToBufferSize(row + startRowOffset, startColOffset);\n const endColIndex = this._stringLengthToBufferSize(row + endRowOffset, endColOffset);\n const size = endColIndex - startColIndex + this._terminal.cols * (endRowOffset - startRowOffset);\n\n return {\n term,\n col: startColIndex,\n row: row + startRowOffset,\n size\n };\n }\n }\n\n private _stringLengthToBufferSize(row: number, offset: number): number {\n const line = this._terminal.buffer.active.getLine(row);\n if (!line) {\n return 0;\n }\n for (let i = 0; i < offset; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n // Adjust the searchIndex to normalize emoji into single chars\n const char = cell.getChars();\n if (char.length > 1) {\n offset -= char.length - 1;\n }\n // Adjust the searchIndex for empty characters following wide unicode\n // chars (eg. CJK)\n const nextCell = line.getCell(i + 1);\n if (nextCell && nextCell.getWidth() === 0) {\n offset++;\n }\n }\n return offset;\n }\n\n /**\n * `cols` counts from the start of the logical line, so summing the cells of every row before the\n * resume point costs O(line) per call and the highlight-all pass makes one call per match.\n * `lineOffsets` already holds the string offset each wrapped row starts at \u2014 the same map used\n * above to turn a match index back into a row \u2014 so only the last, partial row needs cells. It is\n * also the map the row a match lands on is read from, which the cell sum disagreed with by one\n * for a row whose trailing cell is the null placeholder of a wide character that wrapped.\n */\n private _bufferColsToStringOffset(startRow: number, cols: number, lineOffsets: number[]): number {\n const rowsBack = Math.min(Math.floor(cols / this._terminal.cols), lineOffsets.length - 1);\n let offset = lineOffsets[rowsBack];\n const line = this._terminal.buffer.active.getLine(startRow + rowsBack);\n if (line) {\n const colsInRow = Math.min(cols - rowsBack * this._terminal.cols, this._terminal.cols);\n for (let i = 0; i < colsInRow; i++) {\n const cell = line.getCell(i);\n if (!cell) {\n break;\n }\n if (cell.getWidth()) {\n // Treat null characters as whitespace to align with the translateToString API\n offset += cell.getCode() === 0 ? 1 : cell.getChars().length;\n }\n }\n }\n return offset;\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, IDecoration } from '@xterm/xterm';\nimport type { ISearchDecorationOptions } from '@xterm/addon-search';\nimport { dispose, Disposable, toDisposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a highlight decoration.\n */\ninterface IHighlight extends IDisposable {\n decoration: IDecoration;\n match: ISearchResult;\n}\n\n/**\n * Interface for managing multiple decorations for a single match.\n */\ninterface IMultiHighlight extends IDisposable {\n decorations: IDecoration[];\n match: ISearchResult;\n}\n\n/**\n * Manages visual decorations for search results including highlighting and active selection\n * indicators. This class handles the creation, styling, and disposal of search-related decorations.\n */\nexport class DecorationManager extends Disposable {\n private _highlightDecorations: IHighlight[] = [];\n private _highlightedLines: Set<number> = new Set();\n\n constructor(private readonly _terminal: Terminal) {\n super();\n this._register(toDisposable(() => this.clearHighlightDecorations()));\n }\n\n /**\n * Creates decorations for all provided search results.\n * @param results The search results to create decorations for.\n * @param options The decoration options.\n */\n public createHighlightDecorations(results: ISearchResult[], options: ISearchDecorationOptions): void {\n this.clearHighlightDecorations();\n\n for (const match of results) {\n const decorations = this._createResultDecorations(match, options, false);\n if (decorations) {\n for (const decoration of decorations) {\n this._storeDecoration(decoration, match);\n }\n }\n }\n }\n\n /**\n * Creates decorations for the currently active search result.\n * @param result The active search result.\n * @param options The decoration options.\n * @returns The multi-highlight decoration or undefined if creation failed.\n */\n public createActiveDecoration(result: ISearchResult, options: ISearchDecorationOptions): IMultiHighlight | undefined {\n const decorations = this._createResultDecorations(result, options, true);\n if (decorations) {\n return { decorations, match: result, dispose() { dispose(decorations); } };\n }\n return undefined;\n }\n\n /**\n * Clears all highlight decorations.\n */\n public clearHighlightDecorations(): void {\n dispose(this._highlightDecorations);\n this._highlightDecorations = [];\n this._highlightedLines.clear();\n }\n\n /**\n * Stores a decoration and tracks it for management.\n * @param decoration The decoration to store.\n * @param match The search result this decoration represents.\n */\n private _storeDecoration(decoration: IDecoration, match: ISearchResult): void {\n this._highlightedLines.add(decoration.marker.line);\n this._highlightDecorations.push({ decoration, match, dispose() { decoration.dispose(); } });\n }\n\n /**\n * Applies styles to the decoration when it is rendered.\n * @param element The decoration's element.\n * @param borderColor The border color to apply.\n * @param isActiveResult Whether the element is part of the active search result.\n */\n private _applyStyles(element: HTMLElement, borderColor: string | undefined, isActiveResult: boolean): void {\n if (!element.classList.contains('xterm-find-result-decoration')) {\n element.classList.add('xterm-find-result-decoration');\n if (borderColor) {\n element.style.outline = `1px solid ${borderColor}`;\n }\n }\n if (isActiveResult) {\n element.classList.add('xterm-find-active-result-decoration');\n }\n }\n\n /**\n * Creates a decoration for the result and applies styles\n * @param result the search result for which to create the decoration\n * @param options the options for the decoration\n * @param isActiveResult whether this is the currently active result\n * @returns the decorations or undefined if the marker has already been disposed of\n */\n private _createResultDecorations(result: ISearchResult, options: ISearchDecorationOptions, isActiveResult: boolean): IDecoration[] | undefined {\n // Gather decoration ranges for this match as it could wrap\n const decorationRanges: [number, number, number][] = [];\n let currentCol = result.col;\n let remainingSize = result.size;\n let markerOffset = -this._terminal.buffer.active.baseY - this._terminal.buffer.active.cursorY + result.row;\n while (remainingSize > 0) {\n const amountThisRow = Math.min(this._terminal.cols - currentCol, remainingSize);\n decorationRanges.push([markerOffset, currentCol, amountThisRow]);\n currentCol = 0;\n remainingSize -= amountThisRow;\n markerOffset++;\n }\n\n // Create the decorations\n const decorations: IDecoration[] = [];\n for (const range of decorationRanges) {\n const marker = this._terminal.registerMarker(range[0]);\n const decoration = this._terminal.registerDecoration({\n marker,\n x: range[1],\n width: range[2],\n layer: isActiveResult ? 'top' : 'bottom',\n backgroundColor: isActiveResult ? options.activeMatchBackground : options.matchBackground,\n overviewRulerOptions: this._highlightedLines.has(marker.line) ? undefined : {\n color: isActiveResult ? options.activeMatchColorOverviewRuler : options.matchOverviewRuler,\n position: 'center'\n }\n });\n if (decoration) {\n const disposables: IDisposable[] = [];\n disposables.push(marker);\n disposables.push(decoration.onRender((e) => this._applyStyles(e, isActiveResult ? options.activeMatchBorder : options.matchBorder, false)));\n disposables.push(decoration.onDispose(() => dispose(disposables)));\n decorations.push(decoration);\n }\n }\n\n return decorations.length === 0 ? undefined : decorations;\n }\n}\n\n\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { ISearchResultChangeEvent } from '@xterm/addon-search';\nimport type { IDisposable } from '@xterm/xterm';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable } from 'common/Lifecycle';\nimport type { ISearchResult } from './SearchEngine';\n\n/**\n * Interface for managing a currently selected decoration.\n */\ninterface ISelectedDecoration extends IDisposable {\n match: ISearchResult;\n}\n\n/**\n * Tracks search results, manages result indexing, and fires events when results change.\n * This class provides centralized management of search result state and notifications.\n */\nexport class SearchResultTracker extends Disposable {\n private _searchResults: ISearchResult[] = [];\n private _selectedDecoration: ISelectedDecoration | undefined;\n\n private readonly _onDidChangeResults = this._register(new Emitter<ISearchResultChangeEvent>());\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> { return this._onDidChangeResults.event; }\n\n /**\n * Gets the current search results.\n */\n public get searchResults(): ReadonlyArray<ISearchResult> {\n return this._searchResults;\n }\n\n /**\n * Gets the currently selected decoration.\n */\n public get selectedDecoration(): ISelectedDecoration | undefined {\n return this._selectedDecoration;\n }\n\n /**\n * Sets the currently selected decoration.\n */\n public set selectedDecoration(decoration: ISelectedDecoration | undefined) {\n this._selectedDecoration = decoration;\n }\n\n /**\n * Updates the search results with a new set of results.\n * @param results The new search results.\n * @param maxResults The maximum number of results to track.\n */\n public updateResults(results: ISearchResult[], maxResults: number): void {\n this._searchResults = results.slice(0, maxResults);\n }\n\n /**\n * Clears all search results.\n */\n public clearResults(): void {\n this._searchResults = [];\n }\n\n /**\n * Clears the selected decoration.\n */\n public clearSelectedDecoration(): void {\n if (this._selectedDecoration) {\n this._selectedDecoration.dispose();\n this._selectedDecoration = undefined;\n }\n }\n\n /**\n * Finds the index of a result in the current results array.\n * @param result The result to find.\n * @returns The index of the result, or -1 if not found.\n */\n public findResultIndex(result: ISearchResult): number {\n for (let i = 0; i < this._searchResults.length; i++) {\n const match = this._searchResults[i];\n if (match.row === result.row && match.col === result.col && match.size === result.size) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Fires a result change event with the current state.\n * @param hasDecorations Whether decorations are enabled.\n */\n public fireResultsChanged(hasDecorations: boolean): void {\n if (!hasDecorations) {\n return;\n }\n\n let resultIndex = -1;\n if (this._selectedDecoration) {\n resultIndex = this.findResultIndex(this._selectedDecoration.match);\n }\n\n this._onDidChangeResults.fire({\n resultIndex,\n resultCount: this._searchResults.length\n });\n }\n\n /**\n * Resets all state.\n */\n public reset(): void {\n this.clearSelectedDecoration();\n this.clearResults();\n }\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport type { Terminal, IDisposable, ITerminalAddon } from '@xterm/xterm';\nimport type { SearchAddon as ISearchApi, ISearchOptions, ISearchAddonOptions, ISearchResultChangeEvent, ISearchDecorationOptions } from '@xterm/addon-search';\nimport { Emitter, type IEvent } from 'common/Event';\nimport { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';\nimport { disposableTimeout } from 'common/Async';\nimport { SearchLineCache } from './SearchLineCache';\nimport { SearchState } from './SearchState';\nimport { SearchEngine, type ISearchResult } from './SearchEngine';\nimport { DecorationManager } from './DecorationManager';\nimport { SearchResultTracker } from './SearchResultTracker';\n\ninterface IInternalSearchOptions {\n noScroll: boolean;\n}\n\n/**\n * Configuration constants for the search addon functionality.\n */\nconst enum Constants {\n /**\n * Default maximum number of search results to highlight simultaneously. This limit prevents\n * performance degradation when searching for very common terms that would result in excessive\n * highlighting decorations.\n */\n DEFAULT_HIGHLIGHT_LIMIT = 1000\n}\n\nexport class SearchAddon extends Disposable implements ITerminalAddon, ISearchApi {\n private _terminal: Terminal | undefined;\n private _highlightLimit: number;\n private _highlightTimeout = this._register(new MutableDisposable<IDisposable>());\n private _lineCache = this._register(new MutableDisposable<SearchLineCache>());\n\n // Component instances\n private _state = new SearchState();\n private _engine: SearchEngine | undefined;\n private _decorationManager: DecorationManager | undefined;\n private _resultTracker = this._register(new SearchResultTracker());\n\n private readonly _onAfterSearch = this._register(new Emitter<void>());\n public readonly onAfterSearch = this._onAfterSearch.event;\n private readonly _onBeforeSearch = this._register(new Emitter<void>());\n public readonly onBeforeSearch = this._onBeforeSearch.event;\n\n public get onDidChangeResults(): IEvent<ISearchResultChangeEvent> {\n return this._resultTracker.onDidChangeResults;\n }\n\n constructor(options?: Partial<ISearchAddonOptions>) {\n super();\n\n this._highlightLimit = options?.highlightLimit ?? Constants.DEFAULT_HIGHLIGHT_LIMIT;\n }\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n this._lineCache.value = new SearchLineCache(terminal);\n this._engine = new SearchEngine(terminal, this._lineCache.value);\n this._decorationManager = new DecorationManager(terminal);\n this._register(this._terminal.onWriteParsed(() => this._updateMatches()));\n this._register(this._terminal.onResize(() => this._updateMatches()));\n this._register(toDisposable(() => this.clearDecorations()));\n }\n\n private _updateMatches(): void {\n this._highlightTimeout.clear();\n if (this._state.cachedSearchTerm && this._state.lastSearchOptions?.decorations) {\n this._highlightTimeout.value = disposableTimeout(() => {\n const term = this._state.cachedSearchTerm;\n this._state.clearCachedTerm();\n this.findPrevious(term!, { ...this._state.lastSearchOptions, incremental: true }, { noScroll: true });\n }, 200);\n }\n }\n\n public clearDecorations(retainCachedSearchTerm?: boolean): void {\n this._resultTracker.clearSelectedDecoration();\n this._decorationManager?.clearHighlightDecorations();\n this._resultTracker.clearResults();\n if (!retainCachedSearchTerm) {\n this._state.clearCachedTerm();\n }\n }\n\n public clearActiveDecoration(): void {\n this._resultTracker.clearSelectedDecoration();\n }\n\n /**\n * Find the next instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findNext(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findNextAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _highlightAllMatches(term: string, searchOptions: ISearchOptions): void {\n if (!this._terminal || !this._engine || !this._decorationManager) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n if (!this._state.isValidSearchTerm(term)) {\n this.clearDecorations();\n return;\n }\n\n // new search, clear out the old decorations\n this.clearDecorations(true);\n\n const results: ISearchResult[] = [];\n let prevResult: ISearchResult | undefined = undefined;\n let result = this._engine.find(term, 0, 0, searchOptions);\n\n while (result && (prevResult?.row !== result.row || prevResult?.col !== result.col)) {\n if (results.length >= this._highlightLimit) {\n break;\n }\n prevResult = result;\n results.push(prevResult);\n const cols = this._terminal.cols;\n let nextCol = prevResult.col + prevResult.size;\n let nextRow = prevResult.row;\n if (nextCol >= cols) {\n nextRow += Math.floor(nextCol / cols);\n nextCol = nextCol % cols;\n }\n result = this._engine.find(term, nextRow, nextCol, searchOptions);\n }\n\n this._resultTracker.updateResults(results, this._highlightLimit);\n if (searchOptions.decorations) {\n this._decorationManager.createHighlightDecorations(results, searchOptions.decorations);\n }\n }\n\n private _findNextAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findNextWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Find the previous instance of the term, then scroll to and select it. If it\n * doesn't exist, do nothing.\n * @param term The search term.\n * @param searchOptions Search options.\n * @returns Whether a result was found.\n */\n public findPrevious(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n this._onBeforeSearch.fire();\n\n this._state.lastSearchOptions = searchOptions;\n\n if (this._state.shouldUpdateHighlighting(term, searchOptions)) {\n this._highlightAllMatches(term, searchOptions!);\n }\n\n const found = this._findPreviousAndSelect(term, searchOptions, internalSearchOptions);\n this._fireResults(searchOptions);\n this._state.cachedSearchTerm = term;\n\n this._onAfterSearch.fire();\n\n return found;\n }\n\n private _fireResults(searchOptions?: ISearchOptions): void {\n this._resultTracker.fireResultsChanged(!!searchOptions?.decorations);\n }\n\n private _findPreviousAndSelect(term: string, searchOptions?: ISearchOptions, internalSearchOptions?: IInternalSearchOptions): boolean {\n if (!this._terminal || !this._engine) {\n return false;\n }\n if (!this._state.isValidSearchTerm(term)) {\n this._terminal.clearSelection();\n this.clearDecorations();\n return false;\n }\n\n const result = this._engine.findPreviousWithSelection(term, searchOptions, this._state.cachedSearchTerm);\n return this._selectResult(result, searchOptions?.decorations, internalSearchOptions?.noScroll);\n }\n\n /**\n * Selects and scrolls to a result.\n * @param result The result to select.\n * @returns Whether a result was selected.\n */\n private _selectResult(result: ISearchResult | undefined, options?: ISearchDecorationOptions, noScroll?: boolean): boolean {\n if (!this._terminal || !this._decorationManager) {\n return false;\n }\n\n this._resultTracker.clearSelectedDecoration();\n if (!result) {\n this._terminal.clearSelection();\n return false;\n }\n\n this._terminal.select(result.col, result.row, result.size);\n if (options) {\n const activeDecoration = this._decorationManager.createActiveDecoration(result, options);\n if (activeDecoration) {\n this._resultTracker.selectedDecoration = activeDecoration;\n }\n }\n\n if (!noScroll) {\n // If it is not in the viewport then we scroll else it just gets selected\n if (result.row >= (this._terminal.buffer.active.viewportY + this._terminal.rows) || result.row < this._terminal.buffer.active.viewportY) {\n let scroll = result.row - this._terminal.buffer.active.viewportY;\n scroll -= Math.floor(this._terminal.rows / 2);\n this._terminal.scrollLines(scroll);\n }\n }\n return true;\n }\n}\n"],
+ "mappings": "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",
+ "names": ["toDisposable", "fn", "dispose", "arg", "d", "combinedDisposable", "disposables", "DisposableStore", "o", "Disposable", "MutableDisposable", "value", "Emitter", "listener", "thisArgs", "disposables", "toDisposable", "entry", "result", "idx", "event", "listeners", "i", "len", "EventUtils", "forward", "from", "to", "e", "map", "any", "events", "store", "DisposableStore", "runAndSubscribe", "handler", "initial", "disposableTimeout", "handler", "timeout", "store", "timer", "disposable", "toDisposable", "SearchLineCache", "Disposable", "_terminal", "MutableDisposable", "toDisposable", "combinedDisposable", "delay", "disposableTimeout", "elapsed", "row", "entry", "lineIndex", "trimRight", "strings", "lineOffsets", "bufferLength", "line", "nextLine", "lineWrapsToNext", "string", "lastCell", "SearchState", "term", "options", "newOptions", "SearchEngine", "_terminal", "_lineCache", "term", "startRow", "startCol", "searchOptions", "searchPosition", "result", "y", "cachedSearchTerm", "prevSelectedPos", "isReverseSearch", "searchIndex", "line", "row", "col", "cache", "stringLine", "offsets", "offset", "searchTerm", "searchStringLine", "resultIndex", "searchRegex", "foundTerm", "matchIndex", "startRowOffset", "endRowOffset", "startColOffset", "endColOffset", "startColIndex", "size", "i", "cell", "char", "nextCell", "cols", "lineOffsets", "rowsBack", "colsInRow", "DecorationManager", "Disposable", "_terminal", "toDisposable", "results", "options", "match", "decorations", "decoration", "result", "dispose", "element", "borderColor", "isActiveResult", "decorationRanges", "currentCol", "remainingSize", "markerOffset", "amountThisRow", "range", "marker", "disposables", "e", "SearchResultTracker", "Disposable", "Emitter", "decoration", "results", "maxResults", "result", "i", "match", "hasDecorations", "resultIndex", "SearchAddon", "Disposable", "options", "MutableDisposable", "SearchState", "SearchResultTracker", "Emitter", "terminal", "SearchLineCache", "SearchEngine", "DecorationManager", "toDisposable", "disposableTimeout", "term", "retainCachedSearchTerm", "searchOptions", "internalSearchOptions", "found", "results", "prevResult", "result", "cols", "nextCol", "nextRow", "noScroll", "activeDecoration", "scroll"]
}
diff --git a/src/SearchEngine.ts b/src/SearchEngine.ts
index 1760bc2bd1fd274d23e2032fde631b39c739f0d9..5b3c5cc5e861356b87e8a15c55797f45bac20a5c 100644
--- a/src/SearchEngine.ts
+++ b/src/SearchEngine.ts
@@ -76,6 +76,9 @@ export class SearchEngine {
// Search from startRow + 1 to end
if (!result) {
for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {
+ if (this._isRowCoveredByEarlierSearch(y)) {
+ continue;
+ }
searchPosition.startRow = y;
searchPosition.startCol = 0;
result = this._findInLine(term, searchPosition, searchOptions);
@@ -127,6 +130,9 @@ export class SearchEngine {
// Search from startRow + 1 to end
if (!result) {
for (let y = startRow + 1; y < this._terminal.buffer.active.baseY + this._terminal.rows; y++) {
+ if (this._isRowCoveredByEarlierSearch(y)) {
+ continue;
+ }
searchPosition.startRow = y;
searchPosition.startCol = 0;
result = this._findInLine(term, searchPosition, searchOptions);
@@ -138,6 +144,11 @@ export class SearchEngine {
// If we hit the bottom and didn't search from the very top wrap back up
if (!result && startRow !== 0) {
for (let y = 0; y < startRow; y++) {
+ // Row 0 is never skipped: it can be a continuation whose line start was trimmed from the
+ // scrollback, and nothing earlier in this loop has searched it.
+ if (y > 0 && this._isRowCoveredByEarlierSearch(y)) {
+ continue;
+ }
searchPosition.startRow = y;
searchPosition.startCol = 0;
result = this._findInLine(term, searchPosition, searchOptions);
@@ -237,6 +248,22 @@ export class SearchEngine {
(((searchIndex + term.length) === line.length) || (Constants.NON_WORD_CHARACTERS.includes(line[searchIndex + term.length])));
}
+ /** `_isWholeWord` gated on the option, so a rejected hit can be stepped past instead of ending the scan. */
+ private _satisfiesWholeWord(searchIndex: number, line: string, term: string, searchOptions: ISearchOptions): boolean {
+ return !searchOptions.wholeWord || this._isWholeWord(searchIndex, line, term);
+ }
+
+ /**
+ * Whether an earlier `_findInLine` in this same call already scanned this row's line from an
+ * equal or lower offset, which makes rescanning it pure O(rows^2) work on one long line. Sound
+ * for every option because `_findInLine` returns the first accepted match at or after its
+ * offset, which is monotone in that offset. Only valid once such a search has happened — the
+ * wrap-around loop starts at row 0, whose line start may have been trimmed from the scrollback.
+ */
+ private _isRowCoveredByEarlierSearch(row: number): boolean {
+ return this._terminal.buffer.active.getLine(row)?.isWrapped === true;
+ }
+
/**
* Searches a line for a search term. Takes the provided terminal line and searches the text line,
* which may contain subsequent terminal lines if the text is wrapped. If the provided line number
@@ -250,23 +277,26 @@ export class SearchEngine {
* @returns The search result if it was found.
*/
private _findInLine(term: string, searchPosition: ISearchPosition, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult | undefined {
- const row = searchPosition.startRow;
- const col = searchPosition.startCol;
-
// Ignore wrapped lines, only consider on unwrapped line (first row of command string).
- const firstLine = this._terminal.buffer.active.getLine(row);
- if (firstLine?.isWrapped) {
- if (isReverseSearch) {
+ if (isReverseSearch) {
+ // Reverse search never rewinds: its caller carries startCol down the rows of the line. Row 0
+ // is searched even when wrapped, since its line start may have been trimmed from the scrollback.
+ if (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {
searchPosition.startCol += this._terminal.cols;
return;
}
-
- // This will iterate until we find the line start.
- // When we find it, we will search using the calculated start column.
- searchPosition.startRow--;
- searchPosition.startCol += this._terminal.cols;
- return this._findInLine(term, searchPosition, searchOptions);
+ } else {
+ // A loop rather than recursion: one frame per wrapped row overflows the stack on a line long
+ // enough to fill the scrollback. Bounded at row 0 because after a reflow the buffer's ring
+ // holds stale entries at negative indices, so `getLine(-1)` answers with a wrapped line.
+ while (searchPosition.startRow > 0 && this._terminal.buffer.active.getLine(searchPosition.startRow)?.isWrapped) {
+ searchPosition.startRow--;
+ searchPosition.startCol += this._terminal.cols;
+ }
}
+ const row = searchPosition.startRow;
+ const col = searchPosition.startCol;
+
let cache = this._lineCache.getLineFromCache(row);
if (!cache) {
cache = this._lineCache.translateBufferLineToStringWithWrap(row, true);
@@ -274,7 +304,7 @@ export class SearchEngine {
}
const [stringLine, offsets] = cache;
- const offset = this._bufferColsToStringOffset(row, col);
+ const offset = this._bufferColsToStringOffset(row, col, offsets);
let searchTerm = term;
let searchStringLine = stringLine;
if (!searchOptions.regex) {
@@ -289,32 +319,46 @@ export class SearchEngine {
if (isReverseSearch) {
// This loop will get the resultIndex of the _last_ regex match in the range 0..offset
while (foundTerm = searchRegex.exec(searchStringLine.slice(0, offset))) {
- resultIndex = searchRegex.lastIndex - foundTerm[0].length;
- term = foundTerm[0];
- searchRegex.lastIndex -= (term.length - 1);
+ const matchIndex = searchRegex.lastIndex - foundTerm[0].length;
+ if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {
+ resultIndex = matchIndex;
+ term = foundTerm[0];
+ }
+ searchRegex.lastIndex = matchIndex + 1;
}
} else {
- foundTerm = searchRegex.exec(searchStringLine.slice(offset));
- if (foundTerm && foundTerm[0].length > 0) {
- resultIndex = offset + (searchRegex.lastIndex - foundTerm[0].length);
- term = foundTerm[0];
+ // Driven over the whole line from `offset` rather than over `slice(offset)`: a slice
+ // re-anchors ^ and \b at whatever column the row happened to wrap at, and only
+ // first-accepted-match-at-or-after-offset is monotone in `offset`, which is what lets
+ // `_isRowCoveredByEarlierSearch` skip a wrapped row an earlier scan already covered.
+ searchRegex.lastIndex = offset;
+ while (foundTerm = searchRegex.exec(searchStringLine)) {
+ const matchIndex = searchRegex.lastIndex - foundTerm[0].length;
+ if (foundTerm[0].length > 0 && this._satisfiesWholeWord(matchIndex, searchStringLine, foundTerm[0], searchOptions)) {
+ resultIndex = matchIndex;
+ term = foundTerm[0];
+ break;
+ }
+ // A zero-length or rejected match would otherwise repeat forever.
+ searchRegex.lastIndex = matchIndex + 1;
}
}
+ } else if (isReverseSearch) {
+ let matchIndex = offset - searchTerm.length >= 0 ? searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length) : -1;
+ // `lastIndexOf` clamps a negative fromIndex to 0, so index 0 has to end the walk.
+ while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {
+ matchIndex = matchIndex > 0 ? searchStringLine.lastIndexOf(searchTerm, matchIndex - 1) : -1;
+ }
+ resultIndex = matchIndex;
} else {
- if (isReverseSearch) {
- if (offset - searchTerm.length >= 0) {
- resultIndex = searchStringLine.lastIndexOf(searchTerm, offset - searchTerm.length);
- }
- } else {
- resultIndex = searchStringLine.indexOf(searchTerm, offset);
+ let matchIndex = searchStringLine.indexOf(searchTerm, offset);
+ while (matchIndex >= 0 && !this._satisfiesWholeWord(matchIndex, searchStringLine, searchTerm, searchOptions)) {
+ matchIndex = searchStringLine.indexOf(searchTerm, matchIndex + 1);
}
+ resultIndex = matchIndex;
}
if (resultIndex >= 0) {
- if (searchOptions.wholeWord && !this._isWholeWord(resultIndex, searchStringLine, term)) {
- return;
- }
-
// Adjust the row number and search index if needed since a "line" of text can span multiple
// rows
let startRowOffset = 0;
@@ -365,12 +409,21 @@ export class SearchEngine {
return offset;
}
- private _bufferColsToStringOffset(startRow: number, cols: number): number {
- let lineIndex = startRow;
- let offset = 0;
- let line = this._terminal.buffer.active.getLine(lineIndex);
- while (cols > 0 && line) {
- for (let i = 0; i < cols && i < this._terminal.cols; i++) {
+ /**
+ * `cols` counts from the start of the logical line, so summing the cells of every row before the
+ * resume point costs O(line) per call and the highlight-all pass makes one call per match.
+ * `lineOffsets` already holds the string offset each wrapped row starts at — the same map used
+ * above to turn a match index back into a row — so only the last, partial row needs cells. It is
+ * also the map the row a match lands on is read from, which the cell sum disagreed with by one
+ * for a row whose trailing cell is the null placeholder of a wide character that wrapped.
+ */
+ private _bufferColsToStringOffset(startRow: number, cols: number, lineOffsets: number[]): number {
+ const rowsBack = Math.min(Math.floor(cols / this._terminal.cols), lineOffsets.length - 1);
+ let offset = lineOffsets[rowsBack];
+ const line = this._terminal.buffer.active.getLine(startRow + rowsBack);
+ if (line) {
+ const colsInRow = Math.min(cols - rowsBack * this._terminal.cols, this._terminal.cols);
+ for (let i = 0; i < colsInRow; i++) {
const cell = line.getCell(i);
if (!cell) {
break;
@@ -380,12 +433,6 @@ export class SearchEngine {
offset += cell.getCode() === 0 ? 1 : cell.getChars().length;
}
}
- lineIndex++;
- line = this._terminal.buffer.active.getLine(lineIndex);
- if (line && !line.isWrapped) {
- break;
- }
- cols -= this._terminal.cols;
}
return offset;
}
diff --git a/src/SearchLineCache.ts b/src/SearchLineCache.ts
index 526f4bfcc74a881bb39b400ec79a25d33d602303..19b22f2f70e50a6b01d07966e15727cc5271c776 100644
--- a/src/SearchLineCache.ts
+++ b/src/SearchLineCache.ts
@@ -109,9 +109,13 @@ export class SearchLineCache extends Disposable {
public translateBufferLineToStringWithWrap(lineIndex: number, trimRight: boolean): LineCacheEntry {
const strings = [];
const lineOffsets = [0];
+ // A single line longer than the whole scrollback leaves every buffer row wrapped, and the
+ // buffer's ring answers an out-of-range row by cycling back to the start, so an unbounded walk
+ // never reaches an unwrapped line.
+ const bufferLength = this._terminal.buffer.active.length;
let line = this._terminal.buffer.active.getLine(lineIndex);
while (line) {
- const nextLine = this._terminal.buffer.active.getLine(lineIndex + 1);
+ const nextLine = lineIndex + 1 < bufferLength ? this._terminal.buffer.active.getLine(lineIndex + 1) : undefined;
const lineWrapsToNext = nextLine ? nextLine.isWrapped : false;
let string = line.translateToString(!lineWrapsToNext && trimRight);
if (lineWrapsToNext && nextLine) {