/
outbreak
/
kilocode
Обзор
Документация
Войти
/
outbreak
/
kilocode
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/services/continuedev/core/diff/streamDiff.ts
80 строк
2 KB
Eamon Nerbonne
Use kilocode coding standards (just autoformat)
21 окт 2025, 19:58
21 окт 2025, 19:58
ec253df
Код
Авторство
О чём код?
import { DiffLine, DiffType } from "../index.js" import { LineStream, matchLine } from "./util.js" /** * https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/ * Invariants: * - new + same = newLines.length * - old + same = oldLinesCopy.length * ^ (above two guarantee that all lines get represented) * - Lines are always output in order, at least among old and new separately * - Old lines in a hunk are always output before the new lines */ export async function* streamDiff(oldLines: string[], newLines: LineStream): AsyncGenerator<DiffLine> { const oldLinesCopy = [...oldLines] // If one indentation mistake is made, others are likely. So we are more permissive about matching let seenIndentationMistake = false let newLineResult = await newLines.next() while (oldLinesCopy.length > 0 && !newLineResult.done) { const { matchIndex, isPerfectMatch, newLine } = matchLine( newLineResult.value, oldLinesCopy, seenIndentationMistake, ) if (!seenIndentationMistake && newLineResult.value !== newLine) { seenIndentationMistake = true } let type: DiffType const isNewLine = matchIndex === -1 if (isNewLine) { type = "new" } else { // Insert all deleted lines before match for (let i = 0; i < matchIndex; i++) { yield { type: "old", line: oldLinesCopy.shift()! } } type = isPerfectMatch ? "same" : "old" } switch (type) { case "new": yield { type, line: newLine } break case "same": yield { type, line: oldLinesCopy.shift()! } break case "old": yield { type, line: oldLinesCopy.shift()! } yield { type: "new", line: newLine } break default: console.error(`Error streaming diff, unrecognized diff type: ${type}`) } newLineResult = await newLines.next() } // Once at the edge, only one choice if (newLineResult.done && oldLinesCopy.length > 0) { for (const oldLine of oldLinesCopy) { yield { type: "old", line: oldLine } } } if (!newLineResult.done && oldLinesCopy.length === 0) { yield { type: "new", line: newLineResult.value } for await (const newLine of newLines) { yield { type: "new", line: newLine } } } }