From 499475f2ff2d07e4bcdfb69eaba2a8c67d3d4f46 Mon Sep 17 00:00:00 2001 From: Megan Rogge Date: Wed, 13 Nov 2024 15:53:47 -0600 Subject: [PATCH] pass in cancellation token --- .../src/terminalSuggestMain.ts | 3 +++ .../api/browser/mainThreadTerminalService.ts | 4 ++-- .../workbench/api/common/extHost.protocol.ts | 2 +- .../browser/pwshCompletionProviderAddon.ts | 23 +++++++++++++++++-- .../browser/terminalCompletionService.ts | 9 ++++---- .../suggest/browser/terminalSuggestAddon.ts | 2 +- 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/extensions/terminal-suggest/src/terminalSuggestMain.ts b/extensions/terminal-suggest/src/terminalSuggestMain.ts index 108ee33b6b6..75f2a3fb6a6 100644 --- a/extensions/terminal-suggest/src/terminalSuggestMain.ts +++ b/extensions/terminal-suggest/src/terminalSuggestMain.ts @@ -153,6 +153,9 @@ vscode.window.registerTerminalCompletionProvider({ result.push(createCompletionItem(terminalContext.cursorPosition, prefix, commandName, spec.description)); } } + if (token.isCancellationRequested) { + return undefined; + } return result.length ? result : undefined; } }); diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 2b42bcae5dc..5a0d242c885 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -271,8 +271,8 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape // Proxy completion provider requests through the extension host this._completionProviders.set(id, this._terminalCompletionService.registerTerminalCompletionProvider(extensionIdentifier, id, { id, - provideCompletions: async (commandLine, cursorPosition) => { - return await this._proxy.$provideTerminalCompletions(id, { commandLine, cursorPosition }); + provideCompletions: async (commandLine, cursorPosition, token) => { + return await this._proxy.$provideTerminalCompletions(id, { commandLine, cursorPosition }, token); } }, ...triggerCharacters)); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 233939461ae..4f7fe5e918d 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2409,7 +2409,7 @@ export interface ExtHostTerminalServiceShape { $acceptDefaultProfile(profile: ITerminalProfile, automationProfile: ITerminalProfile): void; $createContributedProfileTerminal(id: string, options: ICreateContributedTerminalProfileOptions): Promise; $provideTerminalQuickFixes(id: string, matchResult: TerminalCommandMatchResultDto, token: CancellationToken): Promise | undefined>; - $provideTerminalCompletions(id: string, options: { commandLine: string; cursorPosition: number }): Promise; + $provideTerminalCompletions(id: string, options: { commandLine: string; cursorPosition: number }, token: CancellationToken): Promise; } export interface ExtHostTerminalShellIntegrationShape { diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/pwshCompletionProviderAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/pwshCompletionProviderAddon.ts index 6e770978c70..d1ed1081330 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/pwshCompletionProviderAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/pwshCompletionProviderAddon.ts @@ -21,6 +21,7 @@ import { GeneralShellType } from '../../../../../platform/terminal/common/termin import { ITerminalCapabilityStore, TerminalCapability } from '../../../../../platform/terminal/common/capabilities/capabilities.js'; import { IStorageService, StorageScope, StorageTarget } from '../../../../../platform/storage/common/storage.js'; import { DeferredPromise } from '../../../../../base/common/async.js'; +import { CancellationToken } from '../../../../../base/common/cancellation.js'; export const enum VSCodeSuggestOscPt { Completions = 'Completions', @@ -244,7 +245,7 @@ export class PwshCompletionProviderAddon extends Disposable implements ITerminal return this._completionsDeferred.p; } - provideCompletions(value: string): Promise { + provideCompletions(value: string, cursorPosition: number, token: CancellationToken): Promise { const builtinCompletionsConfig = this._configurationService.getValue(terminalSuggestConfigSection).builtinCompletions; if (!this._codeCompletionsRequested && builtinCompletionsConfig.pwshCode) { this._onDidRequestSendText.fire(RequestCompletionsSequence.Code); @@ -265,7 +266,25 @@ export class PwshCompletionProviderAddon extends Disposable implements ITerminal if (this._lastUserDataTimestamp > SuggestAddon.lastAcceptedCompletionTimestamp) { this._onDidRequestSendText.fire(RequestCompletionsSequence.Contextual); } - return this._getCompletionsPromise(); + + // Check for cancellation again before awaiting the completions promise + if (token.isCancellationRequested) { + return Promise.resolve(undefined); + } + + return new Promise((resolve) => { + const completionPromise = this._getCompletionsPromise(); + token.onCancellationRequested(() => { + this._resolveCompletions(undefined); + }); + completionPromise.then(result => { + if (token.isCancellationRequested) { + resolve(undefined); + } else { + resolve(result); + } + }); + }); } } diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts index 23963281718..2730108657e 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalCompletionService.ts @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { CancellationToken } from '../../../../../base/common/cancellation.js'; import { Disposable, IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js'; import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js'; import { createDecorator } from '../../../../../platform/instantiation/common/instantiation.js'; @@ -21,7 +22,7 @@ export enum ISimpleCompletionKind { export interface ITerminalCompletionProvider { id: string; shellTypes?: TerminalShellType[]; - provideCompletions(value: string, cursorPosition: number): Promise; + provideCompletions(value: string, cursorPosition: number, token: CancellationToken): Promise; triggerCharacters?: string[]; isBuiltin?: boolean; } @@ -30,7 +31,7 @@ export interface ITerminalCompletionService { _serviceBrand: undefined; providers: ITerminalCompletionProvider[]; registerTerminalCompletionProvider(extensionIdentifier: string, id: string, provider: ITerminalCompletionProvider, ...triggerCharacters: string[]): IDisposable; - provideCompletions(promptValue: string, cursorPosition: number, shellType: TerminalShellType, triggeredProviders?: ITerminalCompletionProvider[]): Promise; + provideCompletions(promptValue: string, cursorPosition: number, shellType: TerminalShellType, token: CancellationToken, triggeredProviders?: ITerminalCompletionProvider[]): Promise; } export class TerminalCompletionService extends Disposable implements ITerminalCompletionService { @@ -62,7 +63,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo }); } - async provideCompletions(promptValue: string, cursorPosition: number, shellType: TerminalShellType, triggeredProviders?: ITerminalCompletionProvider[]): Promise { + async provideCompletions(promptValue: string, cursorPosition: number, shellType: TerminalShellType, token: CancellationToken, triggeredProviders?: ITerminalCompletionProvider[]): Promise { const completionItems: ISimpleCompletion[] = []; if (!this._providers || !this._providers.values) { @@ -74,7 +75,7 @@ export class TerminalCompletionService extends Disposable implements ITerminalCo if (provider.shellTypes && !provider.shellTypes.includes(shellType)) { return; } - const completions = await provider.provideCompletions(promptValue, cursorPosition); + const completions = await provider.provideCompletions(promptValue, cursorPosition, token); const devModeEnabled = this._configurationService.getValue(TerminalSettingId.DevMode); if (completions) { for (const completion of completions) { diff --git a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts index 7aef0efacec..0c6b37dd719 100644 --- a/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts +++ b/src/vs/workbench/contrib/terminalContrib/suggest/browser/terminalSuggestAddon.ts @@ -142,7 +142,7 @@ export class SuggestAddon extends Disposable implements ITerminalAddon, ISuggest this._hasActivatedExtensions = true; } - const providedCompletions = await this._terminalCompletionService.provideCompletions(this._promptInputModel.value, this._promptInputModel.cursorIndex, this._shellType, providers); + const providedCompletions = await this._terminalCompletionService.provideCompletions(this._promptInputModel.value, this._promptInputModel.cursorIndex, this._shellType, token, providers); if (!providedCompletions?.length || token.isCancellationRequested) { return; }