Merge pull request #1983 from zed-industries/multi-buffer-git-gutter
Multi buffer git gutter
This commit is contained in:
commit
de9c58d216
8 changed files with 302 additions and 27 deletions
|
@ -1817,7 +1817,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_local_a.read_with(cx_a, |buffer, _| {
|
buffer_local_a.read_with(cx_a, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(1..2, "", "two\n")],
|
&[(1..2, "", "two\n")],
|
||||||
|
@ -1837,7 +1837,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_remote_a.read_with(cx_b, |buffer, _| {
|
buffer_remote_a.read_with(cx_b, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(1..2, "", "two\n")],
|
&[(1..2, "", "two\n")],
|
||||||
|
@ -1861,7 +1861,7 @@ async fn test_git_diff_base_change(
|
||||||
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
||||||
|
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(2..3, "", "three\n")],
|
&[(2..3, "", "three\n")],
|
||||||
|
@ -1872,7 +1872,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_remote_a.read_with(cx_b, |buffer, _| {
|
buffer_remote_a.read_with(cx_b, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(2..3, "", "three\n")],
|
&[(2..3, "", "three\n")],
|
||||||
|
@ -1915,7 +1915,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_local_b.read_with(cx_a, |buffer, _| {
|
buffer_local_b.read_with(cx_a, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(1..2, "", "two\n")],
|
&[(1..2, "", "two\n")],
|
||||||
|
@ -1935,7 +1935,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_remote_b.read_with(cx_b, |buffer, _| {
|
buffer_remote_b.read_with(cx_b, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(1..2, "", "two\n")],
|
&[(1..2, "", "two\n")],
|
||||||
|
@ -1963,12 +1963,12 @@ async fn test_git_diff_base_change(
|
||||||
"{:?}",
|
"{:?}",
|
||||||
buffer
|
buffer
|
||||||
.snapshot()
|
.snapshot()
|
||||||
.git_diff_hunks_in_range(0..4, false)
|
.git_diff_hunks_in_row_range(0..4, false)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
|
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(2..3, "", "three\n")],
|
&[(2..3, "", "three\n")],
|
||||||
|
@ -1979,7 +1979,7 @@ async fn test_git_diff_base_change(
|
||||||
buffer_remote_b.read_with(cx_b, |buffer, _| {
|
buffer_remote_b.read_with(cx_b, |buffer, _| {
|
||||||
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
assert_eq!(buffer.diff_base(), Some(new_diff_base.as_ref()));
|
||||||
git::diff::assert_hunks(
|
git::diff::assert_hunks(
|
||||||
buffer.snapshot().git_diff_hunks_in_range(0..4, false),
|
buffer.snapshot().git_diff_hunks_in_row_range(0..4, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[(2..3, "", "three\n")],
|
&[(2..3, "", "three\n")],
|
||||||
|
|
|
@ -575,6 +575,15 @@ impl Item for ProjectDiagnosticsEditor {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn git_diff_recalc(
|
||||||
|
&mut self,
|
||||||
|
project: ModelHandle<Project>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
self.editor
|
||||||
|
.update(cx, |editor, cx| editor.git_diff_recalc(project, cx))
|
||||||
|
}
|
||||||
|
|
||||||
fn to_item_events(event: &Self::Event) -> Vec<ItemEvent> {
|
fn to_item_events(event: &Self::Event) -> Vec<ItemEvent> {
|
||||||
Editor::to_item_events(event)
|
Editor::to_item_events(event)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2710,11 +2710,73 @@ impl MultiBufferSnapshot {
|
||||||
row_range: Range<u32>,
|
row_range: Range<u32>,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||||
self.as_singleton()
|
let mut cursor = self.excerpts.cursor::<Point>();
|
||||||
.into_iter()
|
|
||||||
.flat_map(move |(_, _, buffer)| {
|
if reversed {
|
||||||
buffer.git_diff_hunks_in_range(row_range.clone(), reversed)
|
cursor.seek(&Point::new(row_range.end, 0), Bias::Left, &());
|
||||||
})
|
if cursor.item().is_none() {
|
||||||
|
cursor.prev(&());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cursor.seek(&Point::new(row_range.start, 0), Bias::Right, &());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::iter::from_fn(move || {
|
||||||
|
let excerpt = cursor.item()?;
|
||||||
|
let multibuffer_start = *cursor.start();
|
||||||
|
let multibuffer_end = multibuffer_start + excerpt.text_summary.lines;
|
||||||
|
if multibuffer_start.row >= row_range.end {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut buffer_start = excerpt.range.context.start;
|
||||||
|
let mut buffer_end = excerpt.range.context.end;
|
||||||
|
let excerpt_start_point = buffer_start.to_point(&excerpt.buffer);
|
||||||
|
let excerpt_end_point = excerpt_start_point + excerpt.text_summary.lines;
|
||||||
|
|
||||||
|
if row_range.start > multibuffer_start.row {
|
||||||
|
let buffer_start_point =
|
||||||
|
excerpt_start_point + Point::new(row_range.start - multibuffer_start.row, 0);
|
||||||
|
buffer_start = excerpt.buffer.anchor_before(buffer_start_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
if row_range.end < multibuffer_end.row {
|
||||||
|
let buffer_end_point =
|
||||||
|
excerpt_start_point + Point::new(row_range.end - multibuffer_start.row, 0);
|
||||||
|
buffer_end = excerpt.buffer.anchor_before(buffer_end_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
let buffer_hunks = excerpt
|
||||||
|
.buffer
|
||||||
|
.git_diff_hunks_intersecting_range(buffer_start..buffer_end, reversed)
|
||||||
|
.filter_map(move |hunk| {
|
||||||
|
let start = multibuffer_start.row
|
||||||
|
+ hunk
|
||||||
|
.buffer_range
|
||||||
|
.start
|
||||||
|
.saturating_sub(excerpt_start_point.row);
|
||||||
|
let end = multibuffer_start.row
|
||||||
|
+ hunk
|
||||||
|
.buffer_range
|
||||||
|
.end
|
||||||
|
.min(excerpt_end_point.row + 1)
|
||||||
|
.saturating_sub(excerpt_start_point.row);
|
||||||
|
|
||||||
|
Some(DiffHunk {
|
||||||
|
buffer_range: start..end,
|
||||||
|
diff_base_byte_range: hunk.diff_base_byte_range.clone(),
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if reversed {
|
||||||
|
cursor.prev(&());
|
||||||
|
} else {
|
||||||
|
cursor.next(&());
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(buffer_hunks)
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
|
pub fn range_for_syntax_ancestor<T: ToOffset>(&self, range: Range<T>) -> Option<Range<usize>> {
|
||||||
|
@ -3546,11 +3608,12 @@ impl ToPointUtf16 for PointUtf16 {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use gpui::MutableAppContext;
|
use gpui::{MutableAppContext, TestAppContext};
|
||||||
use language::{Buffer, Rope};
|
use language::{Buffer, Rope};
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::{env, rc::Rc};
|
use std::{env, rc::Rc};
|
||||||
|
use unindent::Unindent;
|
||||||
|
|
||||||
use util::test::sample_text;
|
use util::test::sample_text;
|
||||||
|
|
||||||
|
@ -4168,6 +4231,178 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
async fn test_diff_hunks_in_range(cx: &mut TestAppContext) {
|
||||||
|
use git::diff::DiffHunkStatus;
|
||||||
|
|
||||||
|
// buffer has two modified hunks with two rows each
|
||||||
|
let buffer_1 = cx.add_model(|cx| {
|
||||||
|
let mut buffer = Buffer::new(
|
||||||
|
0,
|
||||||
|
"
|
||||||
|
1.zero
|
||||||
|
1.ONE
|
||||||
|
1.TWO
|
||||||
|
1.three
|
||||||
|
1.FOUR
|
||||||
|
1.FIVE
|
||||||
|
1.six
|
||||||
|
"
|
||||||
|
.unindent(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
buffer.set_diff_base(
|
||||||
|
Some(
|
||||||
|
"
|
||||||
|
1.zero
|
||||||
|
1.one
|
||||||
|
1.two
|
||||||
|
1.three
|
||||||
|
1.four
|
||||||
|
1.five
|
||||||
|
1.six
|
||||||
|
"
|
||||||
|
.unindent(),
|
||||||
|
),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
buffer
|
||||||
|
});
|
||||||
|
|
||||||
|
// buffer has a deletion hunk and an insertion hunk
|
||||||
|
let buffer_2 = cx.add_model(|cx| {
|
||||||
|
let mut buffer = Buffer::new(
|
||||||
|
0,
|
||||||
|
"
|
||||||
|
2.zero
|
||||||
|
2.one
|
||||||
|
2.two
|
||||||
|
2.three
|
||||||
|
2.four
|
||||||
|
2.five
|
||||||
|
2.six
|
||||||
|
"
|
||||||
|
.unindent(),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
buffer.set_diff_base(
|
||||||
|
Some(
|
||||||
|
"
|
||||||
|
2.zero
|
||||||
|
2.one
|
||||||
|
2.one-and-a-half
|
||||||
|
2.two
|
||||||
|
2.three
|
||||||
|
2.four
|
||||||
|
2.six
|
||||||
|
"
|
||||||
|
.unindent(),
|
||||||
|
),
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
buffer
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
|
let multibuffer = cx.add_model(|cx| {
|
||||||
|
let mut multibuffer = MultiBuffer::new(0);
|
||||||
|
multibuffer.push_excerpts(
|
||||||
|
buffer_1.clone(),
|
||||||
|
[
|
||||||
|
// excerpt ends in the middle of a modified hunk
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(0, 0)..Point::new(1, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
// excerpt begins in the middle of a modified hunk
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(5, 0)..Point::new(6, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
multibuffer.push_excerpts(
|
||||||
|
buffer_2.clone(),
|
||||||
|
[
|
||||||
|
// excerpt ends at a deletion
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(0, 0)..Point::new(1, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
// excerpt starts at a deletion
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(2, 0)..Point::new(2, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
// excerpt fully contains a deletion hunk
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(1, 0)..Point::new(2, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
// excerpt fully contains an insertion hunk
|
||||||
|
ExcerptRange {
|
||||||
|
context: Point::new(4, 0)..Point::new(6, 5),
|
||||||
|
primary: Default::default(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
multibuffer
|
||||||
|
});
|
||||||
|
|
||||||
|
let snapshot = multibuffer.read_with(cx, |b, cx| b.snapshot(cx));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
snapshot.text(),
|
||||||
|
"
|
||||||
|
1.zero
|
||||||
|
1.ONE
|
||||||
|
1.FIVE
|
||||||
|
1.six
|
||||||
|
2.zero
|
||||||
|
2.one
|
||||||
|
2.two
|
||||||
|
2.one
|
||||||
|
2.two
|
||||||
|
2.four
|
||||||
|
2.five
|
||||||
|
2.six"
|
||||||
|
.unindent()
|
||||||
|
);
|
||||||
|
|
||||||
|
let expected = [
|
||||||
|
(DiffHunkStatus::Modified, 1..2),
|
||||||
|
(DiffHunkStatus::Modified, 2..3),
|
||||||
|
//TODO: Define better when and where removed hunks show up at range extremities
|
||||||
|
(DiffHunkStatus::Removed, 6..6),
|
||||||
|
(DiffHunkStatus::Removed, 8..8),
|
||||||
|
(DiffHunkStatus::Added, 10..11),
|
||||||
|
];
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
snapshot
|
||||||
|
.git_diff_hunks_in_range(0..12, false)
|
||||||
|
.map(|hunk| (hunk.status(), hunk.buffer_range))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
&expected,
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
snapshot
|
||||||
|
.git_diff_hunks_in_range(0..12, true)
|
||||||
|
.map(|hunk| (hunk.status(), hunk.buffer_range))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
expected
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.cloned()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.as_slice(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test(iterations = 100)]
|
#[gpui::test(iterations = 100)]
|
||||||
fn test_random_multibuffer(cx: &mut MutableAppContext, mut rng: StdRng) {
|
fn test_random_multibuffer(cx: &mut MutableAppContext, mut rng: StdRng) {
|
||||||
let operations = env::var("OPERATIONS")
|
let operations = env::var("OPERATIONS")
|
||||||
|
|
|
@ -254,7 +254,7 @@ impl<'a> EditorTestContext<'a> {
|
||||||
|
|
||||||
Actual selections:
|
Actual selections:
|
||||||
{}
|
{}
|
||||||
"},
|
"},
|
||||||
self.assertion_context(),
|
self.assertion_context(),
|
||||||
expected_marked_text,
|
expected_marked_text,
|
||||||
actual_marked_text,
|
actual_marked_text,
|
||||||
|
|
|
@ -71,18 +71,26 @@ impl BufferDiff {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hunks_in_range<'a>(
|
pub fn hunks_in_row_range<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
query_row_range: Range<u32>,
|
range: Range<u32>,
|
||||||
buffer: &'a BufferSnapshot,
|
buffer: &'a BufferSnapshot,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||||
let start = buffer.anchor_before(Point::new(query_row_range.start, 0));
|
let start = buffer.anchor_before(Point::new(range.start, 0));
|
||||||
let end = buffer.anchor_after(Point::new(query_row_range.end, 0));
|
let end = buffer.anchor_after(Point::new(range.end, 0));
|
||||||
|
self.hunks_intersecting_range(start..end, buffer, reversed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hunks_intersecting_range<'a>(
|
||||||
|
&'a self,
|
||||||
|
range: Range<Anchor>,
|
||||||
|
buffer: &'a BufferSnapshot,
|
||||||
|
reversed: bool,
|
||||||
|
) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||||
let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| {
|
let mut cursor = self.tree.filter::<_, DiffHunkSummary>(move |summary| {
|
||||||
let before_start = summary.buffer_range.end.cmp(&start, buffer).is_lt();
|
let before_start = summary.buffer_range.end.cmp(&range.start, buffer).is_lt();
|
||||||
let after_end = summary.buffer_range.start.cmp(&end, buffer).is_gt();
|
let after_end = summary.buffer_range.start.cmp(&range.end, buffer).is_gt();
|
||||||
!before_start && !after_end
|
!before_start && !after_end
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -141,7 +149,9 @@ impl BufferDiff {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn hunks<'a>(&'a self, text: &'a BufferSnapshot) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
fn hunks<'a>(&'a self, text: &'a BufferSnapshot) -> impl 'a + Iterator<Item = DiffHunk<u32>> {
|
||||||
self.hunks_in_range(0..u32::MAX, text, false)
|
let start = text.anchor_before(Point::new(0, 0));
|
||||||
|
let end = text.anchor_after(Point::new(u32::MAX, u32::MAX));
|
||||||
|
self.hunks_intersecting_range(start..end, text, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn diff<'a>(head: &'a str, current: &'a str) -> Option<GitPatch<'a>> {
|
fn diff<'a>(head: &'a str, current: &'a str) -> Option<GitPatch<'a>> {
|
||||||
|
@ -355,7 +365,7 @@ mod tests {
|
||||||
assert_eq!(diff.hunks(&buffer).count(), 8);
|
assert_eq!(diff.hunks(&buffer).count(), 8);
|
||||||
|
|
||||||
assert_hunks(
|
assert_hunks(
|
||||||
diff.hunks_in_range(7..12, &buffer, false),
|
diff.hunks_in_row_range(7..12, &buffer, false),
|
||||||
&buffer,
|
&buffer,
|
||||||
&diff_base,
|
&diff_base,
|
||||||
&[
|
&[
|
||||||
|
|
|
@ -2310,13 +2310,21 @@ impl BufferSnapshot {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn git_diff_hunks_in_range<'a>(
|
pub fn git_diff_hunks_in_row_range<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
query_row_range: Range<u32>,
|
range: Range<u32>,
|
||||||
|
reversed: bool,
|
||||||
|
) -> impl 'a + Iterator<Item = git::diff::DiffHunk<u32>> {
|
||||||
|
self.git_diff.hunks_in_row_range(range, self, reversed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn git_diff_hunks_intersecting_range<'a>(
|
||||||
|
&'a self,
|
||||||
|
range: Range<Anchor>,
|
||||||
reversed: bool,
|
reversed: bool,
|
||||||
) -> impl 'a + Iterator<Item = git::diff::DiffHunk<u32>> {
|
) -> impl 'a + Iterator<Item = git::diff::DiffHunk<u32>> {
|
||||||
self.git_diff
|
self.git_diff
|
||||||
.hunks_in_range(query_row_range, self, reversed)
|
.hunks_intersecting_range(range, self, reversed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diagnostics_in_range<'a, T, O>(
|
pub fn diagnostics_in_range<'a, T, O>(
|
||||||
|
|
|
@ -334,6 +334,15 @@ impl Item for ProjectSearchView {
|
||||||
.update(cx, |editor, cx| editor.navigate(data, cx))
|
.update(cx, |editor, cx| editor.navigate(data, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn git_diff_recalc(
|
||||||
|
&mut self,
|
||||||
|
project: ModelHandle<Project>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> Task<anyhow::Result<()>> {
|
||||||
|
self.results_editor
|
||||||
|
.update(cx, |editor, cx| editor.git_diff_recalc(project, cx))
|
||||||
|
}
|
||||||
|
|
||||||
fn to_item_events(event: &Self::Event) -> Vec<ItemEvent> {
|
fn to_item_events(event: &Self::Event) -> Vec<ItemEvent> {
|
||||||
match event {
|
match event {
|
||||||
ViewEvent::UpdateTab => vec![ItemEvent::UpdateBreadcrumbs, ItemEvent::UpdateTab],
|
ViewEvent::UpdateTab => vec![ItemEvent::UpdateBreadcrumbs, ItemEvent::UpdateTab],
|
||||||
|
|
|
@ -597,6 +597,10 @@ where
|
||||||
self.cursor.item()
|
self.cursor.item()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn item_summary(&self) -> Option<&'a T::Summary> {
|
||||||
|
self.cursor.item_summary()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
|
pub fn next(&mut self, cx: &<T::Summary as Summary>::Context) {
|
||||||
self.cursor.next_internal(&mut self.filter_node, cx);
|
self.cursor.next_internal(&mut self.filter_node, cx);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue