diff --git a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts index a627670c70a..f724cfd8c44 100644 --- a/extensions/typescript-language-features/src/languageFeatures/quickFix.ts +++ b/extensions/typescript-language-features/src/languageFeatures/quickFix.ts @@ -198,10 +198,10 @@ class SupportedCodeActionProvider { private readonly client: ITypeScriptServiceClient ) { } - public async getFixableDiagnosticsForContext(context: vscode.CodeActionContext): Promise { + public async getFixableDiagnosticsForContext(diagnostics: readonly vscode.Diagnostic[]): Promise { const fixableCodes = await this.fixableDiagnosticCodes; return DiagnosticsSet.from( - context.diagnostics.filter(diagnostic => typeof diagnostic.code !== 'undefined' && fixableCodes.has(diagnostic.code + ''))); + diagnostics.filter(diagnostic => typeof diagnostic.code !== 'undefined' && fixableCodes.has(diagnostic.code + ''))); } @memoize @@ -214,6 +214,8 @@ class SupportedCodeActionProvider { class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { + private static readonly _maxCodeActionsPerFile: number = 1000; + public static readonly metadata: vscode.CodeActionProviderMetadata = { providedCodeActionKinds: [vscode.CodeActionKind.QuickFix] }; @@ -237,7 +239,7 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { @@ -246,12 +248,32 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider { + setTimeout(resolve, 500); + }); + + if (token.isCancellationRequested) { + return; + } + const allDiagnostics: vscode.Diagnostic[] = []; + + // Match ranges again after getting new diagnostics + for (const diagnostic of this.diagnosticsManager.getDiagnostics(document.uri)) { + if (range.intersection(diagnostic.range)) { + const newLen = allDiagnostics.push(diagnostic); + if (newLen > TypeScriptQuickFixProvider._maxCodeActionsPerFile) { + break; + } + } + } + diagnostics = allDiagnostics; } - if (this.client.bufferSyncSupport.hasPendingDiagnostics(document.uri)) { + const fixableDiagnostics = await this.supportedCodeActionProvider.getFixableDiagnosticsForContext(diagnostics); + if (!fixableDiagnostics.size || token.isCancellationRequested) { return; } diff --git a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts index f26fe0b1ca4..9c7e0c73b76 100644 --- a/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts +++ b/src/vs/editor/contrib/codeAction/browser/codeActionModel.ts @@ -321,7 +321,20 @@ export class CodeActionModel extends Disposable { if (trigger.trigger.type === CodeActionTriggerType.Invoke) { this._progressService?.showWhile(actions, 250); } - this.setState(new CodeActionsState.Triggered(trigger.trigger, startPosition, actions)); + const newState = new CodeActionsState.Triggered(trigger.trigger, startPosition, actions); + let isManualToAutoTransition = false; + if (this._state.type === CodeActionsState.Type.Triggered) { + // Check if the current state is manual and the new state is automatic + isManualToAutoTransition = this._state.trigger.type === CodeActionTriggerType.Invoke && + newState.type === CodeActionsState.Type.Triggered && + newState.trigger.type === CodeActionTriggerType.Auto && + this._state.position !== newState.position; + } + + // Do not trigger state if current state is manual and incoming state is automatic + if (!isManualToAutoTransition) { + this.setState(newState); + } }, undefined); this._codeActionOracle.value.trigger({ type: CodeActionTriggerType.Auto, triggerAction: CodeActionTriggerSource.Default }); } else {