diff --git a/.editorconfig b/.editorconfig
index 4d582a0f31fc..69dfbc863399 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -4,7 +4,7 @@ root = true
insert_final_newline = true
end_of_line = lf
charset = utf-8
-trim_trailing_whitespace = true
+trim_trailing_whitespace = false
indent_style = space
indent_size = 4
diff --git a/vscode/src/chat/chat-view/chat-helpers.ts b/vscode/src/chat/chat-view/chat-helpers.ts
index dcc22f013b83..866290776043 100644
--- a/vscode/src/chat/chat-view/chat-helpers.ts
+++ b/vscode/src/chat/chat-view/chat-helpers.ts
@@ -13,3 +13,11 @@ export function getChatPanelTitle(lastHumanText?: string, truncateTitle = true):
// truncate title that is too long
return text.length > 25 ? `${text.slice(0, 25).trim()}...` : text
}
+
+export function chatHelper(hello: string): string {
+ return hello
+}
+
+export function chatHelper2(message: string): string {
+ return message
+}
diff --git a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/auotedit-short-term-diff.ts b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/auotedit-short-term-diff.ts
index 326127b1202c..5b175c92f84a 100644
--- a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/auotedit-short-term-diff.ts
+++ b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/auotedit-short-term-diff.ts
@@ -22,10 +22,19 @@ export class AutoeditWithShortTermDiffStrategy implements RecentEditsRetrieverDi
public getDiffHunks(input: DiffCalculationInput): DiffHunk[] {
const rawChanges = groupChangesForSimilarLinesTogether(input.changes)
+ const rawDiffHunks = this.getDiffHunksFromGroupedChanges(input, rawChanges)
const changes = combineNonOverlappingLinesSchemaTogether(rawChanges)
- this.logGroupedChanges(input.uri, input.oldContent, changes)
- const allDiffHunks: DiffHunk[] = []
+ const combinedDiffHunks = this.getDiffHunksFromGroupedChanges(input, changes)
+
+ this.logRawDataPoints(input.uri.toString(), input.oldContent, rawDiffHunks, combinedDiffHunks)
+ return combinedDiffHunks
+ }
+ private getDiffHunksFromGroupedChanges(
+ input: DiffCalculationInput,
+ changes: TextDocumentChangeGroup[]
+ ): DiffHunk[] {
+ const allDiffHunks: DiffHunk[] = []
let oldContent = input.oldContent
for (const changeList of changes) {
const [diffHunk, newContent] = this.getDiffHunksForChanges(
@@ -40,6 +49,32 @@ export class AutoeditWithShortTermDiffStrategy implements RecentEditsRetrieverDi
return allDiffHunks
}
+ private logRawDataPoints(uri: string, oldContent: string, rawDiffHunks: DiffHunk[], combinedDiffHunks: DiffHunk[]) {
+ const dirPath = '/Users/hiteshsagtani/Desktop/raw-diff-logs'
+ const fileName = uri.split('/').pop()?.split('.')[0] || 'document'
+ const logPath = uri.replace(/[^/\\]+$/, `${fileName}_raw.jsonl`)
+ const finalLogPath = path.join(dirPath, path.basename(logPath))
+ const fs = require('fs')
+
+ // Create directory if it doesn't exist
+ if (!fs.existsSync(dirPath)) {
+ fs.mkdirSync(dirPath, { recursive: true })
+ }
+
+ const logData = {
+ uri: uri.toString(),
+ oldContent,
+ rawDiffHunks,
+ combinedDiffHunks
+ }
+ // Append to file if it exists, create if it doesn't
+ fs.appendFileSync(
+ finalLogPath,
+ JSON.stringify(logData) + '\n',
+ { encoding: 'utf8' }
+ )
+ }
+
private logGroupedChanges(uri: vscode.Uri, oldContent: string, changes: TextDocumentChangeGroup[]) {
const fileName = uri.fsPath.split('/').pop()?.split('.')[0] || 'document'
const logPath = uri.fsPath.replace(/[^/\\]+$/, `${fileName}_grouped.json`)
diff --git a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.test.ts b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.test.ts
index 2cdb911eda57..3f1979cdca20 100644
--- a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.test.ts
+++ b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.test.ts
@@ -3,12 +3,7 @@ import dedent from 'dedent'
import { describe, expect, it } from 'vitest'
import type * as vscode from 'vscode'
import { getDiffsForContentChanges, getTextDocumentChangesForText } from './helper'
-import {
- applyTextDocumentChanges,
- computeDiffWithLineNumbers,
- groupChangesForSimilarLinesTogether,
- groupConsecutiveItemsByPredicate,
-} from './utils'
+import {applyTextDocumentChanges, computeDiffWithLineNumbers, groupChangesForSimilarLinesTogether, groupConsecutiveItemsByPredicate, combineNonOverlappingLinesSchemaTogether} from './utils';
const processComputedDiff = (text: string) => {
const lines = text.split('\n')
@@ -16,7 +11,7 @@ const processComputedDiff = (text: string) => {
return updatedText.split('\n').slice(3).join('\n')
}
-describe('groupChangesForSimilarLinesTogether', () => {
+describe('groupChangesForLines', () => {
it('handles multiple deletions across different lines', () => {
const text = dedent`
@@ -48,6 +43,19 @@ describe('groupChangesForSimilarLinesTogether', () => {
-}
"
`)
+ const combinedChanges = combineNonOverlappingLinesSchemaTogether(result)
+ expect(combinedChanges.length).toBe(1)
+ const combinedDiffs = getDiffsForContentChanges(originalText, combinedChanges)
+ expect(processComputedDiff(combinedDiffs[0])).toMatchInlineSnapshot(`
+ " const a = 5;
+ -console.log('test');
+ const data = 5;
+ -function test() {
+ - return true;
+ -}
+ "
+ `)
+
})
it('handles interleaved insertions and deletions', () => {
@@ -74,13 +82,27 @@ describe('groupChangesForSimilarLinesTogether', () => {
function test() {
const x = 5;
if (true) {
- console.log(x);
+ console.log(x);
}
}
`
- const { changes } = getTextDocumentChangesForText(text)
+ const { originalText, changes } = getTextDocumentChangesForText(text)
const result = groupChangesForSimilarLinesTogether(changes)
expect(result.length).toBe(2)
+ const combinedChanges = combineNonOverlappingLinesSchemaTogether(result)
+ expect(combinedChanges.length).toBe(1)
+ const combinedDiffs = getDiffsForContentChanges(originalText, combinedChanges)
+ expect(processComputedDiff(combinedDiffs[0])).toMatchInlineSnapshot(`
+ " function test() {
+ -
+ -
+ + const x = 5;
+ + if (true) {
+ + console.log(x);
+ + }
+ }
+ "
+ `)
})
it('seperate line changes for non-continous changes on different lines', () => {
@@ -114,6 +136,18 @@ describe('groupChangesForSimilarLinesTogether', () => {
+const a = 5;
"
`)
+ const combinedChanges = combineNonOverlappingLinesSchemaTogether(result)
+ expect(combinedChanges.length).toBe(1)
+ const combinedDiffs = getDiffsForContentChanges(originalText, combinedChanges)
+ expect(processComputedDiff(combinedDiffs[0])).toMatchInlineSnapshot(`
+ "-console.
+ -data =
+ -const
+ +console.log('Hello, world!');
+ +data = 'check'
+ +const a = 5;
+ "
+ `)
})
it('same line changes with non-continous character typing', () => {
diff --git a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.ts b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.ts
index 164ac23618e5..25831bd4f4ca 100644
--- a/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.ts
+++ b/vscode/src/completions/context/retrievers/recent-user-actions/recent-edits-diff-helpers/utils.ts
@@ -1,11 +1,11 @@
import { PromptString } from '@sourcegraph/cody-shared'
import { displayPath } from '@sourcegraph/cody-shared/src/editor/displayPath'
import { structuredPatch } from 'diff'
-import type * as vscode from 'vscode'
+import * as vscode from 'vscode'
import type { TextDocumentChange } from './base'
/**
- * Represents a group of text document changes with their line range information.
+ * Represents a group of text document changes with their range information.
* The grouped changes are consecutive changes made in the document that should be treated as a single entity when computing diffs.
*
* @example
@@ -17,14 +17,14 @@ export interface TextDocumentChangeGroup {
changes: TextDocumentChange[]
/**
- * The starting line number of the changes in this group
+ * The union of the inserted ranges of all changes in this group
*/
- changeStartLine: number
+ insertRange: vscode.Range
/**
- * The ending line number of the changes in this group
+ * The union of the replace ranges of all changes in this group
*/
- changeEndLine: number
+ replaceRange: vscode.Range
}
/**
@@ -62,11 +62,10 @@ export function groupChangesForSimilarLinesTogether(
}
)
return groupedChanges.map(currentGroup => {
- const range = getMinMaxRangeLines(currentGroup)
return {
changes: currentGroup,
- changeStartLine: range[0],
- changeEndLine: range[1],
+ insertRange: getRangeUnion(currentGroup.map(change => change.insertedRange)),
+ replaceRange: getRangeUnion(currentGroup.map(change => change.change.range)),
}
})
}
@@ -96,33 +95,33 @@ export function combineNonOverlappingLinesSchemaTogether(
}
const combinedGroups = groupConsecutiveItemsByPredicate(
groupedChanges,
- (a: TextDocumentChangeGroup, b: TextDocumentChangeGroup) => {
+ (lastChange: TextDocumentChangeGroup, change: TextDocumentChangeGroup) => {
return !doLineSpansOverlap(
- a.changeStartLine,
- a.changeEndLine,
- b.changeStartLine,
- b.changeEndLine
+ lastChange.insertRange.start.line,
+ lastChange.insertRange.end.line,
+ change.replaceRange.start.line,
+ change.replaceRange.end.line
)
}
)
return combinedGroups.map(changes => ({
changes: changes.flatMap(change => change.changes),
- changeStartLine: Math.min(...changes.map(change => change.changeStartLine)),
- changeEndLine: Math.max(...changes.map(change => change.changeEndLine)),
+ insertRange: getRangeUnion(changes.map(change => change.insertRange)),
+ replaceRange: getRangeUnion(changes.map(change => change.replaceRange)),
}))
}
-function getMinMaxRangeLines(documentChanges: TextDocumentChange[]): [number, number] {
- let minLine = Number.POSITIVE_INFINITY
- let maxLine = Number.NEGATIVE_INFINITY
- for (const change of documentChanges) {
- const ranges = [change.change.range, change.insertedRange]
- for (const range of ranges) {
- minLine = Math.min(minLine, range.start.line)
- maxLine = Math.max(maxLine, range.end.line)
- }
+function getRangeUnion(ranges: vscode.Range[]): vscode.Range {
+ if (ranges.length === 0) {
+ throw new Error('Cannot get union of empty ranges')
+ }
+ let start = ranges[0].start
+ let end = ranges[0].end
+ for (const range of ranges) {
+ start = start.isBefore(range.start) ? start : range.start
+ end = end.isAfter(range.end) ? end : range.end
}
- return [minLine, maxLine]
+ return new vscode.Range(start, end)
}
/**