Files
oh-my-pi/packages/hashline/src/diff-preview.ts
T
can1357 b12e4698a6 feat: added @oh-my-pi/hashline package and migrated hashline tooling
- Added a dedicated @oh-my-pi/hashline package with parser, patcher, filesystem, snapshots, and release metadata.
- Migrated coding-agent hashline and stream entrypoints to @oh-my-pi/hashline and removed old hashline module exports.
- Changed multi-section hashline execution to validate section hashes and flush diagnostics only at the final commit.
- Added session fileSnapshotStore support and rewired edit/read/search/write tools to use it instead of fileReadCache.
2026-05-27 04:03:49 +02:00

50 lines
1.8 KiB
TypeScript

/**
* Re-number a unified diff that uses the `+<lineNum>|content` /
* `-<lineNum>|content` / ` <lineNum>|content` line format into a compact
* preview that anchors every line to its post-edit position. Added lines,
* removed lines, and context lines all end up with a hashline-style anchor
* so a follow-up edit can reuse them directly.
*
* This is intentionally decoupled from the diff producer: anything that
* emits the `<sign><lineNum>|<content>` shape works.
*/
import type { CompactDiffOptions, CompactDiffPreview } from "./types";
export function buildCompactDiffPreview(diff: string, _options: CompactDiffOptions = {}): CompactDiffPreview {
const lines = diff.length === 0 ? [] : diff.split("\n");
let addedLines = 0;
let removedLines = 0;
// External diff producers number `+` lines with the post-edit line number,
// `-` lines with the pre-edit line number, and context lines with the
// pre-edit line number. To emit fresh line numbers usable for follow-up
// edits, convert context-line numbers to post-edit positions by tracking
// the running offset (added so far - removed so far) as we walk the diff.
const formatted = lines.map(line => {
const kind = line[0];
if (kind !== "+" && kind !== "-" && kind !== " ") return line;
const body = line.slice(1);
const sep = body.indexOf("|");
if (sep === -1) return line;
const lineNumber = Number.parseInt(body.slice(0, sep), 10);
const content = body.slice(sep + 1);
switch (kind) {
case "+":
addedLines++;
return `+${lineNumber}:${content}`;
case "-":
removedLines++;
return `-${lineNumber}:${content}`;
default: {
const newLineNumber = lineNumber + addedLines - removedLines;
return ` ${newLineNumber}:${content}`;
}
}
});
return { preview: formatted.join("\n"), addedLines, removedLines };
}