Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/extension/inlineEdits/node/diffNextEdits.ts
13399 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IDiffService } from '../../../platform/diff/common/diffService';
7
import { LineEdit, LineReplacement } from '../../../util/vs/editor/common/core/edits/lineEdit';
8
import { LineRangeMapping } from '../../../util/vs/editor/common/diff/rangeMapping';
9
import { Lines } from '../../prompt/node/editGeneration';
10
import { getTrailingArrayEmptyLineCount } from '../../prompts/node/codeMapper/codeMapper';
11
12
/**
13
* Generates the next edit based on the current lines and the desired lines.
14
*/
15
export async function generateDiffNextEdits(
16
diffService: IDiffService,
17
currentLines: string[],
18
desiredLines: Lines
19
): Promise<LineEdit> {
20
const adjustedDesiredLines = eliminateTrimEmptyLinesDifference(currentLines, desiredLines);
21
const diff = await diffService.computeDiff(
22
currentLines.join('\n'),
23
adjustedDesiredLines.join('\n'),
24
{
25
ignoreTrimWhitespace: false,
26
maxComputationTimeMs: 1000,
27
computeMoves: false
28
}
29
);
30
const lineEdit = createLineEditFromDiff(diff.changes, adjustedDesiredLines);
31
return lineEdit;
32
}
33
34
function eliminateTrimEmptyLinesDifference(sourceLines: Lines, resultLines: Lines): Lines {
35
const leadingEmptyLineCount = getLeadingEmptyLineCount(sourceLines);
36
const trailingEmptyLineCount = getTrailingArrayEmptyLineCount(sourceLines);
37
38
const leadingResultEmptyLineCount = getLeadingEmptyLineCount(resultLines);
39
const trailingResultEmptyLineCount = getTrailingArrayEmptyLineCount(resultLines);
40
41
const trimResultLines = resultLines.slice(leadingResultEmptyLineCount, resultLines.length - trailingResultEmptyLineCount);
42
return [
43
...sourceLines.slice(0, leadingEmptyLineCount),
44
...trimResultLines,
45
...sourceLines.slice(sourceLines.length - trailingEmptyLineCount, sourceLines.length)
46
];
47
}
48
49
function getLeadingEmptyLineCount(lines: readonly string[]): number {
50
for (let i = 0; i < lines.length; i++) {
51
if (lines[i].trim() !== '') {
52
return i;
53
}
54
}
55
return lines.length;
56
}
57
58
function createLineEditFromDiff(changes: readonly LineRangeMapping[], resultingLines: Lines): LineEdit {
59
return new LineEdit(changes.map((change) => {
60
return createSingleLineEditFromDiff(change, resultingLines);
61
}));
62
}
63
64
function createSingleLineEditFromDiff(diff: LineRangeMapping, newLines: readonly string[]): LineReplacement {
65
return new LineReplacement(diff.original, newLines.slice(diff.modified.startLineNumber - 1, diff.modified.endLineNumberExclusive - 1));
66
}
67
68