From c85c3229f3ac7b569c3138e7aa39c75062e6abc6 Mon Sep 17 00:00:00 2001 From: Mark IJbema Date: Wed, 29 Oct 2025 12:14:29 +0100 Subject: [PATCH 1/4] fix: detect and handle auto-inserted brackets in Ghost completions - Modified findMatchingSuggestion to return both text and original suggestion - Added logic to detect when VS Code auto-inserts closing brackets - Compare current suffix with cached suffix to identify auto-inserted characters - Replace auto-inserted brackets instead of inserting alongside them - Added comprehensive test coverage for bracket detection scenarios - Fixes issue where duplicate brackets appeared after accepting suggestions --- .../GhostInlineCompletionProvider.ts | 84 ++++++++++- .../GhostInlineCompletionProvider.test.ts | 137 ++++++++++++++++-- 2 files changed, 202 insertions(+), 19 deletions(-) diff --git a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts index 6f04ebc330a..a93843b1fa6 100644 --- a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts +++ b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts @@ -19,25 +19,56 @@ export type CostTrackingCallback = ( cacheReadTokens: number, ) => void +/** + * Result of finding a matching suggestion + */ +export interface MatchingSuggestionResult { + text: string + originalSuggestion: FillInAtCursorSuggestion +} + +/** + * Check if a character is an auto-closing bracket/quote + */ +function isAutoClosingChar(char: string): boolean { + return [")", "]", "}", ">", '"', "'", "`"].includes(char) +} + /** * Find a matching suggestion from the history based on current prefix and suffix * @param prefix - The text before the cursor position * @param suffix - The text after the cursor position * @param suggestionsHistory - Array of previous suggestions (most recent last) - * @returns The matching suggestion text, or null if no match found + * @returns The matching suggestion result with text and original suggestion, or null if no match found */ export function findMatchingSuggestion( prefix: string, suffix: string, suggestionsHistory: FillInAtCursorSuggestion[], -): string | null { +): MatchingSuggestionResult | null { // Search from most recent to least recent for (let i = suggestionsHistory.length - 1; i >= 0; i--) { const fillInAtCursor = suggestionsHistory[i] // First, try exact prefix/suffix match if (prefix === fillInAtCursor.prefix && suffix === fillInAtCursor.suffix) { - return fillInAtCursor.text + return { + text: fillInAtCursor.text, + originalSuggestion: fillInAtCursor, + } + } + + // Check if suffix has an auto-inserted bracket at the start + // This happens when VS Code's bracket completion runs after we cached the suggestion + const suffixWithoutAutoBracket = + suffix.length > 0 && isAutoClosingChar(suffix[0]) ? suffix.substring(1) : suffix + + // Try matching with the suffix minus any auto-inserted bracket + if (prefix === fillInAtCursor.prefix && suffixWithoutAutoBracket === fillInAtCursor.suffix) { + return { + text: fillInAtCursor.text, + originalSuggestion: fillInAtCursor, + } } // If no exact match, check for partial typing @@ -49,7 +80,22 @@ export function findMatchingSuggestion( // Check if the typed content matches the beginning of the suggestion if (fillInAtCursor.text.startsWith(typedContent)) { // Return the remaining part of the suggestion (with already-typed portion removed) - return fillInAtCursor.text.substring(typedContent.length) + return { + text: fillInAtCursor.text.substring(typedContent.length), + originalSuggestion: fillInAtCursor, + } + } + } + + // Also check partial typing with auto-inserted bracket in suffix + if (prefix.startsWith(fillInAtCursor.prefix) && suffixWithoutAutoBracket === fillInAtCursor.suffix) { + const typedContent = prefix.substring(fillInAtCursor.prefix.length) + + if (fillInAtCursor.text.startsWith(typedContent)) { + return { + text: fillInAtCursor.text.substring(typedContent.length), + originalSuggestion: fillInAtCursor, + } } } } @@ -237,12 +283,30 @@ export class GhostInlineCompletionProvider implements vscode.InlineCompletionIte ): Promise { const { prefix, suffix } = extractPrefixSuffix(document, position) - const matchingText = findMatchingSuggestion(prefix, suffix, this.suggestionsHistory) + const matchingResult = findMatchingSuggestion(prefix, suffix, this.suggestionsHistory) + + if (matchingResult !== null) { + // Check if suffix has a new auto-inserted bracket at the start + // This happens when VS Code's bracket completion runs before our suggestion + const suffixFirstChar = suffix.length > 0 ? suffix[0] : "" + const originalSuffixFirstChar = + matchingResult.originalSuggestion.suffix.length > 0 ? matchingResult.originalSuggestion.suffix[0] : "" + + // Detect if a bracket was auto-inserted: + // 1. Current suffix starts with an auto-closing character + // 2. Original suffix didn't start with that character (or was different) + const hasAutoInsertedBracket = + isAutoClosingChar(suffixFirstChar) && suffixFirstChar !== originalSuffixFirstChar - if (matchingText !== null) { const item: vscode.InlineCompletionItem = { - insertText: matchingText, - range: new vscode.Range(position, position), + insertText: matchingResult.text, + range: hasAutoInsertedBracket + ? new vscode.Range(position, new vscode.Position(position.line, position.character + 1)) // Replace the auto-bracket + : new vscode.Range(position, position), // Just insert + command: { + title: "Accept Suggestion", + command: "editor.action.inlineSuggest.commit", + }, } return [item] } @@ -295,6 +359,10 @@ export class GhostInlineCompletionProvider implements vscode.InlineCompletionIte const item: vscode.InlineCompletionItem = { insertText: fillInAtCursor.text, range: new vscode.Range(position, position), + command: { + title: "Accept Suggestion", + command: "editor.action.inlineSuggest.commit", + }, } return [item] } diff --git a/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts b/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts index 3d878e426c6..b9acd9774ef 100644 --- a/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts +++ b/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts @@ -3,6 +3,7 @@ import { GhostInlineCompletionProvider, findMatchingSuggestion, CostTrackingCallback, + MatchingSuggestionResult, } from "../GhostInlineCompletionProvider" import { GhostSuggestionsState, FillInAtCursorSuggestion } from "../GhostSuggestions" import { MockTextDocument } from "../../../mocking/MockTextDocument" @@ -34,7 +35,9 @@ describe("findMatchingSuggestion", () => { ] const result = findMatchingSuggestion("const x = 1", "\nconst y = 2", suggestions) - expect(result).toBe("console.log('Hello, World!');") + expect(result).not.toBeNull() + expect(result?.text).toBe("console.log('Hello, World!');") + expect(result?.originalSuggestion).toEqual(suggestions[0]) }) it("should return null when prefix does not match", () => { @@ -81,7 +84,9 @@ describe("findMatchingSuggestion", () => { // User typed "cons" after the prefix const result = findMatchingSuggestion("const x = 1cons", "\nconst y = 2", suggestions) - expect(result).toBe("ole.log('Hello, World!');") + expect(result).not.toBeNull() + expect(result?.text).toBe("ole.log('Hello, World!');") + expect(result?.originalSuggestion).toEqual(suggestions[0]) }) it("should return full suggestion when no partial typing", () => { @@ -94,7 +99,8 @@ describe("findMatchingSuggestion", () => { ] const result = findMatchingSuggestion("const x = 1", "\nconst y = 2", suggestions) - expect(result).toBe("console.log('test');") + expect(result).not.toBeNull() + expect(result?.text).toBe("console.log('test');") }) it("should return null when partially typed content does not match suggestion", () => { @@ -121,7 +127,8 @@ describe("findMatchingSuggestion", () => { ] const result = findMatchingSuggestion("const x = 1console.log('test');", "\nconst y = 2", suggestions) - expect(result).toBe("") + expect(result).not.toBeNull() + expect(result?.text).toBe("") }) it("should return null when suffix has changed during partial typing", () => { @@ -149,7 +156,8 @@ describe("findMatchingSuggestion", () => { // User typed "function te" const result = findMatchingSuggestion("const x = 1function te", "\nconst y = 2", suggestions) - expect(result).toBe("st() { return 42; }") + expect(result).not.toBeNull() + expect(result?.text).toBe("st() { return 42; }") }) it("should be case-sensitive in partial matching", () => { @@ -183,7 +191,8 @@ describe("findMatchingSuggestion", () => { ] const result = findMatchingSuggestion("const x = 1", "\nconst y = 2", suggestions) - expect(result).toBe("second suggestion") + expect(result).not.toBeNull() + expect(result?.text).toBe("second suggestion") }) it("should match different suggestions based on context", () => { @@ -201,10 +210,12 @@ describe("findMatchingSuggestion", () => { ] const result1 = findMatchingSuggestion("const x = 1", "\nconst y = 2", suggestions) - expect(result1).toBe("first suggestion") + expect(result1).not.toBeNull() + expect(result1?.text).toBe("first suggestion") const result2 = findMatchingSuggestion("const a = 1", "\nconst b = 2", suggestions) - expect(result2).toBe("second suggestion") + expect(result2).not.toBeNull() + expect(result2?.text).toBe("second suggestion") }) it("should prefer exact match over partial match", () => { @@ -223,7 +234,8 @@ describe("findMatchingSuggestion", () => { // User is at position that matches exact prefix of second suggestion const result = findMatchingSuggestion("const x = 1cons", "\nconst y = 2", suggestions) - expect(result).toBe("exact match") + expect(result).not.toBeNull() + expect(result?.text).toBe("exact match") }) }) }) @@ -325,8 +337,11 @@ describe("GhostInlineCompletionProvider", () => { expect(result).toHaveLength(1) expect(result[0].insertText).toBe(fimContent.text) expect(result[0].range).toEqual(new vscode.Range(mockPosition, mockPosition)) - // No command property - VSCode handles acceptance automatically - expect(result[0].command).toBeUndefined() + // Command property to suppress conflicting VS Code completions + expect(result[0].command).toEqual({ + title: "Accept Suggestion", + command: "editor.action.inlineSuggest.commit", + }) }) it("should return empty array when prefix does not match", async () => { @@ -808,6 +823,106 @@ describe("GhostInlineCompletionProvider", () => { expect(result).toEqual([]) }) }) + + describe("auto-bracket detection", () => { + it("should replace auto-inserted closing bracket when detected", async () => { + // Set up a suggestion with no bracket in suffix + const suggestions = new GhostSuggestionsState() + suggestions.setFillInAtCursor({ + text: "useState(true);", + prefix: "const x = ", + suffix: "\nconst y = 2", + }) + provider.updateSuggestions(suggestions) + + // Simulate VS Code auto-inserting a closing bracket after typing "[" + // Document now has: "const x = ]\nconst y = 2" + // Position is right after "= " and before the auto-inserted "]" + const documentWithBracket = new MockTextDocument( + vscode.Uri.file("/test.ts"), + "const x = ]\nconst y = 2", + ) + const positionBeforeBracket = new vscode.Position(0, 10) // After "= ", before "]" + + const result = (await provider.provideInlineCompletionItems( + documentWithBracket, + positionBeforeBracket, + mockContext, + mockToken, + )) as vscode.InlineCompletionItem[] + + expect(result).toHaveLength(1) + expect(result[0].insertText).toBe("useState(true);") + // Should replace the auto-inserted bracket + expect(result[0].range).toEqual(new vscode.Range(positionBeforeBracket, new vscode.Position(0, 11))) + }) + + it("should not replace bracket if it was in original suffix", async () => { + // Set up a suggestion where bracket was already in suffix + const suggestions = new GhostSuggestionsState() + suggestions.setFillInAtCursor({ + text: "useState(true);", + prefix: "const x = ", + suffix: "]\nconst y = 2", + }) + provider.updateSuggestions(suggestions) + + // Same document state - bracket was already there when suggestion was cached + const documentWithBracket = new MockTextDocument( + vscode.Uri.file("/test.ts"), + "const x = ]\nconst y = 2", + ) + const positionBeforeBracket = new vscode.Position(0, 10) + + const result = (await provider.provideInlineCompletionItems( + documentWithBracket, + positionBeforeBracket, + mockContext, + mockToken, + )) as vscode.InlineCompletionItem[] + + expect(result).toHaveLength(1) + expect(result[0].insertText).toBe("useState(true);") + // Should NOT replace the bracket - just insert + expect(result[0].range).toEqual(new vscode.Range(positionBeforeBracket, positionBeforeBracket)) + }) + + it("should handle other auto-closing characters", async () => { + const testCases = [ + { char: ")", desc: "parenthesis" }, + { char: "}", desc: "curly brace" }, + { char: ">", desc: "angle bracket" }, + { char: '"', desc: "double quote" }, + { char: "'", desc: "single quote" }, + ] + + for (const { char, desc } of testCases) { + const suggestions = new GhostSuggestionsState() + suggestions.setFillInAtCursor({ + text: "test", + prefix: "const x = ", + suffix: "\nconst y = 2", + }) + provider.updateSuggestions(suggestions) + + const documentWithChar = new MockTextDocument( + vscode.Uri.file("/test.ts"), + `const x = ${char}\nconst y = 2`, + ) + const position = new vscode.Position(0, 10) + + const result = (await provider.provideInlineCompletionItems( + documentWithChar, + position, + mockContext, + mockToken, + )) as vscode.InlineCompletionItem[] + + expect(result).toHaveLength(1) + expect(result[0].range).toEqual(new vscode.Range(position, new vscode.Position(0, 11))) + } + }) + }) }) describe("cachedSuggestionAvailable", () => { From 52c6a87a56f4338782d29a99b3aa20ed080fdbec Mon Sep 17 00:00:00 2001 From: Mark IJbema Date: Wed, 29 Oct 2025 12:22:35 +0100 Subject: [PATCH 2/4] abstrat --- .../GhostInlineCompletionProvider.ts | 96 +++++++++++-------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts index a93843b1fa6..7ef0feee403 100644 --- a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts +++ b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts @@ -34,6 +34,44 @@ function isAutoClosingChar(char: string): boolean { return [")", "]", "}", ">", '"', "'", "`"].includes(char) } +/** + * Remove auto-inserted bracket from the start of suffix if present + * @param suffix - The text after the cursor position + * @returns The suffix with any auto-inserted bracket removed + */ +function removePotentialAutoBracket(suffix: string): string { + return suffix.length > 0 && isAutoClosingChar(suffix[0]) ? suffix.substring(1) : suffix +} + +/** + * Check if prefix and suffix match, considering potential auto-inserted brackets + * @param prefix - Current prefix to check + * @param suffix - Current suffix to check + * @param expectedPrefix - Expected prefix from cached suggestion + * @param expectedSuffix - Expected suffix from cached suggestion + * @returns Object with match status and cleaned suffix + */ +function checkPrefixSuffixMatch( + prefix: string, + suffix: string, + expectedPrefix: string, + expectedSuffix: string, +): { matches: boolean; cleanedSuffix: string } { + const cleanedSuffix = removePotentialAutoBracket(suffix) + + // Check exact match first + if (prefix === expectedPrefix && suffix === expectedSuffix) { + return { matches: true, cleanedSuffix: suffix } + } + + // Check match with auto-bracket removed + if (prefix === expectedPrefix && cleanedSuffix === expectedSuffix) { + return { matches: true, cleanedSuffix } + } + + return { matches: false, cleanedSuffix } +} + /** * Find a matching suggestion from the history based on current prefix and suffix * @param prefix - The text before the cursor position @@ -50,51 +88,31 @@ export function findMatchingSuggestion( for (let i = suggestionsHistory.length - 1; i >= 0; i--) { const fillInAtCursor = suggestionsHistory[i] - // First, try exact prefix/suffix match - if (prefix === fillInAtCursor.prefix && suffix === fillInAtCursor.suffix) { + // Check for exact match (with or without auto-inserted bracket) + const exactMatch = checkPrefixSuffixMatch(prefix, suffix, fillInAtCursor.prefix, fillInAtCursor.suffix) + if (exactMatch.matches) { return { text: fillInAtCursor.text, originalSuggestion: fillInAtCursor, } } - // Check if suffix has an auto-inserted bracket at the start - // This happens when VS Code's bracket completion runs after we cached the suggestion - const suffixWithoutAutoBracket = - suffix.length > 0 && isAutoClosingChar(suffix[0]) ? suffix.substring(1) : suffix - - // Try matching with the suffix minus any auto-inserted bracket - if (prefix === fillInAtCursor.prefix && suffixWithoutAutoBracket === fillInAtCursor.suffix) { - return { - text: fillInAtCursor.text, - originalSuggestion: fillInAtCursor, - } - } - - // If no exact match, check for partial typing - // The user may have started typing the suggested text - if (prefix.startsWith(fillInAtCursor.prefix) && suffix === fillInAtCursor.suffix) { - // Extract what the user has typed between the original prefix and current position - const typedContent = prefix.substring(fillInAtCursor.prefix.length) - - // Check if the typed content matches the beginning of the suggestion - if (fillInAtCursor.text.startsWith(typedContent)) { - // Return the remaining part of the suggestion (with already-typed portion removed) - return { - text: fillInAtCursor.text.substring(typedContent.length), - originalSuggestion: fillInAtCursor, - } - } - } - - // Also check partial typing with auto-inserted bracket in suffix - if (prefix.startsWith(fillInAtCursor.prefix) && suffixWithoutAutoBracket === fillInAtCursor.suffix) { - const typedContent = prefix.substring(fillInAtCursor.prefix.length) - - if (fillInAtCursor.text.startsWith(typedContent)) { - return { - text: fillInAtCursor.text.substring(typedContent.length), - originalSuggestion: fillInAtCursor, + // Check for partial typing - user may have started typing the suggested text + if (prefix.startsWith(fillInAtCursor.prefix)) { + const partialMatch = checkPrefixSuffixMatch(prefix, suffix, fillInAtCursor.prefix, fillInAtCursor.suffix) + + // Only proceed if suffix matches (with or without auto-bracket) + if (partialMatch.cleanedSuffix === fillInAtCursor.suffix) { + // Extract what the user has typed between the original prefix and current position + const typedContent = prefix.substring(fillInAtCursor.prefix.length) + + // Check if the typed content matches the beginning of the suggestion + if (fillInAtCursor.text.startsWith(typedContent)) { + // Return the remaining part of the suggestion (with already-typed portion removed) + return { + text: fillInAtCursor.text.substring(typedContent.length), + originalSuggestion: fillInAtCursor, + } } } } From eaa82ecbfd7fe90a9c02af432013280b8e8f298a Mon Sep 17 00:00:00 2001 From: Mark IJbema Date: Wed, 29 Oct 2025 12:24:37 +0100 Subject: [PATCH 3/4] remove comments --- .../GhostInlineCompletionProvider.ts | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts index 7ef0feee403..f15a61da8cd 100644 --- a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts +++ b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts @@ -27,30 +27,14 @@ export interface MatchingSuggestionResult { originalSuggestion: FillInAtCursorSuggestion } -/** - * Check if a character is an auto-closing bracket/quote - */ function isAutoClosingChar(char: string): boolean { return [")", "]", "}", ">", '"', "'", "`"].includes(char) } -/** - * Remove auto-inserted bracket from the start of suffix if present - * @param suffix - The text after the cursor position - * @returns The suffix with any auto-inserted bracket removed - */ function removePotentialAutoBracket(suffix: string): string { return suffix.length > 0 && isAutoClosingChar(suffix[0]) ? suffix.substring(1) : suffix } -/** - * Check if prefix and suffix match, considering potential auto-inserted brackets - * @param prefix - Current prefix to check - * @param suffix - Current suffix to check - * @param expectedPrefix - Expected prefix from cached suggestion - * @param expectedSuffix - Expected suffix from cached suggestion - * @returns Object with match status and cleaned suffix - */ function checkPrefixSuffixMatch( prefix: string, suffix: string, @@ -59,12 +43,10 @@ function checkPrefixSuffixMatch( ): { matches: boolean; cleanedSuffix: string } { const cleanedSuffix = removePotentialAutoBracket(suffix) - // Check exact match first if (prefix === expectedPrefix && suffix === expectedSuffix) { return { matches: true, cleanedSuffix: suffix } } - // Check match with auto-bracket removed if (prefix === expectedPrefix && cleanedSuffix === expectedSuffix) { return { matches: true, cleanedSuffix } } @@ -88,7 +70,6 @@ export function findMatchingSuggestion( for (let i = suggestionsHistory.length - 1; i >= 0; i--) { const fillInAtCursor = suggestionsHistory[i] - // Check for exact match (with or without auto-inserted bracket) const exactMatch = checkPrefixSuffixMatch(prefix, suffix, fillInAtCursor.prefix, fillInAtCursor.suffix) if (exactMatch.matches) { return { @@ -97,18 +78,13 @@ export function findMatchingSuggestion( } } - // Check for partial typing - user may have started typing the suggested text if (prefix.startsWith(fillInAtCursor.prefix)) { const partialMatch = checkPrefixSuffixMatch(prefix, suffix, fillInAtCursor.prefix, fillInAtCursor.suffix) - // Only proceed if suffix matches (with or without auto-bracket) if (partialMatch.cleanedSuffix === fillInAtCursor.suffix) { - // Extract what the user has typed between the original prefix and current position const typedContent = prefix.substring(fillInAtCursor.prefix.length) - // Check if the typed content matches the beginning of the suggestion if (fillInAtCursor.text.startsWith(typedContent)) { - // Return the remaining part of the suggestion (with already-typed portion removed) return { text: fillInAtCursor.text.substring(typedContent.length), originalSuggestion: fillInAtCursor, From 938aecabbe9b092cf1deceb01d38aeb25755d76a Mon Sep 17 00:00:00 2001 From: Mark IJbema Date: Wed, 29 Oct 2025 12:38:51 +0100 Subject: [PATCH 4/4] remove change --- .../GhostInlineCompletionProvider.ts | 11 ----------- .../__tests__/GhostInlineCompletionProvider.test.ts | 7 ++----- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts index f15a61da8cd..386a803c9f8 100644 --- a/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts +++ b/src/services/ghost/classic-auto-complete/GhostInlineCompletionProvider.ts @@ -19,9 +19,6 @@ export type CostTrackingCallback = ( cacheReadTokens: number, ) => void -/** - * Result of finding a matching suggestion - */ export interface MatchingSuggestionResult { text: string originalSuggestion: FillInAtCursorSuggestion @@ -297,10 +294,6 @@ export class GhostInlineCompletionProvider implements vscode.InlineCompletionIte range: hasAutoInsertedBracket ? new vscode.Range(position, new vscode.Position(position.line, position.character + 1)) // Replace the auto-bracket : new vscode.Range(position, position), // Just insert - command: { - title: "Accept Suggestion", - command: "editor.action.inlineSuggest.commit", - }, } return [item] } @@ -353,10 +346,6 @@ export class GhostInlineCompletionProvider implements vscode.InlineCompletionIte const item: vscode.InlineCompletionItem = { insertText: fillInAtCursor.text, range: new vscode.Range(position, position), - command: { - title: "Accept Suggestion", - command: "editor.action.inlineSuggest.commit", - }, } return [item] } diff --git a/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts b/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts index b9acd9774ef..37ef2a74413 100644 --- a/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts +++ b/src/services/ghost/classic-auto-complete/__tests__/GhostInlineCompletionProvider.test.ts @@ -337,11 +337,8 @@ describe("GhostInlineCompletionProvider", () => { expect(result).toHaveLength(1) expect(result[0].insertText).toBe(fimContent.text) expect(result[0].range).toEqual(new vscode.Range(mockPosition, mockPosition)) - // Command property to suppress conflicting VS Code completions - expect(result[0].command).toEqual({ - title: "Accept Suggestion", - command: "editor.action.inlineSuggest.commit", - }) + // No command property - VSCode handles acceptance automatically + expect(result[0].command).toBeUndefined() }) it("should return empty array when prefix does not match", async () => {