Repository: microsoft/vscode (TypeScript)
Date: 2021-09-08 08:18:18+00:00
Task type: Bug Fix

Issue:
Inline-suggestion appearing at previous cursor location
<!-- ⚠️⚠️ Do Not Delete This! bug_report_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- 🕮 Read our guide about submitting issues: https://github.com/microsoft/vscode/wiki/Submitting-Bugs-and-Suggestions -->
<!-- 🔎 Search existing issues to avoid creating duplicates. -->
<!-- 🧪 Test using the latest Insiders build to see if your issue has already been fixed: https://code.visualstudio.com/insiders/ -->
<!-- 💡 Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. -->
<!-- 🔧 Launch with `code --disable-extensions` to check. -->
Does this issue occur when all extensions are disabled?: No (Needs InlineSuggestions from some extension)

<!-- 🪓 If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. -->
<!-- 📣 Issues caused by an extension need to be reported directly to the extension publisher. The 'Help > Report Issue' dialog can assist with this. -->
- VS Code Version: 1.60.0
- OS Version: MacOS Catalina 10.15.7

Steps to Reproduce:

1. Use GitHub Copilot. The exact version shouldn't be important, but this was verified using 1.4.2586.
2. Open a blank Python document and enter the following text:

```
thisVariable = 
thatVariable = 
``` 

There are a single space after each `=` sign. Put the cursor on the end of the first line and trigger Copilot inline-suggestion by pressing Backspace then Space. Don't accept it, but press Down-arrow, Backspace, Space. After pressing Down-arrow the suggestion on the first line disappears (as it should), but after the Backspace+space, you may see the suggestion briefly appear again, before the new inline-suggestion appearing on the second line.

This is a bit flaky, and it may not appear every time the cursor is moved. It may also depend on latency to the Copilot server, and so be less pronounced in e.g. North America than in Europe or Asia.

*Edit by @hediet*: This is the buggy behavior:
![Kapture 2021-09-06 at 16 52 18](https://user-images.githubusercontent.com/3774274/132235064-50fbc790-27df-4bf5-9dd3-ccc257036036.gif)
Inline-suggestion appearing at previous cursor location
<!-- ⚠️⚠️ Do Not Delete This! bug_report_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- 🕮 Read our guide about submitting issues: https://github.com/microsoft/vscode/wiki/Submitting-Bugs-and-Suggestions -->
<!-- 🔎 Search existing issues to avoid creating duplicates. -->
<!-- 🧪 Test using the latest Insiders build to see if your issue has already been fixed: https://code.visualstudio.com/insiders/ -->
<!-- 💡 Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. -->
<!-- 🔧 Launch with `code --disable-extensions` to check. -->
Does this issue occur when all extensions are disabled?: No (Needs InlineSuggestions from some extension)

<!-- 🪓 If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. -->
<!-- 📣 Issues caused by an extension need to be reported directly to the extension publisher. The 'Help > Report Issue' dialog can assist with this. -->
- VS Code Version: 1.60.0
- OS Version: MacOS Catalina 10.15.7

Steps to Reproduce:

1. Use GitHub Copilot. The exact version shouldn't be important, but this was verified using 1.4.2586.
2. Open a blank Python document and enter the following text:

```
thisVariable = 
thatVariable = 
``` 

There are a single space after each `=` sign. Put the cursor on the end of the first line and trigger Copilot inline-suggestion by pressing Backspace then Space. Don't accept it, but press Down-arrow, Backspace, Space. After pressing Down-arrow the suggestion on the first line disappears (as it should), but after the Backspace+space, you may see the suggestion briefly appear again, before the new inline-suggestion appearing on the second line.

This is a bit flaky, and it may not appear every time the cursor is moved. It may also depend on latency to the Copilot server, and so be less pronounced in e.g. North America than in Europe or Asia.

*Edit by @hediet*: This is the buggy behavior:
![Kapture 2021-09-06 at 16 52 18](https://user-images.githubusercontent.com/3774274/132235064-50fbc790-27df-4bf5-9dd3-ccc257036036.gif)


Issue discussion:
Please let me know soon if we should release this with our Recovery Release tomorrow!
Thanks for your lightning fast fix, @hediet! 🍾 🥳  Releasing this quickly would be awesome - it's a quite distracting glitch!
@johanrosenkilde can you verify that the issue is fixed in todays insider build?
Please let me know soon if we should release this with our Recovery Release tomorrow!
Thanks for your lightning fast fix, @hediet! 🍾 🥳  Releasing this quickly would be awesome - it's a quite distracting glitch!
@johanrosenkilde can you verify that the issue is fixed in todays insider build?

Solution patch:
diff --git a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts
--- a/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts
+++ b/src/vs/editor/contrib/inlineCompletions/inlineCompletionsModel.ts
@@ -204,6 +204,10 @@ export class InlineCompletionsSession extends BaseGhostTextWidgetModel {
 			}
 		}));
 
+		this._register(toDisposable(() => {
+			this.cache.clear();
+		}));
+
 		this._register(this.editor.onDidChangeCursorPosition((e) => {
 			if (this.cache.value) {
 				this.onDidChangeEmitter.fire();


Test patch:
diff --git a/src/vs/editor/contrib/inlineCompletions/test/inlineCompletionsProvider.test.ts b/src/vs/editor/contrib/inlineCompletions/test/inlineCompletionsProvider.test.ts
--- a/src/vs/editor/contrib/inlineCompletions/test/inlineCompletionsProvider.test.ts
+++ b/src/vs/editor/contrib/inlineCompletions/test/inlineCompletionsProvider.test.ts
@@ -483,6 +483,53 @@ suite('Inline Completions', () => {
 				]);
 			});
 	});
+
+	test('Do not reuse cache from previous session (#132516)', async function () {
+		const provider = new MockInlineCompletionsProvider();
+		await withAsyncTestCodeEditorAndInlineCompletionsModel('',
+			{ fakeClock: true, provider, inlineSuggest: { enabled: true } },
+			async ({ editor, editorViewModel, model, context }) => {
+				model.setActive(true);
+				context.keyboardType('hello\n');
+				context.cursorLeft();
+				provider.setReturnValue({ text: 'helloworld', range: new Range(1, 1, 1, 6) }, 1000);
+				await timeout(2000);
+
+				assert.deepStrictEqual(provider.getAndClearCallHistory(), [
+					{
+						position: '(1,6)',
+						text: 'hello\n',
+						triggerKind: 0,
+					}
+				]);
+
+				provider.setReturnValue({ text: 'helloworld', range: new Range(2, 1, 2, 6) }, 1000);
+
+				context.cursorDown();
+				context.keyboardType('hello');
+				await timeout(100);
+
+				context.cursorLeft(); // Cause the ghost text to update
+				context.cursorRight();
+
+				await timeout(2000);
+
+				assert.deepStrictEqual(provider.getAndClearCallHistory(), [
+					{
+						position: '(2,6)',
+						text: 'hello\nhello',
+						triggerKind: 0,
+					}
+				]);
+
+				assert.deepStrictEqual(context.getAndClearViewStates(), [
+					'',
+					'hello[world]\n',
+					'hello\n',
+					'hello\nhello[world]',
+				]);
+			});
+	});
 });
 
 async function withAsyncTestCodeEditorAndInlineCompletionsModel<T>(
diff --git a/src/vs/editor/contrib/inlineCompletions/test/utils.ts b/src/vs/editor/contrib/inlineCompletions/test/utils.ts
--- a/src/vs/editor/contrib/inlineCompletions/test/utils.ts
+++ b/src/vs/editor/contrib/inlineCompletions/test/utils.ts
@@ -6,7 +6,7 @@
 import { timeout } from 'vs/base/common/async';
 import { CancellationToken } from 'vs/base/common/cancellation';
 import { Disposable } from 'vs/base/common/lifecycle';
-import { CoreEditingCommands } from 'vs/editor/browser/controller/coreCommands';
+import { CoreEditingCommands, CoreNavigationCommands } from 'vs/editor/browser/controller/coreCommands';
 import { Position } from 'vs/editor/common/core/position';
 import { ITextModel } from 'vs/editor/common/model';
 import { InlineCompletionsProvider, InlineCompletion, InlineCompletionContext } from 'vs/editor/common/modes';
@@ -112,6 +112,26 @@ export class GhostTextContext extends Disposable {
 		this.editor.trigger('keyboard', 'type', { text });
 	}
 
+	public cursorUp(): void {
+		CoreNavigationCommands.CursorUp.runEditorCommand(null, this.editor, null);
+	}
+
+	public cursorRight(): void {
+		CoreNavigationCommands.CursorRight.runEditorCommand(null, this.editor, null);
+	}
+
+	public cursorLeft(): void {
+		CoreNavigationCommands.CursorLeft.runEditorCommand(null, this.editor, null);
+	}
+
+	public cursorDown(): void {
+		CoreNavigationCommands.CursorDown.runEditorCommand(null, this.editor, null);
+	}
+
+	public cursorLineEnd(): void {
+		CoreNavigationCommands.CursorLineEnd.runEditorCommand(null, this.editor, null);
+	}
+
 	public leftDelete(): void {
 		CoreEditingCommands.DeleteLeft.runEditorCommand(null, this.editor, null);
 	}