diff --git a/vscode/src/autoedits/autoedits-provider.ts b/vscode/src/autoedits/autoedits-provider.ts index 6fd244a2092..d137c3bbc9a 100644 --- a/vscode/src/autoedits/autoedits-provider.ts +++ b/vscode/src/autoedits/autoedits-provider.ts @@ -178,9 +178,11 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v currentFileText.slice(0, document.offsetAt(range.start)) + prediction + currentFileText.slice(document.offsetAt(range.end)) - if (this.shouldFilterAutoeditResponse(currentFileText, predictedFileText, codeToReplaceData)) { - autoeditsLogger.logDebug('Autoedits', 'Model prediction already of suffix') + autoeditsLogger.logDebug( + 'Autoedits', + 'Skipping autoedit - predicted text already exists in suffix' + ) return } await this.rendererManager.displayProposedEdit({ @@ -211,7 +213,9 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v const maxAddedLineIndex = addedLines[addedLines.length - 1] const allAddedLines = predictedFileLines.slice(minAddedLineIndex, maxAddedLineIndex + 1) const allAddedLinesText = allAddedLines.join('\n') - if (codeToReplaceData.areaSuffix.includes(allAddedLinesText)) { + + const immediateSuffix = codeToReplaceData.suffixInArea + codeToReplaceData.suffixAfterArea + if (immediateSuffix.startsWith(allAddedLinesText)) { return true } return false diff --git a/vscode/src/autoedits/prompt-utils.ts b/vscode/src/autoedits/prompt-utils.ts index 576f0bacbd4..194da4e6634 100644 --- a/vscode/src/autoedits/prompt-utils.ts +++ b/vscode/src/autoedits/prompt-utils.ts @@ -51,8 +51,10 @@ export interface CurrentFilePromptOptions { export interface CodeToReplaceData { codeToRewrite: string - areaPrefix: string - areaSuffix: string + prefixBeforeArea: string + suffixAfterArea: string + prefixInArea: string + suffixInArea: string codeToRewritePrefix: string codeToRewriteSuffix: string startLine: number @@ -170,8 +172,10 @@ export function getCurrentFilePromptComponents( endLine: currentFileContext.codeToRewriteEndLine, codeToRewritePrefix: currentFileContext.codeToRewritePrefix.toString(), codeToRewriteSuffix: currentFileContext.codeToRewriteSuffix.toString(), - areaPrefix: currentFileContext.prefixInArea.toString(), - areaSuffix: currentFileContext.suffixInArea.toString(), + prefixBeforeArea: currentFileContext.prefixBeforeArea.toString(), + suffixAfterArea: currentFileContext.suffixAfterArea.toString(), + prefixInArea: currentFileContext.prefixInArea.toString(), + suffixInArea: currentFileContext.suffixInArea.toString(), } const fileWithMarker = ps`${currentFileContext.prefixBeforeArea} diff --git a/vscode/src/autoedits/renderer.ts b/vscode/src/autoedits/renderer.ts index b10c6d47075..388077f0fb2 100644 --- a/vscode/src/autoedits/renderer.ts +++ b/vscode/src/autoedits/renderer.ts @@ -67,7 +67,10 @@ export class AutoEditsRendererManager implements vscode.Disposable { vscode.commands.registerCommand('cody.supersuggest.dismiss', () => this.dismissProposedChange() ), - vscode.workspace.onDidChangeTextDocument(event => this.onDidChangeTextDocument(event)) + vscode.workspace.onDidChangeTextDocument(event => this.onDidChangeTextDocument(event)), + vscode.window.onDidChangeTextEditorSelection(event => + this.onDidChangeTextEditorSelection(event) + ) ) } @@ -77,7 +80,6 @@ export class AutoEditsRendererManager implements vscode.Disposable { if (!editor || options.document !== editor.document) { return } - this.activeProposedChange = { uri: options.document.uri.toString(), range: options.range, @@ -128,9 +130,37 @@ export class AutoEditsRendererManager implements vscode.Disposable { // Only dismiss if we have an active suggestion and the changed document matches // else, we will falsely discard the suggestion on unrelated changes such as changes in output panel. if ( - this.activeProposedChange && - event.document.uri.toString() === this.activeProposedChange.uri + !this.activeProposedChange || + event.document.uri.toString() !== this.activeProposedChange.uri + ) { + return + } + await this.dismissProposedChange() + } + + private async onDidChangeTextEditorSelection( + event: vscode.TextEditorSelectionChangeEvent + ): Promise { + if ( + !this.activeProposedChange || + event.textEditor.document.uri.toString() !== this.activeProposedChange.uri ) { + return + } + const currentSelectionRange = event.selections[0] + const proposedChangeRange = this.activeProposedChange.range + + // If the user places the cursor beyond the buffer around the proposed selection range, dismiss the suggestion + const BUFFER_LINES = 4 + const document = event.textEditor.document + const startLine = Math.max(proposedChangeRange.start.line - BUFFER_LINES, 0) + const endLine = Math.min(proposedChangeRange.end.line + BUFFER_LINES, document.lineCount - 1) + const expandedRange = new vscode.Range( + document.lineAt(startLine).range.start, + document.lineAt(endLine).range.end + ) + if (!currentSelectionRange.intersection(expandedRange)) { + // No overlap with expanded range, dismiss the proposed change await this.dismissProposedChange() } }