Skip to content

Commit 9f585b2

Browse files
committed
fix Hunk header display
1 parent 4db149f commit 9f585b2

5 files changed

Lines changed: 73 additions & 9 deletions

File tree

diff/README.mbt.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ test "patience diff keeps unique anchors in place" {
7474
## Group Into Hunks And Render
7575

7676
`group` splits the edit script into `Hunk[T]` values, keeping `radius` lines
77-
of surrounding context (default 3). Each `Hunk[T]` implements `Show`, so you
78-
can print it directly as unified-diff output.
77+
of surrounding context (default 3). `radius` must be non-negative, and
78+
`radius=0` emits hunks without surrounding context. Each `Hunk[T]` implements
79+
`Show`, so you can print it directly as unified-diff output.
7980

8081
```mbt check
8182
///|

diff/diff_test.mbt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,39 @@ test "delete then insert to hunks" {
175175
)
176176
}
177177

178+
///|
179+
test "delete then insert to hunks without context" {
180+
let old = ["fn main() {", " println(\"foo\")", "}"][:]
181+
let new = ["fn main() {", " println(\"bar\")", "}"][:]
182+
let d = @diff.Diff(old~, new~)
183+
let patience = @diff.Diff(old~, new~, patience=true)
184+
inspect(
185+
hunks_to_string(d.group(radius=0)),
186+
content=(
187+
#|@@ -2 +2 @@
188+
#|- println("foo")
189+
#|+ println("bar")
190+
#|
191+
),
192+
)
193+
inspect(
194+
hunks_to_string(patience.group(radius=0)),
195+
content=(
196+
#|@@ -2 +2 @@
197+
#|- println("foo")
198+
#|+ println("bar")
199+
#|
200+
),
201+
)
202+
}
203+
204+
///|
205+
test "panic group with negative radius" {
206+
let old = ["fn main() {", "}"][:]
207+
let new = old
208+
ignore(@diff.Diff(old~, new~).group(radius=-1))
209+
}
210+
178211
///|
179212
test "large text to hunks" {
180213
let old = [

diff/edit.mbt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ fn[T] group_edits(
8888
old~ : ArrayView[T],
8989
new~ : ArrayView[T],
9090
) -> Array[Hunk[T]] {
91+
guard radius >= 0 else { abort("radius must be non-negative") }
9192
if edits.is_empty() {
9293
return []
9394
}

diff/edit_wbtest.mbt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,14 @@ test "range display for single and empty span" {
5959
content="@@ -4,0 +3 @@",
6060
)
6161
}
62+
63+
///|
64+
test "range display spans replacement ending with insert" {
65+
inspect(
66+
HunkHeader::new([
67+
Delete(old_index=1, new_index=1, old_len=1),
68+
Insert(old_index=1, new_index=1, new_len=1),
69+
]).to_string(),
70+
content="@@ -2 +2 @@",
71+
)
72+
}

diff/hunk.mbt

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,31 @@ priv struct HunkHeader(Range, Range)
3838
///|
3939
/// Creates a hunk header from a (non empty) array of edit
4040
fn HunkHeader::new(edits : ArrayView[Edit]) -> Self {
41-
let first = edits[0]
42-
let last = edits[edits.length() - 1]
43-
let old_start = first.old_range().0
44-
let new_start = first.new_range().0
45-
let old_end = last.old_range().1
46-
let new_end = last.new_range().1
47-
HunkHeader(Range(old_start, old_end), Range(new_start, new_end))
41+
let (first_old_start, first_old_end) = edits[0].old_range()
42+
let (first_new_start, first_new_end) = edits[0].new_range()
43+
let mut old_end = first_old_end
44+
let mut new_end = first_new_end
45+
let mut found_old_end = false
46+
let mut found_new_end = false
47+
let mut i = edits.length()
48+
while i > 0 {
49+
i -= 1
50+
let edit = edits[i]
51+
let (edit_old_start, edit_old_end) = edit.old_range()
52+
let (edit_new_start, edit_new_end) = edit.new_range()
53+
if !found_old_end && edit_old_start != edit_old_end {
54+
old_end = edit_old_end
55+
found_old_end = true
56+
}
57+
if !found_new_end && edit_new_start != edit_new_end {
58+
new_end = edit_new_end
59+
found_new_end = true
60+
}
61+
if found_old_end && found_new_end {
62+
break
63+
}
64+
}
65+
HunkHeader(Range(first_old_start, old_end), Range(first_new_start, new_end))
4866
}
4967

5068
///|

0 commit comments

Comments
 (0)