From 83843855f03df6a66fbceeb727e04a4db32d75d5 Mon Sep 17 00:00:00 2001 From: Maya Kid <29959320+Maya-Kid@users.noreply.github.com> Date: Thu, 15 Oct 2026 18:46:55 +1100 Subject: [PATCH 1/2] Keep changed lines that resemble file headers in a diff Signed-off-by: Maya Kid <29959320+Maya-Kid@users.noreply.github.com> --- src/components/ui/diff-view.tsx | 37 +++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/components/ui/diff-view.tsx b/src/components/ui/diff-view.tsx index 9f76a39..22ab52f 100644 --- a/src/components/ui/diff-view.tsx +++ b/src/components/ui/diff-view.tsx @@ -1,11 +1,39 @@ import { cn } from "@/lib/utils" +/** File headers and changed text can have the same prefix, even "+++ ". */ +function patchLines(patch: string): string[] { + const lines: string[] = [] + let inHunk = false + let oldLines = 0 + let newLines = 0 + for (const line of patch.replace(/\n$/, "").split("\n")) { + if (line.startsWith("diff --git ")) inHunk = false + const hunk = /^@@ -\d+(?:,(\d+))? \+\d+(?:,(\d+))? @@/.exec(line) + if (hunk) { + oldLines = Number(hunk[1] ?? 1) + newLines = Number(hunk[2] ?? 1) + inHunk = oldLines > 0 || newLines > 0 + } else if (line.startsWith("@@")) { + // Also accept abbreviated hunks, as used in compact tool output. + inHunk = true + oldLines = newLines = Infinity + } else if (!inHunk && /^(---|\+\+\+) /.test(line)) { + continue + } else if (inHunk) { + if (line.startsWith("-") || line.startsWith(" ")) oldLines-- + if (line.startsWith("+") || line.startsWith(" ")) newLines-- + if (oldLines <= 0 && newLines <= 0) inHunk = false + } + lines.push(line) + } + return lines +} + /** Lines added and removed by a unified patch, headers aside. */ function patchStats(patch: string): { added: number; removed: number } { let added = 0 let removed = 0 - for (const line of patch.split("\n")) { - if (line.startsWith("+++") || line.startsWith("---")) continue + for (const line of patchLines(patch)) { if (line.startsWith("+")) added++ else if (line.startsWith("-")) removed++ } @@ -23,10 +51,7 @@ function DiffStats({ added, removed, className }: { added: number; removed: numb /** A patch as a diff: hunks with added and removed lines coloured, headers dropped. */ function DiffView({ patch, className }: { patch: string; className?: string }) { - const lines = patch - .replace(/\n$/, "") - .split("\n") - .filter((line) => !line.startsWith("+++") && !line.startsWith("---")) + const lines = patchLines(patch) return (
Date: Thu, 15 Oct 2026 19:02:29 +1100 Subject: [PATCH 2/2] Explain the file boundaries required for compact multi-file patches Signed-off-by: Maya Kid <29959320+Maya-Kid@users.noreply.github.com> --- content/solid/diff-view.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/solid/diff-view.mdx b/content/solid/diff-view.mdx index 0f92a6c..4956563 100644 --- a/content/solid/diff-view.mdx +++ b/content/solid/diff-view.mdx @@ -27,3 +27,7 @@ import { DiffView } from "@/components/ui/diff-view" ```tsx ``` + +Pass a unified diff with complete hunk ranges. Compact or truncated hunks are +also supported; keep the `diff --git` separators when combining them across +multiple files so file headers can be distinguished from changed text.