Skip to content

Commit fdb03d3

Browse files
Move DisplayDiffHunk into hunk_diff module (#18307)
Release Notes: - N/A Co-authored-by: Marshall <marshall@zed.dev>
1 parent c4e0f5e commit fdb03d3

File tree

4 files changed

+320
-338
lines changed

4 files changed

+320
-338
lines changed

crates/editor/src/editor.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ pub use element::{
7171
use futures::{future, FutureExt};
7272
use fuzzy::{StringMatch, StringMatchCandidate};
7373
use git::blame::GitBlame;
74-
use git::diff_hunk_to_display;
7574
use gpui::{
7675
div, impl_actions, point, prelude::*, px, relative, size, uniform_list, Action, AnyElement,
7776
AppContext, AsyncWindowContext, AvailableSpace, BackgroundExecutor, Bounds, ClipboardEntry,
@@ -84,8 +83,8 @@ use gpui::{
8483
};
8584
use highlight_matching_bracket::refresh_matching_bracket_highlights;
8685
use hover_popover::{hide_hover, HoverState};
87-
use hunk_diff::ExpandedHunks;
8886
pub(crate) use hunk_diff::HoveredHunk;
87+
use hunk_diff::{diff_hunk_to_display, ExpandedHunks};
8988
use indent_guides::ActiveIndentGuidesState;
9089
use inlay_hint_cache::{InlayHintCache, InlaySplice, InvalidationStrategy};
9190
pub use inline_completion_provider::*;

crates/editor/src/element.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@ use crate::{
77
CurrentLineHighlight, DoubleClickInMultibuffer, MultiCursorModifier, ScrollBeyondLastLine,
88
ShowScrollbar,
99
},
10-
git::{
11-
blame::{CommitDetails, GitBlame},
12-
diff_hunk_to_display, DisplayDiffHunk,
13-
},
10+
git::blame::{CommitDetails, GitBlame},
1411
hover_popover::{
1512
self, hover_at, HOVER_POPOVER_GAP, MIN_POPOVER_CHARACTER_WIDTH, MIN_POPOVER_LINE_HEIGHT,
1613
},
17-
hunk_diff::ExpandedHunk,
14+
hunk_diff::{diff_hunk_to_display, DisplayDiffHunk, ExpandedHunk},
1815
hunk_status,
1916
items::BufferSearchHighlights,
2017
mouse_context_menu::{self, MenuPosition, MouseContextMenu},

crates/editor/src/git.rs

Lines changed: 0 additions & 308 deletions
Original file line numberDiff line numberDiff line change
@@ -1,309 +1 @@
11
pub mod blame;
2-
3-
use std::ops::Range;
4-
5-
use git::diff::DiffHunkStatus;
6-
use language::Point;
7-
use multi_buffer::{Anchor, MultiBufferDiffHunk};
8-
9-
use crate::{
10-
display_map::{DisplaySnapshot, ToDisplayPoint},
11-
hunk_status, AnchorRangeExt, DisplayRow,
12-
};
13-
14-
#[derive(Debug, Clone, PartialEq, Eq)]
15-
pub enum DisplayDiffHunk {
16-
Folded {
17-
display_row: DisplayRow,
18-
},
19-
20-
Unfolded {
21-
diff_base_byte_range: Range<usize>,
22-
display_row_range: Range<DisplayRow>,
23-
multi_buffer_range: Range<Anchor>,
24-
status: DiffHunkStatus,
25-
},
26-
}
27-
28-
impl DisplayDiffHunk {
29-
pub fn start_display_row(&self) -> DisplayRow {
30-
match self {
31-
&DisplayDiffHunk::Folded { display_row } => display_row,
32-
DisplayDiffHunk::Unfolded {
33-
display_row_range, ..
34-
} => display_row_range.start,
35-
}
36-
}
37-
38-
pub fn contains_display_row(&self, display_row: DisplayRow) -> bool {
39-
let range = match self {
40-
&DisplayDiffHunk::Folded { display_row } => display_row..=display_row,
41-
42-
DisplayDiffHunk::Unfolded {
43-
display_row_range, ..
44-
} => display_row_range.start..=display_row_range.end,
45-
};
46-
47-
range.contains(&display_row)
48-
}
49-
}
50-
51-
pub fn diff_hunk_to_display(
52-
hunk: &MultiBufferDiffHunk,
53-
snapshot: &DisplaySnapshot,
54-
) -> DisplayDiffHunk {
55-
let hunk_start_point = Point::new(hunk.row_range.start.0, 0);
56-
let hunk_start_point_sub = Point::new(hunk.row_range.start.0.saturating_sub(1), 0);
57-
let hunk_end_point_sub = Point::new(
58-
hunk.row_range
59-
.end
60-
.0
61-
.saturating_sub(1)
62-
.max(hunk.row_range.start.0),
63-
0,
64-
);
65-
66-
let status = hunk_status(hunk);
67-
let is_removal = status == DiffHunkStatus::Removed;
68-
69-
let folds_start = Point::new(hunk.row_range.start.0.saturating_sub(2), 0);
70-
let folds_end = Point::new(hunk.row_range.end.0 + 2, 0);
71-
let folds_range = folds_start..folds_end;
72-
73-
let containing_fold = snapshot.folds_in_range(folds_range).find(|fold| {
74-
let fold_point_range = fold.range.to_point(&snapshot.buffer_snapshot);
75-
let fold_point_range = fold_point_range.start..=fold_point_range.end;
76-
77-
let folded_start = fold_point_range.contains(&hunk_start_point);
78-
let folded_end = fold_point_range.contains(&hunk_end_point_sub);
79-
let folded_start_sub = fold_point_range.contains(&hunk_start_point_sub);
80-
81-
(folded_start && folded_end) || (is_removal && folded_start_sub)
82-
});
83-
84-
if let Some(fold) = containing_fold {
85-
let row = fold.range.start.to_display_point(snapshot).row();
86-
DisplayDiffHunk::Folded { display_row: row }
87-
} else {
88-
let start = hunk_start_point.to_display_point(snapshot).row();
89-
90-
let hunk_end_row = hunk.row_range.end.max(hunk.row_range.start);
91-
let hunk_end_point = Point::new(hunk_end_row.0, 0);
92-
93-
let multi_buffer_start = snapshot.buffer_snapshot.anchor_before(hunk_start_point);
94-
let multi_buffer_end = snapshot.buffer_snapshot.anchor_after(hunk_end_point);
95-
let end = hunk_end_point.to_display_point(snapshot).row();
96-
97-
DisplayDiffHunk::Unfolded {
98-
display_row_range: start..end,
99-
multi_buffer_range: multi_buffer_start..multi_buffer_end,
100-
status,
101-
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
102-
}
103-
}
104-
}
105-
106-
#[cfg(test)]
107-
mod tests {
108-
use crate::Point;
109-
use crate::{editor_tests::init_test, hunk_status};
110-
use gpui::{Context, TestAppContext};
111-
use language::Capability::ReadWrite;
112-
use multi_buffer::{ExcerptRange, MultiBuffer, MultiBufferRow};
113-
use project::{FakeFs, Project};
114-
use unindent::Unindent;
115-
#[gpui::test]
116-
async fn test_diff_hunks_in_range(cx: &mut TestAppContext) {
117-
use git::diff::DiffHunkStatus;
118-
init_test(cx, |_| {});
119-
120-
let fs = FakeFs::new(cx.background_executor.clone());
121-
let project = Project::test(fs, [], cx).await;
122-
123-
// buffer has two modified hunks with two rows each
124-
let buffer_1 = project.update(cx, |project, cx| {
125-
project.create_local_buffer(
126-
"
127-
1.zero
128-
1.ONE
129-
1.TWO
130-
1.three
131-
1.FOUR
132-
1.FIVE
133-
1.six
134-
"
135-
.unindent()
136-
.as_str(),
137-
None,
138-
cx,
139-
)
140-
});
141-
buffer_1.update(cx, |buffer, cx| {
142-
buffer.set_diff_base(
143-
Some(
144-
"
145-
1.zero
146-
1.one
147-
1.two
148-
1.three
149-
1.four
150-
1.five
151-
1.six
152-
"
153-
.unindent(),
154-
),
155-
cx,
156-
);
157-
});
158-
159-
// buffer has a deletion hunk and an insertion hunk
160-
let buffer_2 = project.update(cx, |project, cx| {
161-
project.create_local_buffer(
162-
"
163-
2.zero
164-
2.one
165-
2.two
166-
2.three
167-
2.four
168-
2.five
169-
2.six
170-
"
171-
.unindent()
172-
.as_str(),
173-
None,
174-
cx,
175-
)
176-
});
177-
buffer_2.update(cx, |buffer, cx| {
178-
buffer.set_diff_base(
179-
Some(
180-
"
181-
2.zero
182-
2.one
183-
2.one-and-a-half
184-
2.two
185-
2.three
186-
2.four
187-
2.six
188-
"
189-
.unindent(),
190-
),
191-
cx,
192-
);
193-
});
194-
195-
cx.background_executor.run_until_parked();
196-
197-
let multibuffer = cx.new_model(|cx| {
198-
let mut multibuffer = MultiBuffer::new(ReadWrite);
199-
multibuffer.push_excerpts(
200-
buffer_1.clone(),
201-
[
202-
// excerpt ends in the middle of a modified hunk
203-
ExcerptRange {
204-
context: Point::new(0, 0)..Point::new(1, 5),
205-
primary: Default::default(),
206-
},
207-
// excerpt begins in the middle of a modified hunk
208-
ExcerptRange {
209-
context: Point::new(5, 0)..Point::new(6, 5),
210-
primary: Default::default(),
211-
},
212-
],
213-
cx,
214-
);
215-
multibuffer.push_excerpts(
216-
buffer_2.clone(),
217-
[
218-
// excerpt ends at a deletion
219-
ExcerptRange {
220-
context: Point::new(0, 0)..Point::new(1, 5),
221-
primary: Default::default(),
222-
},
223-
// excerpt starts at a deletion
224-
ExcerptRange {
225-
context: Point::new(2, 0)..Point::new(2, 5),
226-
primary: Default::default(),
227-
},
228-
// excerpt fully contains a deletion hunk
229-
ExcerptRange {
230-
context: Point::new(1, 0)..Point::new(2, 5),
231-
primary: Default::default(),
232-
},
233-
// excerpt fully contains an insertion hunk
234-
ExcerptRange {
235-
context: Point::new(4, 0)..Point::new(6, 5),
236-
primary: Default::default(),
237-
},
238-
],
239-
cx,
240-
);
241-
multibuffer
242-
});
243-
244-
let snapshot = multibuffer.read_with(cx, |b, cx| b.snapshot(cx));
245-
246-
assert_eq!(
247-
snapshot.text(),
248-
"
249-
1.zero
250-
1.ONE
251-
1.FIVE
252-
1.six
253-
2.zero
254-
2.one
255-
2.two
256-
2.one
257-
2.two
258-
2.four
259-
2.five
260-
2.six"
261-
.unindent()
262-
);
263-
264-
let expected = [
265-
(
266-
DiffHunkStatus::Modified,
267-
MultiBufferRow(1)..MultiBufferRow(2),
268-
),
269-
(
270-
DiffHunkStatus::Modified,
271-
MultiBufferRow(2)..MultiBufferRow(3),
272-
),
273-
//TODO: Define better when and where removed hunks show up at range extremities
274-
(
275-
DiffHunkStatus::Removed,
276-
MultiBufferRow(6)..MultiBufferRow(6),
277-
),
278-
(
279-
DiffHunkStatus::Removed,
280-
MultiBufferRow(8)..MultiBufferRow(8),
281-
),
282-
(
283-
DiffHunkStatus::Added,
284-
MultiBufferRow(10)..MultiBufferRow(11),
285-
),
286-
];
287-
288-
assert_eq!(
289-
snapshot
290-
.git_diff_hunks_in_range(MultiBufferRow(0)..MultiBufferRow(12))
291-
.map(|hunk| (hunk_status(&hunk), hunk.row_range))
292-
.collect::<Vec<_>>(),
293-
&expected,
294-
);
295-
296-
assert_eq!(
297-
snapshot
298-
.git_diff_hunks_in_range_rev(MultiBufferRow(0)..MultiBufferRow(12))
299-
.map(|hunk| (hunk_status(&hunk), hunk.row_range))
300-
.collect::<Vec<_>>(),
301-
expected
302-
.iter()
303-
.rev()
304-
.cloned()
305-
.collect::<Vec<_>>()
306-
.as_slice(),
307-
);
308-
}
309-
}

0 commit comments

Comments
 (0)