Detailed changes
@@ -135,7 +135,7 @@ impl AssistantDiff {
continue;
};
- let path_key = PathKey::namespaced("", file.full_path(cx).into());
+ let path_key = PathKey::namespaced(0, file.full_path(cx).into());
paths_to_delete.remove(&path_key);
let snapshot = buffer.read(cx).snapshot();
@@ -152,7 +152,7 @@ impl AssistantDiff {
let (was_empty, is_excerpt_newly_added) =
self.multibuffer.update(cx, |multibuffer, cx| {
let was_empty = multibuffer.is_empty();
- let is_excerpt_newly_added = multibuffer.set_excerpts_for_path(
+ let (_, is_excerpt_newly_added) = multibuffer.set_excerpts_for_path(
path_key.clone(),
buffer.clone(),
diff_hunk_ranges,
@@ -147,7 +147,7 @@ pub use multi_buffer::{
};
use multi_buffer::{
ExcerptInfo, ExpandExcerptDirection, MultiBufferDiffHunk, MultiBufferPoint, MultiBufferRow,
- MultiOrSingleBufferOffsetRange, ToOffsetUtf16,
+ MultiOrSingleBufferOffsetRange, PathKey, ToOffsetUtf16,
};
use parking_lot::Mutex;
use project::{
@@ -5035,17 +5035,19 @@ impl Editor {
let excerpt_buffer = cx.new(|cx| {
let mut multibuffer = MultiBuffer::new(Capability::ReadWrite).with_title(title);
for (buffer_handle, transaction) in &entries {
- let buffer = buffer_handle.read(cx);
- ranges_to_highlight.extend(
- multibuffer.push_excerpts_with_context_lines(
- buffer_handle.clone(),
- buffer
- .edited_ranges_for_transaction::<usize>(transaction)
- .collect(),
- DEFAULT_MULTIBUFFER_CONTEXT,
- cx,
- ),
+ let edited_ranges = buffer_handle
+ .read(cx)
+ .edited_ranges_for_transaction::<Point>(transaction)
+ .collect::<Vec<_>>();
+ let (ranges, _) = multibuffer.set_excerpts_for_path(
+ PathKey::for_buffer(buffer_handle, cx),
+ buffer_handle.clone(),
+ edited_ranges,
+ DEFAULT_MULTIBUFFER_CONTEXT,
+ cx,
);
+
+ ranges_to_highlight.extend(ranges);
}
multibuffer.push_transaction(entries.iter().map(|(b, t)| (b, t)), cx);
multibuffer
@@ -13531,7 +13533,7 @@ impl Editor {
// If there are multiple definitions, open them in a multibuffer
locations.sort_by_key(|location| location.buffer.read(cx).remote_id());
let mut locations = locations.into_iter().peekable();
- let mut ranges = Vec::new();
+ let mut ranges: Vec<Range<Anchor>> = Vec::new();
let capability = workspace.project().read(cx).capability();
let excerpt_buffer = cx.new(|cx| {
@@ -13539,12 +13541,12 @@ impl Editor {
while let Some(location) = locations.next() {
let buffer = location.buffer.read(cx);
let mut ranges_for_buffer = Vec::new();
- let range = location.range.to_offset(buffer);
+ let range = location.range.to_point(buffer);
ranges_for_buffer.push(range.clone());
while let Some(next_location) = locations.peek() {
if next_location.buffer == location.buffer {
- ranges_for_buffer.push(next_location.range.to_offset(buffer));
+ ranges_for_buffer.push(next_location.range.to_point(buffer));
locations.next();
} else {
break;
@@ -13552,12 +13554,14 @@ impl Editor {
}
ranges_for_buffer.sort_by_key(|range| (range.start, Reverse(range.end)));
- ranges.extend(multibuffer.push_excerpts_with_context_lines(
+ let (new_ranges, _) = multibuffer.set_excerpts_for_path(
+ PathKey::for_buffer(&location.buffer, cx),
location.buffer.clone(),
ranges_for_buffer,
DEFAULT_MULTIBUFFER_CONTEXT,
cx,
- ))
+ );
+ ranges.extend(new_ranges)
}
multibuffer.with_title(title)
@@ -15824,7 +15824,7 @@ async fn test_display_diff_hunks(cx: &mut TestAppContext) {
for buffer in &buffers {
let snapshot = buffer.read(cx).snapshot();
multibuffer.set_excerpts_for_path(
- PathKey::namespaced("", buffer.read(cx).file().unwrap().path().clone()),
+ PathKey::namespaced(0, buffer.read(cx).file().unwrap().path().clone()),
buffer.clone(),
vec![text::Anchor::MIN.to_point(&snapshot)..text::Anchor::MAX.to_point(&snapshot)],
DEFAULT_MULTIBUFFER_CONTEXT,
@@ -44,8 +44,8 @@ struct CommitMetadataFile {
worktree_id: WorktreeId,
}
-const COMMIT_METADATA_NAMESPACE: &'static str = "0";
-const FILE_NAMESPACE: &'static str = "1";
+const COMMIT_METADATA_NAMESPACE: u32 = 0;
+const FILE_NAMESPACE: u32 = 1;
impl CommitView {
pub fn open(
@@ -61,9 +61,9 @@ struct DiffBuffer {
file_status: FileStatus,
}
-const CONFLICT_NAMESPACE: &'static str = "0";
-const TRACKED_NAMESPACE: &'static str = "1";
-const NEW_NAMESPACE: &'static str = "2";
+const CONFLICT_NAMESPACE: u32 = 0;
+const TRACKED_NAMESPACE: u32 = 1;
+const NEW_NAMESPACE: u32 = 2;
impl ProjectDiff {
pub(crate) fn register(workspace: &mut Workspace, cx: &mut Context<Workspace>) {
@@ -404,7 +404,7 @@ impl ProjectDiff {
let (was_empty, is_excerpt_newly_added) = self.multibuffer.update(cx, |multibuffer, cx| {
let was_empty = multibuffer.is_empty();
- let is_newly_added = multibuffer.set_excerpts_for_path(
+ let (_, is_newly_added) = multibuffer.set_excerpts_for_path(
path_key.clone(),
buffer,
diff_hunk_ranges,
@@ -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| {