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