mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix(jetbrains): render multi-hunk diffs
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@kilocode/kilo-jetbrains": patch
|
||||
---
|
||||
|
||||
Render multi-hunk modified-file diffs correctly in the JetBrains diff viewer.
|
||||
+8
-5
@@ -53,11 +53,14 @@ internal object DiffPatchReconstruct {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Both producers (CLI snapshot and branchDiff) emit a single full-context hunk. A patch with
|
||||
// several hunks, or one whose header lengths don't match the reconstructed body, has elided
|
||||
// context: reconstructing would place every line at the wrong number, so fall back to the
|
||||
// raw-patch view (renderable = false) instead of showing a misaligned side-by-side diff.
|
||||
if (hunks != 1 || oldSeen != oldLen || newSeen != newLen) return DiffSides("", "", false)
|
||||
// A patch may carry several hunks (limited-context git output) or a single full-context hunk.
|
||||
// We concatenate every hunk body into contiguous before/after text: unchanged context lines
|
||||
// anchor each region so the resulting side-by-side still colors adds/removes correctly. The
|
||||
// elided gaps between hunks collapse (line numbers restart at 1), which is acceptable for a
|
||||
// "what changed" view and far better than the all-green raw-patch fallback. We still bail when
|
||||
// there is no hunk, or when the header lengths don't match the reconstructed body (truncated
|
||||
// context), because that would place lines against the wrong side.
|
||||
if (hunks < 1 || oldSeen != oldLen || newSeen != newLen) return DiffSides("", "", false)
|
||||
val left = if (added(patch)) "" else before.toString().removeSuffix("\n")
|
||||
val right = if (deleted(patch)) "" else after.toString().removeSuffix("\n")
|
||||
return DiffSides(left, right, true)
|
||||
|
||||
+36
-1
@@ -133,7 +133,42 @@ class DiffPatchReconstructTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multi hunk partial context patch is not renderable`() {
|
||||
fun `multi hunk patch reconstructs concatenated changed regions`() {
|
||||
// Turn/tool diffs are ordinary limited-context git output with several hunks. The reconstruction
|
||||
// stitches each hunk body into contiguous before/after text so the diff editor colors the
|
||||
// changes instead of dumping the raw patch as all-added lines. Inter-hunk gaps collapse.
|
||||
val dto = DiffFileDto(
|
||||
file = "src/A.kt",
|
||||
additions = 2,
|
||||
deletions = 2,
|
||||
patch = """
|
||||
diff --git a/src/A.kt b/src/A.kt
|
||||
--- a/src/A.kt
|
||||
+++ b/src/A.kt
|
||||
@@ -1,3 +1,3 @@
|
||||
one
|
||||
-two
|
||||
+TWO
|
||||
three
|
||||
@@ -20,3 +20,3 @@
|
||||
twenty
|
||||
-x
|
||||
+X
|
||||
z
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
val sides = DiffPatchReconstruct.sides(dto)
|
||||
|
||||
assertTrue(sides.renderable)
|
||||
assertEquals("one\ntwo\nthree\ntwenty\nx\nz", sides.before)
|
||||
assertEquals("one\nTWO\nthree\ntwenty\nX\nz", sides.after)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `multi hunk patch with truncated context is not renderable`() {
|
||||
// header claims 3 old / 3 new lines per hunk but the body carries only 2 of each: reconstructing
|
||||
// would misalign the sides, so fall back to the raw-patch view.
|
||||
val dto = DiffFileDto(
|
||||
file = "src/A.kt",
|
||||
additions = 2,
|
||||
|
||||
+25
@@ -291,6 +291,31 @@ class KiloDiffEditorContentTest : BasePlatformTestCase() {
|
||||
assertEquals("hello\nworld", contents[1])
|
||||
}
|
||||
|
||||
fun `test diff request reconstructs multi hunk modified patch`() {
|
||||
// Regression: multi-hunk modified diffs used to fall back to an empty original + raw patch on
|
||||
// the right, rendering every line as added. They now reconstruct into a real side-by-side diff.
|
||||
val patch = """
|
||||
diff --git a/src/App.kt b/src/App.kt
|
||||
--- a/src/App.kt
|
||||
+++ b/src/App.kt
|
||||
@@ -1,3 +1,3 @@
|
||||
one
|
||||
-two
|
||||
+TWO
|
||||
three
|
||||
@@ -20,3 +20,3 @@
|
||||
twenty
|
||||
-x
|
||||
+X
|
||||
z
|
||||
""".trimIndent()
|
||||
val request = diffRequest(project, file("src/App.kt", 2, 2, patch = patch)) as SimpleDiffRequest
|
||||
val contents = request.contents.map(::content)
|
||||
|
||||
assertEquals("one\ntwo\nthree\ntwenty\nx\nz", contents[0])
|
||||
assertEquals("one\nTWO\nthree\ntwenty\nX\nz", contents[1])
|
||||
}
|
||||
|
||||
fun `test tree displays absolute files relative to workspace`() {
|
||||
val parent = Disposer.newDisposable()
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user