Use new multibuffer excerpts in find-all-references and friends (#27876)
Release Notes: - N/A --------- Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
parent
e7290df02b
commit
9bc4697a33
7 changed files with 54 additions and 139 deletions
|
@ -38,7 +38,7 @@ use std::{
|
|||
iter::{self, FromIterator},
|
||||
mem,
|
||||
ops::{Range, RangeBounds, Sub},
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
str,
|
||||
sync::Arc,
|
||||
|
@ -167,15 +167,23 @@ impl MultiBufferDiffHunk {
|
|||
|
||||
#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Hash, Debug)]
|
||||
pub struct PathKey {
|
||||
namespace: &'static str,
|
||||
namespace: u32,
|
||||
path: Arc<Path>,
|
||||
}
|
||||
|
||||
impl PathKey {
|
||||
pub fn namespaced(namespace: &'static str, path: Arc<Path>) -> Self {
|
||||
pub fn namespaced(namespace: u32, path: Arc<Path>) -> Self {
|
||||
Self { namespace, path }
|
||||
}
|
||||
|
||||
pub fn for_buffer(buffer: &Entity<Buffer>, cx: &App) -> Self {
|
||||
if let Some(file) = buffer.read(cx).file() {
|
||||
Self::namespaced(1, Arc::from(file.full_path(cx)))
|
||||
} else {
|
||||
Self::namespaced(0, Arc::from(PathBuf::from(buffer.entity_id().to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Arc<Path> {
|
||||
&self.path
|
||||
}
|
||||
|
@ -1448,45 +1456,6 @@ impl MultiBuffer {
|
|||
self.insert_excerpts_after(ExcerptId::max(), buffer, ranges, cx)
|
||||
}
|
||||
|
||||
pub fn push_excerpts_with_context_lines<O>(
|
||||
&mut self,
|
||||
buffer: Entity<Buffer>,
|
||||
ranges: Vec<Range<O>>,
|
||||
context_line_count: u32,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Vec<Range<Anchor>>
|
||||
where
|
||||
O: text::ToPoint + text::ToOffset,
|
||||
{
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||
let (excerpt_ranges, range_counts) =
|
||||
build_excerpt_ranges(&buffer_snapshot, &ranges, context_line_count);
|
||||
|
||||
let excerpt_ids = self.push_excerpts(buffer, excerpt_ranges, cx);
|
||||
|
||||
let mut anchor_ranges = Vec::new();
|
||||
let mut ranges = ranges.into_iter();
|
||||
for (excerpt_id, range_count) in excerpt_ids.into_iter().zip(range_counts.into_iter()) {
|
||||
anchor_ranges.extend(ranges.by_ref().take(range_count).map(|range| {
|
||||
let start = Anchor {
|
||||
buffer_id: Some(buffer_id),
|
||||
excerpt_id,
|
||||
text_anchor: buffer_snapshot.anchor_after(range.start),
|
||||
diff_base_anchor: None,
|
||||
};
|
||||
let end = Anchor {
|
||||
buffer_id: Some(buffer_id),
|
||||
excerpt_id,
|
||||
text_anchor: buffer_snapshot.anchor_after(range.end),
|
||||
diff_base_anchor: None,
|
||||
};
|
||||
start..end
|
||||
}))
|
||||
}
|
||||
anchor_ranges
|
||||
}
|
||||
|
||||
pub fn location_for_path(&self, path: &PathKey, cx: &App) -> Option<Anchor> {
|
||||
let excerpt_id = self.excerpts_by_path.get(path)?.first()?;
|
||||
let snapshot = self.snapshot(cx);
|
||||
|
@ -1589,17 +1558,16 @@ impl MultiBuffer {
|
|||
&mut self,
|
||||
path: PathKey,
|
||||
buffer: Entity<Buffer>,
|
||||
ranges: Vec<Range<Point>>,
|
||||
ranges: impl IntoIterator<Item = Range<Point>>,
|
||||
context_line_count: u32,
|
||||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
) -> (Vec<Range<Anchor>>, bool) {
|
||||
let buffer_snapshot = buffer.update(cx, |buffer, _| buffer.snapshot());
|
||||
|
||||
let excerpt_ranges = ranges.into_iter().map(|range| {
|
||||
let start = range
|
||||
.start
|
||||
.saturating_sub(Point::new(context_line_count, 0));
|
||||
let end_row = (range.end.row + 2).min(buffer_snapshot.max_point().row);
|
||||
let start_row = range.start.row.saturating_sub(context_line_count);
|
||||
let start = Point::new(start_row, 0);
|
||||
let end_row = (range.end.row + context_line_count).min(buffer_snapshot.max_point().row);
|
||||
let end = Point::new(end_row, buffer_snapshot.line_len(end_row));
|
||||
ExcerptRange {
|
||||
context: start..end,
|
||||
|
@ -1607,9 +1575,7 @@ impl MultiBuffer {
|
|||
}
|
||||
});
|
||||
|
||||
let (_, is_new) =
|
||||
self.set_excerpt_ranges_for_path(path, buffer, excerpt_ranges.collect(), cx);
|
||||
is_new
|
||||
self.set_excerpt_ranges_for_path(path, buffer, excerpt_ranges.collect(), cx)
|
||||
}
|
||||
|
||||
/// Sets excerpts, returns `true` if at least one new excerpt was added.
|
||||
|
|
|
@ -710,8 +710,9 @@ fn test_expand_excerpts(cx: &mut App) {
|
|||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
|
||||
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer.push_excerpts_with_context_lines(
|
||||
buffer.clone(),
|
||||
multibuffer.set_excerpts_for_path(
|
||||
PathKey::for_buffer(&buffer, cx),
|
||||
buffer,
|
||||
vec![
|
||||
// Note that in this test, this first excerpt
|
||||
// does not contain a new line
|
||||
|
@ -765,7 +766,6 @@ fn test_expand_excerpts(cx: &mut App) {
|
|||
"ccc\n", //
|
||||
"ddd\n", //
|
||||
"eee\n", //
|
||||
"fff\n", // End of excerpt
|
||||
"fff\n", //
|
||||
"ggg\n", //
|
||||
"hhh\n", //
|
||||
|
@ -780,59 +780,6 @@ fn test_expand_excerpts(cx: &mut App) {
|
|||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_push_excerpts_with_context_lines(cx: &mut App) {
|
||||
let buffer = cx.new(|cx| Buffer::local(sample_text(20, 3, 'a'), cx));
|
||||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
|
||||
let anchor_ranges = multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer.push_excerpts_with_context_lines(
|
||||
buffer.clone(),
|
||||
vec![
|
||||
// Note that in this test, this first excerpt
|
||||
// does contain a new line
|
||||
Point::new(3, 2)..Point::new(4, 2),
|
||||
Point::new(7, 1)..Point::new(7, 3),
|
||||
Point::new(15, 0)..Point::new(15, 0),
|
||||
],
|
||||
2,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let snapshot = multibuffer.read(cx).snapshot(cx);
|
||||
assert_eq!(
|
||||
snapshot.text(),
|
||||
concat!(
|
||||
"bbb\n", // Preserve newlines
|
||||
"ccc\n", //
|
||||
"ddd\n", //
|
||||
"eee\n", //
|
||||
"fff\n", //
|
||||
"ggg\n", //
|
||||
"hhh\n", //
|
||||
"iii\n", //
|
||||
"jjj\n", //
|
||||
"nnn\n", //
|
||||
"ooo\n", //
|
||||
"ppp\n", //
|
||||
"qqq\n", //
|
||||
"rrr", //
|
||||
)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
anchor_ranges
|
||||
.iter()
|
||||
.map(|range| range.to_point(&snapshot))
|
||||
.collect::<Vec<_>>(),
|
||||
vec![
|
||||
Point::new(2, 2)..Point::new(3, 2),
|
||||
Point::new(6, 1)..Point::new(6, 3),
|
||||
Point::new(11, 0)..Point::new(11, 0)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test(iterations = 100)]
|
||||
async fn test_push_multiple_excerpts_with_context_lines(cx: &mut TestAppContext) {
|
||||
let buffer_1 = cx.new(|cx| Buffer::local(sample_text(20, 3, 'a'), cx));
|
||||
|
@ -1513,7 +1460,7 @@ fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) {
|
|||
cx,
|
||||
)
|
||||
});
|
||||
let path1: PathKey = PathKey::namespaced("0", Path::new("/").into());
|
||||
let path1: PathKey = PathKey::namespaced(0, Path::new("/").into());
|
||||
|
||||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
|
@ -1539,13 +1486,11 @@ fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) {
|
|||
one
|
||||
two
|
||||
two.five
|
||||
three
|
||||
-----
|
||||
four
|
||||
five
|
||||
six
|
||||
seven
|
||||
eight
|
||||
-----
|
||||
nine
|
||||
ten
|
||||
|
@ -1561,8 +1506,8 @@ fn test_set_excerpts_for_buffer_ordering(cx: &mut TestAppContext) {
|
|||
path1.clone(),
|
||||
buf1.clone(),
|
||||
vec![
|
||||
Point::row_range(0..2),
|
||||
Point::row_range(5..6),
|
||||
Point::row_range(0..3),
|
||||
Point::row_range(5..7),
|
||||
Point::row_range(10..11),
|
||||
],
|
||||
1,
|
||||
|
@ -1611,7 +1556,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) {
|
|||
cx,
|
||||
)
|
||||
});
|
||||
let path1: PathKey = PathKey::namespaced("0", Path::new("/").into());
|
||||
let path1: PathKey = PathKey::namespaced(0, Path::new("/").into());
|
||||
let buf2 = cx.new(|cx| {
|
||||
Buffer::local(
|
||||
indoc! {
|
||||
|
@ -1630,7 +1575,7 @@ fn test_set_excerpts_for_buffer(cx: &mut TestAppContext) {
|
|||
cx,
|
||||
)
|
||||
});
|
||||
let path2 = PathKey::namespaced("x", Path::new("/").into());
|
||||
let path2 = PathKey::namespaced(1, Path::new("/").into());
|
||||
|
||||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadWrite));
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue