Skip to content

Commit 16e254f

Browse files
committed
use inline completion context
1 parent 771de02 commit 16e254f

File tree

7 files changed

+138
-32
lines changed

7 files changed

+138
-32
lines changed

vscode/src/autoedits/autoedits-provider.ts

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {
4545
autoeditTriggerKind,
4646
getTimeNowInMillis,
4747
} from './analytics-logger'
48-
import { AutoeditCompletionItem } from './autoedit-completion-item'
48+
import type { AutoeditCompletionItem } from './autoedit-completion-item'
4949
import { autoeditsOnboarding } from './autoedit-onboarding'
5050
import { autoeditsProviderConfig } from './autoedits-config'
5151
import { FilterPredictionBasedOnRecentEdits } from './filter-prediction-edits'
@@ -71,7 +71,11 @@ import type { AutoEditRenderOutput } from './renderer/render-output'
7171
import { type AutoeditRequestManagerParams, RequestManager } from './request-manager'
7272
import { shrinkPredictionUntilSuffix } from './shrink-prediction'
7373
import { SmartThrottleService } from './smart-throttle'
74-
import { areSameUriDocs, isDuplicatingTextFromRewriteArea } from './utils'
74+
import {
75+
areSameUriDocs,
76+
getDocumentTextWithInlineCompletionContext,
77+
isDuplicatingTextFromRewriteArea,
78+
} from './utils'
7579

7680
const AUTOEDIT_CONTEXT_STRATEGY = 'auto-edit'
7781
const RESET_SUGGESTION_ON_CURSOR_CHANGE_AFTER_INTERVAL_MS = 60 * 1000
@@ -328,27 +332,6 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
328332
let stopLoading: (() => void) | undefined
329333
const startedAt = getTimeNowInMillis()
330334

331-
if (inlineCompletionContext.selectedCompletionInfo !== undefined) {
332-
const { range, text } = inlineCompletionContext.selectedCompletionInfo
333-
const completion = new AutoeditCompletionItem({
334-
id: null,
335-
insertText: text,
336-
range,
337-
withoutCurrentLinePrefix: { insertText: text, range },
338-
})
339-
// User has a currently selected item in the autocomplete widget.
340-
// Instead of attempting to suggest an auto-edit, just show the selected item
341-
// as the completion. This is to avoid an undesirable edit conflicting with the acceptance
342-
// of the item shown in the widget.
343-
// TODO: We should consider the optimal solution here, it may be better to show an
344-
// inline completion (not an edit) that includes the currently selected item.
345-
return {
346-
items: [completion],
347-
inlineCompletionItems: [completion],
348-
decoratedEditItems: [],
349-
}
350-
}
351-
352335
try {
353336
const triggerKind =
354337
this.lastManualTriggerTimestamp > performance.now() - 50
@@ -398,6 +381,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
398381
position,
399382
maxPrefixLength: tokensToChars(autoeditsProviderConfig.tokenLimit.prefixTokens),
400383
maxSuffixLength: tokensToChars(autoeditsProviderConfig.tokenLimit.suffixTokens),
384+
context: inlineCompletionContext,
401385
})
402386

403387
// Determine the code to replace for this specific request
@@ -409,6 +393,10 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
409393
position,
410394
tokenBudget: autoeditsProviderConfig.tokenLimit,
411395
})
396+
console.log('UMPOX GOT REQUEST CODE TO REPLACE DATA', {
397+
rewrite: requestCodeToReplaceData.codeToRewrite,
398+
inlineCompletionContext,
399+
})
412400
const requestId = autoeditAnalyticsLogger.createRequest({
413401
startedAt,
414402
filePath: getCurrentFilePath(document).toString(),
@@ -478,6 +466,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
478466
prompt,
479467
codeToReplaceData: requestCodeToReplaceData,
480468
requestDocContext,
469+
inlineCompletionContext,
481470
abortSignal,
482471
triggerKind,
483472
})
@@ -503,7 +492,10 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
503492
const initialPrediction = predictionResult.response.prediction
504493
const predictionDocContext = predictionResult.docContext
505494
const predictionCodeToReplaceData = predictionResult.codeToReplaceData
506-
495+
console.log('UMPOX GOT PREDICTION CODE TO REPLACE DATA', {
496+
rewrite: predictionCodeToReplaceData.codeToRewrite,
497+
inlineCompletionContext,
498+
})
507499
autoeditAnalyticsLogger.markAsLoaded({
508500
requestId,
509501
cacheId: predictionResult.cacheId,
@@ -610,6 +602,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
610602
position,
611603
decorationInfo,
612604
codeToReplaceData: predictionCodeToReplaceData,
605+
inlineCompletionContext,
613606
},
614607
this.capabilities
615608
)
@@ -851,6 +844,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
851844
position,
852845
codeToReplaceData,
853846
requestDocContext,
847+
inlineCompletionContext,
854848
prompt,
855849
abortSignal,
856850
triggerKind,
@@ -860,6 +854,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
860854
position: vscode.Position
861855
codeToReplaceData: CodeToReplaceData
862856
requestDocContext: DocumentContext
857+
inlineCompletionContext: vscode.InlineCompletionContext
863858
prompt: AutoeditsPrompt
864859
abortSignal: AbortSignal
865860
triggerKind: AutoeditTriggerKindMetadata
@@ -868,7 +863,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
868863
requestId,
869864
requestUrl: autoeditsProviderConfig.url,
870865
documentUri: document.uri.toString(),
871-
documentText: document.getText(),
866+
documentText: getDocumentTextWithInlineCompletionContext(document, inlineCompletionContext),
872867
documentVersion: document.version,
873868
codeToReplaceData,
874869
requestDocContext,
@@ -897,6 +892,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
897892
document,
898893
codeToReplaceData,
899894
requestDocContext,
895+
inlineCompletionContext,
900896
position,
901897
options: {
902898
hotStreakEnabled: this.features.shouldHotStreak,
@@ -931,6 +927,7 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
931927
document,
932928
codeToReplaceData,
933929
requestDocContext,
930+
inlineCompletionContext,
934931
position,
935932
options: {
936933
hotStreakEnabled: this.features.shouldHotStreak,

vscode/src/autoedits/hot-streak/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface ProcessHotStreakResponsesParams {
2626
document: vscode.TextDocument
2727
codeToReplaceData: CodeToReplaceData
2828
requestDocContext: DocumentContext
29+
inlineCompletionContext: vscode.InlineCompletionContext
2930
position: vscode.Position
3031
options: {
3132
// If hot-streak is actually enabled. If it is not, we will not attempt to emit
@@ -53,6 +54,7 @@ export async function* processHotStreakResponses({
5354
document: originalDocument,
5455
codeToReplaceData,
5556
requestDocContext,
57+
inlineCompletionContext,
5658
position,
5759
options,
5860
}: ProcessHotStreakResponsesParams): AsyncGenerator<ProcessedHotStreakResponse> {
@@ -113,6 +115,7 @@ export async function* processHotStreakResponses({
113115
position: hotStreakPosition,
114116
maxPrefixLength: requestDocContext.maxPrefixLength,
115117
maxSuffixLength: requestDocContext.maxSuffixLength,
118+
context: inlineCompletionContext,
116119
})
117120

118121
const lengthOfChunk = predictionChunk.range.end.line - predictionChunk.range.start.line - 1

vscode/src/autoedits/prompt/prompt-utils.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,21 @@ export function getCodeToReplaceData(options: CurrentFilePromptOptions): CodeToR
236236
remainingSuffixChars
237237
)
238238

239+
// Get the text from the document for each range
240+
const codeToRewritePrefix =
241+
document.getText(ranges.codeToRewritePrefix) + (docContext.injectedPrefix || '')
242+
const codeToRewriteSuffix = document.getText(ranges.codeToRewriteSuffix)
243+
244+
console.log('UMPOX MADE CODE TO REWRITE', {
245+
codeToRewrite: codeToRewritePrefix + codeToRewriteSuffix,
246+
codeToRewritePrefix,
247+
codeToRewriteSuffix,
248+
prefixinject: docContext.injectedPrefix,
249+
})
239250
return {
240-
codeToRewrite: document.getText(ranges.codeToRewrite),
241-
codeToRewritePrefix: document.getText(ranges.codeToRewritePrefix),
242-
codeToRewriteSuffix: document.getText(ranges.codeToRewriteSuffix),
251+
codeToRewrite: codeToRewritePrefix + codeToRewriteSuffix,
252+
codeToRewritePrefix,
253+
codeToRewriteSuffix,
243254
prefixInArea: document.getText(ranges.prefixInArea),
244255
suffixInArea: document.getText(ranges.suffixInArea),
245256
prefixBeforeArea: prefixBeforeArea.toString(),

vscode/src/autoedits/renderer/manager.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,14 @@ export class AutoEditsDefaultRendererManager
426426
}
427427

428428
public getRenderOutput(
429-
{ requestId, prediction, codeToReplaceData, document, position }: GetRenderOutputArgs,
429+
{
430+
requestId,
431+
prediction,
432+
codeToReplaceData,
433+
document,
434+
position,
435+
inlineCompletionContext,
436+
}: GetRenderOutputArgs,
430437
capabilities?: AutoeditClientCapabilities
431438
): AutoEditRenderOutput {
432439
const updatedPrediction = adjustPredictionIfInlineCompletionPossible(
@@ -438,6 +445,7 @@ export class AutoEditsDefaultRendererManager
438445
const { currentLinePrefix, currentLineSuffix } = getCurrentLinePrefixAndSuffix({
439446
document,
440447
position,
448+
inlineCompletionContext,
441449
})
442450
const codeToRewriteAfterCurrentLine = codeToReplaceData.codeToRewriteSuffix.slice(
443451
currentLineSuffix.length + 1 // Additional char for newline

vscode/src/autoedits/renderer/render-output.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { AutoeditCompletionItem } from '../autoedit-completion-item'
1111
import type { AutoeditClientCapabilities } from '../autoedits-provider'
1212
import { autoeditsOutputChannelLogger } from '../output-channel-logger'
1313

14+
import { getNewLineChar } from '../../completions/text-processing'
1415
import type { AutoEditDecoration, AutoEditDecorations, DecorationInfo } from './decorators/base'
1516
import { cssPropertiesToString } from './decorators/utils'
1617
import { isOnlyAddingTextForModifiedLines, isOnlyRemovingTextForModifiedLines } from './diff-utils'
@@ -26,6 +27,7 @@ export interface GetRenderOutputArgs {
2627
position: vscode.Position
2728
decorationInfo: DecorationInfo
2829
codeToReplaceData: CodeToReplaceData
30+
inlineCompletionContext: vscode.InlineCompletionContext
2931
}
3032

3133
interface NoCompletionRenderOutput {
@@ -190,6 +192,7 @@ export class AutoEditsRenderOutput {
190192
args: GetRenderOutputArgs,
191193
capabilities: AutoeditClientCapabilities
192194
): CompletionRenderOutput | CompletionWithDecorationsRenderOutput | null {
195+
console.log('UMPOX CODE TO REWIRTE', args.codeToReplaceData.codeToRewrite)
193196
const completions = this.tryMakeInlineCompletions(args)
194197
if (!completions) {
195198
// Cannot render a completion
@@ -237,27 +240,67 @@ export class AutoEditsRenderOutput {
237240
return null
238241
}
239242

243+
private getInsertionPositionForInlineCompletion(
244+
position: vscode.Position,
245+
inlineCompletionContext: vscode.InlineCompletionContext
246+
) {
247+
const selectedCompletion = inlineCompletionContext.selectedCompletionInfo
248+
if (!selectedCompletion) {
249+
// No selected completion so no need to modify the cursor position
250+
return position
251+
}
252+
253+
const newLineChar = getNewLineChar(selectedCompletion.text)
254+
const linesToInsertFromSelectedCompletion = selectedCompletion.text.split(newLineChar)
255+
256+
if (linesToInsertFromSelectedCompletion.length === 1) {
257+
return new vscode.Position(
258+
selectedCompletion.range.start.line,
259+
selectedCompletion.range.start.character + selectedCompletion.text.length
260+
)
261+
}
262+
263+
const lastInsertionLine =
264+
linesToInsertFromSelectedCompletion[linesToInsertFromSelectedCompletion.length - 1]
265+
return new vscode.Position(
266+
selectedCompletion.range.start.line + linesToInsertFromSelectedCompletion.length - 1,
267+
lastInsertionLine.length
268+
)
269+
}
270+
240271
private tryMakeInlineCompletions({
241272
requestId,
242273
position,
243274
prediction,
244275
document,
245276
decorationInfo,
277+
inlineCompletionContext,
246278
}: GetRenderOutputArgs): {
247279
type: 'full' | 'partial'
248280
inlineCompletionItems: AutoeditCompletionItem[]
249281
updatedDecorationInfo: DecorationInfo
250282
updatedPrediction: string
251283
} | null {
284+
const otherPosition = this.getInsertionPositionForInlineCompletion(
285+
position,
286+
inlineCompletionContext
287+
)
252288
const { insertText, usedChangeIds } = getCompletionText({
253289
prediction,
254290
cursorPosition: position,
255291
decorationInfo,
256292
})
257293

294+
const other = getCompletionText({
295+
prediction,
296+
cursorPosition: otherPosition,
297+
decorationInfo,
298+
})
299+
258300
const { currentLinePrefix, currentLineSuffix } = getCurrentLinePrefixAndSuffix({
259301
document,
260302
position,
303+
inlineCompletionContext,
261304
})
262305

263306
if (insertText.length === 0) {
@@ -272,6 +315,15 @@ export class AutoEditsRenderOutput {
272315
}
273316

274317
const completionText = currentLinePrefix + insertText
318+
console.log('UMPOX GOT COMPLETION TEXT', {
319+
used: {
320+
completionText,
321+
currentLinePrefix,
322+
inlineCompletionContext,
323+
insertText,
324+
},
325+
other,
326+
})
275327
const inlineCompletionItems = [
276328
new AutoeditCompletionItem({
277329
id: requestId,

vscode/src/autoedits/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,23 @@ export function clip(line: number, min: number, max: number) {
161161
export function areSameUriDocs(a?: vscode.TextDocument, b?: vscode.TextDocument): boolean {
162162
return Boolean(a && b && a.uri.toString() === b.uri.toString())
163163
}
164+
165+
export function getDocumentTextWithInlineCompletionContext(
166+
document: vscode.TextDocument,
167+
inlineCompletionContext: vscode.InlineCompletionContext
168+
): string {
169+
const selectedCompletionContext = inlineCompletionContext.selectedCompletionInfo
170+
if (!selectedCompletionContext) {
171+
return document.getText()
172+
}
173+
174+
const documentText = document.getText()
175+
const startOffset = document.offsetAt(selectedCompletionContext.range.start)
176+
const endOffset = document.offsetAt(selectedCompletionContext.range.end)
177+
178+
return (
179+
documentText.substring(0, startOffset) +
180+
selectedCompletionContext.text +
181+
documentText.substring(endOffset)
182+
)
183+
}

vscode/src/completions/get-current-doc-context.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,15 +352,30 @@ function getLinesContext(params: GetLinesContextParams): LinesContext {
352352
export function getCurrentLinePrefixAndSuffix({
353353
document,
354354
position,
355+
inlineCompletionContext,
355356
}: {
356357
document: vscode.TextDocument
357358
position: vscode.Position
359+
inlineCompletionContext: vscode.InlineCompletionContext
358360
}) {
359361
const currentLineStartPosition = new vscode.Position(position.line, 0)
360-
const currentLinePrefix = document.getText(new vscode.Range(currentLineStartPosition, position))
361-
362362
const currentLineEndPosition = document.lineAt(position.line).range.end
363-
const currentLineSuffix = document.getText(new vscode.Range(position, currentLineEndPosition))
364363

364+
const selectedCompletion = inlineCompletionContext.selectedCompletionInfo
365+
if (selectedCompletion) {
366+
console.log('UMPOX GOT SELECTION COMPLETION')
367+
// The selected completion may replace existing characters in the document
368+
// Use this so we get an accurate prefix, we can append the completion text afterwards
369+
// const adjustedPosition = selectedCompletion.range.end
370+
const currentLinePrefix =
371+
document.getText(
372+
new vscode.Range(currentLineStartPosition, selectedCompletion.range.start)
373+
) + selectedCompletion.text
374+
const currentLineSuffix = document.getText(new vscode.Range(position, currentLineEndPosition))
375+
return { currentLinePrefix, currentLineSuffix }
376+
}
377+
378+
const currentLinePrefix = document.getText(new vscode.Range(currentLineStartPosition, position))
379+
const currentLineSuffix = document.getText(new vscode.Range(position, currentLineEndPosition))
365380
return { currentLinePrefix, currentLineSuffix }
366381
}

0 commit comments

Comments
 (0)