diff --git a/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts b/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts index 42cc8f44bf195862cd7c27e71ba4d04cf4400622..a071dabec1a4f65e204f48384bd53002f7b38eb6 100644 --- a/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts +++ b/src/vs/editor/contrib/parameterHints/parameterHintsModel.ts @@ -44,7 +44,8 @@ export class ParameterHintsModel extends Disposable { private retriggerChars = new CharacterSet(); private throttledDelayer: Delayer; - private provideSignatureHelpRequest?: CancelablePromise; + private provideSignatureHelpRequest?: CancelablePromise; + private triggerId = 0; constructor( editor: ICodeEditor, @@ -85,18 +86,18 @@ export class ParameterHintsModel extends Disposable { } trigger(context: TriggerContext, delay?: number): void { - const model = this.editor.getModel(); if (model === null || !modes.SignatureHelpProviderRegistry.has(model)) { return; } + const triggerId = ++this.triggerId; this.throttledDelayer.trigger( () => this.doTrigger({ triggerKind: context.triggerKind, triggerCharacter: context.triggerCharacter, - isRetrigger: this.isTriggered, - }), delay).then(undefined, onUnexpectedError); + isRetrigger: this.state.state === 'active' || this.state.state === 'pending', + }, triggerId), delay).then(undefined, onUnexpectedError); } public next(): void { @@ -149,7 +150,7 @@ export class ParameterHintsModel extends Disposable { this._onChangedHints.fire(this.state.hints); } - private doTrigger(triggerContext: modes.SignatureHelpContext): Promise { + private doTrigger(triggerContext: modes.SignatureHelpContext, triggerId: number): Promise { this.cancel(true); if (!this.editor.hasModel()) { @@ -165,6 +166,11 @@ export class ParameterHintsModel extends Disposable { provideSignatureHelp(model, position, triggerContext, token)); return this.provideSignatureHelpRequest.then(result => { + // Check that we are still resolving the correct signature help + if (triggerId !== this.triggerId) { + return false; + } + if (!result || !result.signatures || result.signatures.length === 0) { this.cancel(); return false; diff --git a/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts b/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts index 69663e0c3ce6e538678c1c33aa4b830b344717af..a4a35b4fff7a0011643dc510f95d62c18279e498 100644 --- a/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts +++ b/src/vs/editor/contrib/parameterHints/test/parameterHintsModel.test.ts @@ -89,12 +89,13 @@ suite('ParameterHintsModel', () => { if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); assert.strictEqual(context.triggerCharacter, triggerChar); + assert.strictEqual(context.isRetrigger, false); // Retrigger editor.trigger('keyboard', Handler.Type, { text: triggerChar }); } else { assert.strictEqual(invokeCount, 2); assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); - assert.ok(context.isRetrigger); + assert.strictEqual(context.isRetrigger, true); assert.strictEqual(context.triggerCharacter, triggerChar); done(); } @@ -122,6 +123,7 @@ suite('ParameterHintsModel', () => { if (invokeCount === 1) { assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); assert.strictEqual(context.triggerCharacter, triggerChar); + assert.strictEqual(context.isRetrigger, false); // Cancel and retrigger hintModel.cancel(); @@ -130,6 +132,8 @@ suite('ParameterHintsModel', () => { assert.strictEqual(invokeCount, 2); assert.strictEqual(context.triggerKind, modes.SignatureHelpTriggerKind.TriggerCharacter); assert.strictEqual(context.triggerCharacter, triggerChar); + assert.strictEqual(context.isRetrigger, false); + done(); } return emptySigHelpResult;