Skip to content

Commit

Permalink
feat(autoedit): refactor renderer code to simplify iteration on decor… (
Browse files Browse the repository at this point in the history
#6163)

The PR refactors the current autoedits renderer to use a common schema
for which Decorations can use.
Idea is to make it easy for anyone to try to implement a new decoration
type without knowing the details on diff computation.
  • Loading branch information
hitesh-1997 authored Nov 22, 2024
1 parent d93cc15 commit bdf587d
Show file tree
Hide file tree
Showing 13 changed files with 740 additions and 481 deletions.
7 changes: 5 additions & 2 deletions vscode/src/autoedits/autoedits-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ import { OpenAIAdapter } from './adapters/openai'
import { autoeditsLogger } from './logger'
import type { AutoeditsModelAdapter } from './prompt-provider'
import type { CodeToReplaceData } from './prompt-utils'
import { AutoEditsRendererManager } from './renderer'
import { DefaultDecorator } from './renderer/decorators/default-decorator'
import { AutoEditsRendererManager } from './renderer/manager'
import {
adjustPredictionIfInlineCompletionPossible,
extractInlineCompletionFromRewrittenCode,
Expand Down Expand Up @@ -75,7 +76,9 @@ export class AutoeditsProvider implements vscode.InlineCompletionItemProvider, v
contextRankingStrategy: ContextRankingStrategy.TimeBased,
dataCollectionEnabled: false,
})
this.rendererManager = new AutoEditsRendererManager()
this.rendererManager = new AutoEditsRendererManager(
(editor: vscode.TextEditor) => new DefaultDecorator(editor)
)
this.onSelectionChangeDebounced = debounce(
(event: vscode.TextEditorSelectionChangeEvent) => this.autoeditOnSelectionChange(event),
ONSELECTION_CHANGE_DEFAULT_DEBOUNCE_INTERVAL_MS
Expand Down
59 changes: 0 additions & 59 deletions vscode/src/autoedits/diff-utils.test.ts

This file was deleted.

100 changes: 0 additions & 100 deletions vscode/src/autoedits/diff-utils.ts

This file was deleted.

70 changes: 70 additions & 0 deletions vscode/src/autoedits/renderer/decorators/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type * as vscode from 'vscode'
import type { ModifiedRange } from '../diff-utils'

/**
* Represents a decorator that manages VS Code editor decorations for auto-edit suggestions.
*
* This interface defines the contract for displaying and managing decorative elements
* that visualize proposed text changes in the editor.
*
* Lifecycle:
* - Single instance should be created per decoration session and disposed of when the decorations
* are no longer needed.
* - Always call dispose() when the decorator is no longer needed to clean up resources.
* - Dispose should always clear the decorations.
*
* Usage Pattern:
* ```typescript
* const decorator = createAutoeditsDecorator(...);
* try {
* decorator.setDecorations(decorationInfo);
* ...
* } finally {
* decorator.clearDecorations();
* decorator.dispose();
* }
* ```
*/
export interface AutoeditsDecorator extends vscode.Disposable {
/**
* Applies decorations to the editor based on the provided decoration information.
*
* @param decorationInformation Contains the line-by-line information about text changes
* and how they should be decorated in the editor.
*/
setDecorations(decorationInformation: DecorationInformation): void
}

/**
* Represents the different types of line decorations that can be applied.
*/
export enum DecorationLineType {
/** Line has been modified from its original state */
Modified = 0,
/** New line has been added */
Added = 1,
/** Line has been removed */
Removed = 2,
/** Line remains unchanged */
Unchanged = 3,
}

export interface DecorationLineInformation {
lineType: DecorationLineType
// Line number in the original text. The line number can be null if the line was added.
oldLineNumber: number | null
// Line number in the new predicted text. The line number can be null if the line was removed.
newLineNumber: number | null
// The text of the line in the original text.
oldText: string
// The text of the line in the new predicted text.
newText: string
// The ranges of text that were modified in the line.
modifiedRanges: ModifiedRange[]
}

export interface DecorationInformation {
lines: DecorationLineInformation[]
oldLines: string[]
newLines: string[]
}
51 changes: 51 additions & 0 deletions vscode/src/autoedits/renderer/decorators/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { type DecorationLineInformation, DecorationLineType } from './base'

/**
* Checks if the only changes for modified lines are additions of text
*/
export function isOnlyAddingTextForModifiedLines(
decorationInformation: DecorationLineInformation[]
): boolean {
for (const line of decorationInformation) {
if (line.lineType !== DecorationLineType.Modified) {
continue
}
if (line.modifiedRanges.some(range => range.from1 !== range.to1)) {
return false
}
}
return true
}

export function splitLineDecorationIntoLineTypes(decorationInformation: DecorationLineInformation[]): {
modifiedLines: DecorationLineInformation[]
removedLines: DecorationLineInformation[]
addedLines: DecorationLineInformation[]
unchangedLines: DecorationLineInformation[]
} {
const result = {
modifiedLines: [] as DecorationLineInformation[],
removedLines: [] as DecorationLineInformation[],
addedLines: [] as DecorationLineInformation[],
unchangedLines: [] as DecorationLineInformation[],
}

for (const line of decorationInformation) {
switch (line.lineType) {
case DecorationLineType.Modified:
result.modifiedLines.push(line)
break
case DecorationLineType.Removed:
result.removedLines.push(line)
break
case DecorationLineType.Added:
result.addedLines.push(line)
break
case DecorationLineType.Unchanged:
result.unchangedLines.push(line)
break
}
}

return result
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { _replaceLeadingTrailingChars } from './renderer'
import { _replaceLeadingTrailingChars } from './default-decorator'

describe('replaceLeadingTrailingChars', () => {
it('replaces leading and trailing spaces with tabs', () => {
Expand Down
Loading

0 comments on commit bdf587d

Please sign in to comment.