import { diffArrays } from "diff";
import type { BlameRange } from "~/lib/code-intel";
const MAX_EDIT_LENGTH = 20_000;
const DIFF_TIMEOUT_MS = 1000;
/** Maps each new-version line index to its old-version index (-1 when added); null if the diff gave up. */
export function mapLines(oldLines: string[], newLines: string[]): Int32Array | null {
const changes = diffArrays(oldLines, newLines, { maxEditLength: MAX_EDIT_LENGTH, timeout: DIFF_TIMEOUT_MS });
if (!changes) return null;
const map = new Int32Array(newLines.length).fill(-1);
let oldIndex = 0;
let newIndex = 0;
for (const change of changes) {
const count = change.count;
if (change.added) newIndex += count;
else if (change.removed) oldIndex += count;
else {
for (let offset = 0; offset < count; offset++) map[newIndex + offset] = oldIndex + offset;
oldIndex += count;
newIndex += count;
}
}
return map;
}
export function splitLines(text: string): string[] {
const lines = text.split("\n");
if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
return lines;
}
/** Tracks unattributed final-version lines through older versions of a file. */
export class LineTracker {
readonly owners: Array<string | null>;
private pending: Array<{ line: number; current: number }>;
constructor(lineCount: number) {
this.owners = new Array<string | null>(lineCount).fill(null);
this.pending = Array.from({ length: lineCount }, (_, line) => ({ line, current: line }));