From 8ffcbd98c46b8705c5a9171edbbe8df20f90a59b Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:48:11 -0700 Subject: [PATCH 1/3] Replace timeout handling with disposableTimeout - Use disposableTimeout instead of manual timeout management - Replace MutableDisposable pattern for SearchAddon highlight timeout - Replace SearchLineCache timeout with MutableDisposable approach - Clean up timeout disposal logic in both classes --- addons/addon-search/src/SearchAddon.ts | 15 +++++---------- addons/addon-search/src/SearchLineCache.ts | 11 ++++------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/addons/addon-search/src/SearchAddon.ts b/addons/addon-search/src/SearchAddon.ts index 84ec40f7..93d57bce 100644 --- a/addons/addon-search/src/SearchAddon.ts +++ b/addons/addon-search/src/SearchAddon.ts @@ -7,6 +7,7 @@ import type { Terminal, IDisposable, ITerminalAddon, IDecoration } from '@xterm/ import type { SearchAddon as ISearchApi, ISearchOptions, ISearchDecorationOptions } from '@xterm/addon-search'; import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, dispose, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { disposableTimeout } from 'vs/base/common/async'; import { SearchLineCache } from './SearchLineCache'; interface IInternalSearchOptions { @@ -34,8 +35,6 @@ export interface ISearchResult { size: number; } - - interface IHighlight extends IDisposable { decoration: IDecoration; match: ISearchResult; @@ -57,8 +56,6 @@ const enum Constants { */ NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\;:"\',./<>?', - - /** * Default maximum number of search results to highlight simultaneously. This limit prevents * performance degradation when searching for very common terms that would result in excessive @@ -73,10 +70,10 @@ export class SearchAddon extends Disposable implements ITerminalAddon, ISearchAp private _highlightedLines: Set = new Set(); private _highlightDecorations: IHighlight[] = []; private _searchResultsWithHighlight: ISearchResult[] = []; - private _selectedDecoration: MutableDisposable = this._register(new MutableDisposable()); + private _selectedDecoration = this._register(new MutableDisposable()); private _highlightLimit: number; private _lastSearchOptions: ISearchOptions | undefined; - private _highlightTimeout: number | undefined; + private _highlightTimeout = this._register(new MutableDisposable()); private _lineCache = this._register(new MutableDisposable()); private readonly _onDidChangeResults = this._register(new Emitter()); @@ -97,11 +94,9 @@ export class SearchAddon extends Disposable implements ITerminalAddon, ISearchAp } private _updateMatches(): void { - if (this._highlightTimeout) { - window.clearTimeout(this._highlightTimeout); - } + this._highlightTimeout.clear(); if (this._cachedSearchTerm && this._lastSearchOptions?.decorations) { - this._highlightTimeout = setTimeout(() => { + this._highlightTimeout.value = disposableTimeout(() => { const term = this._cachedSearchTerm; this._cachedSearchTerm = undefined; this.findPrevious(term!, { ...this._lastSearchOptions, incremental: true }, { noScroll: true }); diff --git a/addons/addon-search/src/SearchLineCache.ts b/addons/addon-search/src/SearchLineCache.ts index f4752c55..94d9fb72 100644 --- a/addons/addon-search/src/SearchLineCache.ts +++ b/addons/addon-search/src/SearchLineCache.ts @@ -5,6 +5,7 @@ import type { Terminal } from '@xterm/xterm'; import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { disposableTimeout } from 'vs/base/common/async'; export type LineCacheEntry = [ /** @@ -35,7 +36,7 @@ export class SearchLineCache extends Disposable { * _linesCache is also invalidated when the terminal cursor moves. */ private _linesCache: LineCacheEntry[] | undefined; - private _linesCacheTimeoutId = 0; + private _linesCacheTimeout = this._register(new MutableDisposable()); private _linesCacheDisposables = this._register(new MutableDisposable()); constructor(private _terminal: Terminal) { @@ -56,17 +57,13 @@ export class SearchLineCache extends Disposable { ); } - window.clearTimeout(this._linesCacheTimeoutId); - this._linesCacheTimeoutId = window.setTimeout(() => this._destroyLinesCache(), Constants.LINES_CACHE_TIME_TO_LIVE); + this._linesCacheTimeout.value = disposableTimeout(() => this._destroyLinesCache(), Constants.LINES_CACHE_TIME_TO_LIVE); } private _destroyLinesCache(): void { this._linesCache = undefined; this._linesCacheDisposables.clear(); - if (this._linesCacheTimeoutId) { - window.clearTimeout(this._linesCacheTimeoutId); - this._linesCacheTimeoutId = 0; - } + this._linesCacheTimeout.clear(); } public getLineFromCache(row: number): LineCacheEntry | undefined { From 90bf20d9d8b5481129f1243034248c558ae40745 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:02:27 -0700 Subject: [PATCH 2/3] Remove Thenable --- src/browser/tsconfig.json | 3 +-- src/vs/base/common/async.ts | 2 +- src/vs/typings/thenable.d.ts | 12 ------------ 3 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/vs/typings/thenable.d.ts diff --git a/src/browser/tsconfig.json b/src/browser/tsconfig.json index 38854e26..d8f3a189 100644 --- a/src/browser/tsconfig.json +++ b/src/browser/tsconfig.json @@ -7,8 +7,7 @@ ], "outDir": "../../out", "types": [ - "../../node_modules/@types/mocha", - "../vs/typings/thenable.d.ts" + "../../node_modules/@types/mocha" ], "baseUrl": "..", "paths": { diff --git a/src/vs/base/common/async.ts b/src/vs/base/common/async.ts index 20f15f32..c0b2669f 100644 --- a/src/vs/base/common/async.ts +++ b/src/vs/base/common/async.ts @@ -124,7 +124,7 @@ export function raceTimeout(promise: Promise, timeout: number, onTimeout?: ]); } -export function asPromise(callback: () => T | Thenable): Promise { +export function asPromise(callback: () => T | PromiseLike): Promise { return new Promise((resolve, reject) => { const item = callback(); if (isThenable(item)) { diff --git a/src/vs/typings/thenable.d.ts b/src/vs/typings/thenable.d.ts deleted file mode 100644 index 73373ead..00000000 --- a/src/vs/typings/thenable.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -/** - * Thenable is a common denominator between ES6 promises, Q, jquery.Deferred, WinJS.Promise, - * and others. This API makes no assumption about what promise library is being used which - * enables reusing existing code without migrating to a specific promise implementation. Still, - * we recommend the use of native promises which are available in VS Code. - */ -interface Thenable extends PromiseLike { } From c27af4fa2eab3ef888f6792f0b0fc0e728976758 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Wed, 17 Sep 2025 15:06:33 -0700 Subject: [PATCH 3/3] Remove thenable from more places --- addons/addon-progress/src/tsconfig.json | 3 +-- addons/addon-webgl/src/tsconfig.json | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/addon-progress/src/tsconfig.json b/addons/addon-progress/src/tsconfig.json index ffc7b01a..8c9bc2fe 100644 --- a/addons/addon-progress/src/tsconfig.json +++ b/addons/addon-progress/src/tsconfig.json @@ -12,8 +12,7 @@ "removeComments": true, "strict": true, "types": [ - "../../../node_modules/@types/mocha", - "../../../src/vs/typings/thenable" + "../../../node_modules/@types/mocha" ], "paths": { "browser/*": [ diff --git a/addons/addon-webgl/src/tsconfig.json b/addons/addon-webgl/src/tsconfig.json index 6f1fefe8..55d754d7 100644 --- a/addons/addon-webgl/src/tsconfig.json +++ b/addons/addon-webgl/src/tsconfig.json @@ -29,8 +29,7 @@ "downlevelIteration": true, "experimentalDecorators": true, "types": [ - "../../../node_modules/@types/mocha", - "../../../src/vs/typings/thenable" + "../../../node_modules/@types/mocha" ] }, "include": [