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.
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 (