Compare commits
1 Commits
edit-diffs
...
refactor-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a55062dd1 |
@@ -228,19 +228,20 @@ impl InlineAssistant {
|
|||||||
let newest_selection = newest_selection.unwrap();
|
let newest_selection = newest_selection.unwrap();
|
||||||
|
|
||||||
let mut codegen_ranges = Vec::new();
|
let mut codegen_ranges = Vec::new();
|
||||||
for (excerpt_id, buffer, buffer_range) in
|
for (excerpt, buffer_range) in
|
||||||
snapshot.excerpts_in_ranges(selections.iter().map(|selection| {
|
snapshot.disjoint_ranges_to_buffer_ranges(selections.iter().map(|selection| {
|
||||||
snapshot.anchor_before(selection.start)..snapshot.anchor_after(selection.end)
|
snapshot.anchor_before(selection.start)..snapshot.anchor_after(selection.end)
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
let buffer = excerpt.buffer();
|
||||||
let start = Anchor {
|
let start = Anchor {
|
||||||
buffer_id: Some(buffer.remote_id()),
|
buffer_id: Some(buffer.remote_id()),
|
||||||
excerpt_id,
|
excerpt_id: excerpt.id(),
|
||||||
text_anchor: buffer.anchor_before(buffer_range.start),
|
text_anchor: buffer.anchor_before(buffer_range.start),
|
||||||
};
|
};
|
||||||
let end = Anchor {
|
let end = Anchor {
|
||||||
buffer_id: Some(buffer.remote_id()),
|
buffer_id: Some(buffer.remote_id()),
|
||||||
excerpt_id,
|
excerpt_id: excerpt.id(),
|
||||||
text_anchor: buffer.anchor_after(buffer_range.end),
|
text_anchor: buffer.anchor_after(buffer_range.end),
|
||||||
};
|
};
|
||||||
codegen_ranges.push(start..end);
|
codegen_ranges.push(start..end);
|
||||||
@@ -798,9 +799,10 @@ impl InlineAssistant {
|
|||||||
let language_name = assist.editor.upgrade().and_then(|editor| {
|
let language_name = assist.editor.upgrade().and_then(|editor| {
|
||||||
let multibuffer = editor.read(cx).buffer().read(cx);
|
let multibuffer = editor.read(cx).buffer().read(cx);
|
||||||
let multibuffer_snapshot = multibuffer.snapshot(cx);
|
let multibuffer_snapshot = multibuffer.snapshot(cx);
|
||||||
let ranges = multibuffer_snapshot.range_to_buffer_ranges(assist.range.clone());
|
let mut ranges =
|
||||||
|
multibuffer_snapshot.range_to_buffer_ranges(assist.range.clone());
|
||||||
ranges
|
ranges
|
||||||
.first()
|
.next()
|
||||||
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
||||||
.map(|language| language.name())
|
.map(|language| language.name())
|
||||||
});
|
});
|
||||||
@@ -2625,9 +2627,10 @@ impl CodegenAlternative {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let snapshot = multi_buffer.read(cx).snapshot(cx);
|
let snapshot = multi_buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
// TODO: Could be made more efficient by using a reverse iterator.
|
||||||
let (old_excerpt, _) = snapshot
|
let (old_excerpt, _) = snapshot
|
||||||
.range_to_buffer_ranges(range.clone())
|
.range_to_buffer_ranges(range.clone())
|
||||||
.pop()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let old_buffer = cx.new_model(|cx| {
|
let old_buffer = cx.new_model(|cx| {
|
||||||
let text = old_excerpt.buffer().as_rope().clone();
|
let text = old_excerpt.buffer().as_rope().clone();
|
||||||
@@ -2872,9 +2875,9 @@ impl CodegenAlternative {
|
|||||||
let language_name = {
|
let language_name = {
|
||||||
let multibuffer = self.buffer.read(cx);
|
let multibuffer = self.buffer.read(cx);
|
||||||
let snapshot = multibuffer.snapshot(cx);
|
let snapshot = multibuffer.snapshot(cx);
|
||||||
let ranges = snapshot.range_to_buffer_ranges(self.range.clone());
|
let mut ranges = snapshot.range_to_buffer_ranges(self.range.clone());
|
||||||
ranges
|
ranges
|
||||||
.first()
|
.next()
|
||||||
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
||||||
.map(|language| language.name())
|
.map(|language| language.name())
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -257,9 +257,10 @@ impl CodegenAlternative {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
let snapshot = buffer.read(cx).snapshot(cx);
|
let snapshot = buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
// TODO: Could be more efficient by using a reverse iterator.
|
||||||
let (old_excerpt, _) = snapshot
|
let (old_excerpt, _) = snapshot
|
||||||
.range_to_buffer_ranges(range.clone())
|
.range_to_buffer_ranges(range.clone())
|
||||||
.pop()
|
.last()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let old_buffer = cx.new_model(|cx| {
|
let old_buffer = cx.new_model(|cx| {
|
||||||
let text = old_excerpt.buffer().as_rope().clone();
|
let text = old_excerpt.buffer().as_rope().clone();
|
||||||
@@ -475,9 +476,9 @@ impl CodegenAlternative {
|
|||||||
let language_name = {
|
let language_name = {
|
||||||
let multibuffer = self.buffer.read(cx);
|
let multibuffer = self.buffer.read(cx);
|
||||||
let snapshot = multibuffer.snapshot(cx);
|
let snapshot = multibuffer.snapshot(cx);
|
||||||
let ranges = snapshot.range_to_buffer_ranges(self.range.clone());
|
let mut ranges = snapshot.range_to_buffer_ranges(self.range.clone());
|
||||||
ranges
|
ranges
|
||||||
.first()
|
.next()
|
||||||
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
||||||
.map(|language| language.name())
|
.map(|language| language.name())
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -294,19 +294,20 @@ impl InlineAssistant {
|
|||||||
let newest_selection = newest_selection.unwrap();
|
let newest_selection = newest_selection.unwrap();
|
||||||
|
|
||||||
let mut codegen_ranges = Vec::new();
|
let mut codegen_ranges = Vec::new();
|
||||||
for (excerpt_id, buffer, buffer_range) in
|
for (excerpt, buffer_range) in
|
||||||
snapshot.excerpts_in_ranges(selections.iter().map(|selection| {
|
snapshot.disjoint_ranges_to_buffer_ranges(selections.iter().map(|selection| {
|
||||||
snapshot.anchor_before(selection.start)..snapshot.anchor_after(selection.end)
|
snapshot.anchor_before(selection.start)..snapshot.anchor_after(selection.end)
|
||||||
}))
|
}))
|
||||||
{
|
{
|
||||||
|
let buffer = excerpt.buffer();
|
||||||
let start = Anchor {
|
let start = Anchor {
|
||||||
buffer_id: Some(buffer.remote_id()),
|
buffer_id: Some(buffer.remote_id()),
|
||||||
excerpt_id,
|
excerpt_id: excerpt.id(),
|
||||||
text_anchor: buffer.anchor_before(buffer_range.start),
|
text_anchor: buffer.anchor_before(buffer_range.start),
|
||||||
};
|
};
|
||||||
let end = Anchor {
|
let end = Anchor {
|
||||||
buffer_id: Some(buffer.remote_id()),
|
buffer_id: Some(buffer.remote_id()),
|
||||||
excerpt_id,
|
excerpt_id: excerpt.id(),
|
||||||
text_anchor: buffer.anchor_after(buffer_range.end),
|
text_anchor: buffer.anchor_after(buffer_range.end),
|
||||||
};
|
};
|
||||||
codegen_ranges.push(start..end);
|
codegen_ranges.push(start..end);
|
||||||
@@ -872,9 +873,9 @@ impl InlineAssistant {
|
|||||||
let language_name = assist.editor.upgrade().and_then(|editor| {
|
let language_name = assist.editor.upgrade().and_then(|editor| {
|
||||||
let multibuffer = editor.read(cx).buffer().read(cx);
|
let multibuffer = editor.read(cx).buffer().read(cx);
|
||||||
let snapshot = multibuffer.snapshot(cx);
|
let snapshot = multibuffer.snapshot(cx);
|
||||||
let ranges = snapshot.range_to_buffer_ranges(assist.range.clone());
|
let mut ranges = snapshot.range_to_buffer_ranges(assist.range.clone());
|
||||||
ranges
|
ranges
|
||||||
.first()
|
.next()
|
||||||
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
.and_then(|(excerpt, _)| excerpt.buffer().language())
|
||||||
.map(|language| language.name())
|
.map(|language| language.name())
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ pub use proposed_changes_editor::{
|
|||||||
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
|
ProposedChangeLocation, ProposedChangesEditor, ProposedChangesEditorToolbar,
|
||||||
};
|
};
|
||||||
use similar::{ChangeTag, TextDiff};
|
use similar::{ChangeTag, TextDiff};
|
||||||
use std::iter::Peekable;
|
use std::iter::{self, Peekable};
|
||||||
use task::{ResolvedTask, TaskTemplate, TaskVariables};
|
use task::{ResolvedTask, TaskTemplate, TaskVariables};
|
||||||
|
|
||||||
use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight};
|
use hover_links::{find_file, HoverLink, HoveredLinkState, InlayHighlight};
|
||||||
@@ -3550,8 +3550,7 @@ impl Editor {
|
|||||||
);
|
);
|
||||||
let multi_buffer_visible_range = multi_buffer_visible_start..multi_buffer_visible_end;
|
let multi_buffer_visible_range = multi_buffer_visible_start..multi_buffer_visible_end;
|
||||||
multi_buffer_snapshot
|
multi_buffer_snapshot
|
||||||
.range_to_buffer_ranges(multi_buffer_visible_range)
|
.disjoint_ranges_to_buffer_ranges(iter::once(multi_buffer_visible_range))
|
||||||
.into_iter()
|
|
||||||
.filter(|(_, excerpt_visible_range)| !excerpt_visible_range.is_empty())
|
.filter(|(_, excerpt_visible_range)| !excerpt_visible_range.is_empty())
|
||||||
.filter_map(|(excerpt, excerpt_visible_range)| {
|
.filter_map(|(excerpt, excerpt_visible_range)| {
|
||||||
let buffer_file = project::File::from_dyn(excerpt.buffer().file())?;
|
let buffer_file = project::File::from_dyn(excerpt.buffer().file())?;
|
||||||
@@ -10498,13 +10497,13 @@ impl Editor {
|
|||||||
} else {
|
} else {
|
||||||
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let mut toggled_buffers = HashSet::default();
|
let mut toggled_buffers = HashSet::default();
|
||||||
for (_, buffer_snapshot, _) in multi_buffer_snapshot.excerpts_in_ranges(
|
for (excerpt, _) in multi_buffer_snapshot.disjoint_ranges_to_buffer_ranges(
|
||||||
self.selections
|
self.selections
|
||||||
.disjoint_anchors()
|
.disjoint_anchors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| selection.range()),
|
.map(|selection| selection.range()),
|
||||||
) {
|
) {
|
||||||
let buffer_id = buffer_snapshot.remote_id();
|
let buffer_id = excerpt.buffer().remote_id();
|
||||||
if toggled_buffers.insert(buffer_id) {
|
if toggled_buffers.insert(buffer_id) {
|
||||||
if self.buffer_folded(buffer_id, cx) {
|
if self.buffer_folded(buffer_id, cx) {
|
||||||
self.unfold_buffer(buffer_id, cx);
|
self.unfold_buffer(buffer_id, cx);
|
||||||
@@ -10584,13 +10583,13 @@ impl Editor {
|
|||||||
} else {
|
} else {
|
||||||
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let mut folded_buffers = HashSet::default();
|
let mut folded_buffers = HashSet::default();
|
||||||
for (_, buffer_snapshot, _) in multi_buffer_snapshot.excerpts_in_ranges(
|
for (excerpt, _) in multi_buffer_snapshot.disjoint_ranges_to_buffer_ranges(
|
||||||
self.selections
|
self.selections
|
||||||
.disjoint_anchors()
|
.disjoint_anchors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| selection.range()),
|
.map(|selection| selection.range()),
|
||||||
) {
|
) {
|
||||||
let buffer_id = buffer_snapshot.remote_id();
|
let buffer_id = excerpt.buffer().remote_id();
|
||||||
if folded_buffers.insert(buffer_id) {
|
if folded_buffers.insert(buffer_id) {
|
||||||
self.fold_buffer(buffer_id, cx);
|
self.fold_buffer(buffer_id, cx);
|
||||||
}
|
}
|
||||||
@@ -10750,13 +10749,13 @@ impl Editor {
|
|||||||
} else {
|
} else {
|
||||||
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
let multi_buffer_snapshot = self.buffer.read(cx).snapshot(cx);
|
||||||
let mut unfolded_buffers = HashSet::default();
|
let mut unfolded_buffers = HashSet::default();
|
||||||
for (_, buffer_snapshot, _) in multi_buffer_snapshot.excerpts_in_ranges(
|
for (excerpt, _) in multi_buffer_snapshot.disjoint_ranges_to_buffer_ranges(
|
||||||
self.selections
|
self.selections
|
||||||
.disjoint_anchors()
|
.disjoint_anchors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|selection| selection.range()),
|
.map(|selection| selection.range()),
|
||||||
) {
|
) {
|
||||||
let buffer_id = buffer_snapshot.remote_id();
|
let buffer_id = excerpt.buffer().remote_id();
|
||||||
if unfolded_buffers.insert(buffer_id) {
|
if unfolded_buffers.insert(buffer_id) {
|
||||||
self.unfold_buffer(buffer_id, cx);
|
self.unfold_buffer(buffer_id, cx);
|
||||||
}
|
}
|
||||||
@@ -11500,36 +11499,36 @@ impl Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_permalink_to_line(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<url::Url>> {
|
fn get_permalink_to_line(&mut self, cx: &mut ViewContext<Self>) -> Task<Result<url::Url>> {
|
||||||
let buffer_and_selection = maybe!({
|
let buffer_and_selection_rows = maybe!({
|
||||||
let selection = self.selections.newest::<Point>(cx);
|
let multi_buffer = self.buffer().read(cx);
|
||||||
|
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
||||||
|
let selection = self.selections.newest_anchor();
|
||||||
let selection_range = selection.range();
|
let selection_range = selection.range();
|
||||||
|
|
||||||
let (buffer, selection) = if let Some(buffer) = self.buffer().read(cx).as_singleton() {
|
let (buffer, selection_rows) = if let Some(buffer) = multi_buffer.as_singleton() {
|
||||||
(buffer, selection_range.start.row..selection_range.end.row)
|
(
|
||||||
|
buffer,
|
||||||
|
selection_range.start.to_point(&multi_buffer_snapshot).row
|
||||||
|
..selection_range.end.to_point(&multi_buffer_snapshot).row,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
let multi_buffer = self.buffer().read(cx);
|
let selection_head = selection.head();
|
||||||
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
let excerpt =
|
||||||
let buffer_ranges = multi_buffer_snapshot.range_to_buffer_ranges(selection_range);
|
multi_buffer_snapshot.excerpt_containing(selection_head..selection_head)?;
|
||||||
|
let range =
|
||||||
let (excerpt, range) = if selection.reversed {
|
excerpt.map_range_to_buffer(selection_range.to_offset(&multi_buffer_snapshot));
|
||||||
buffer_ranges.first()
|
|
||||||
} else {
|
|
||||||
buffer_ranges.last()
|
|
||||||
}?;
|
|
||||||
|
|
||||||
let snapshot = excerpt.buffer();
|
let snapshot = excerpt.buffer();
|
||||||
let selection = text::ToPoint::to_point(&range.start, &snapshot).row
|
|
||||||
..text::ToPoint::to_point(&range.end, &snapshot).row;
|
|
||||||
(
|
(
|
||||||
multi_buffer.buffer(excerpt.buffer_id()).unwrap().clone(),
|
multi_buffer.buffer(excerpt.buffer_id()).unwrap().clone(),
|
||||||
selection,
|
text::ToPoint::to_point(&range.start, &snapshot).row
|
||||||
|
..text::ToPoint::to_point(&range.end, &snapshot).row,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((buffer, selection))
|
Some((buffer, selection_rows))
|
||||||
});
|
});
|
||||||
|
|
||||||
let Some((buffer, selection)) = buffer_and_selection else {
|
let Some((buffer, selection_rows)) = buffer_and_selection_rows else {
|
||||||
return Task::ready(Err(anyhow!("failed to determine buffer and selection")));
|
return Task::ready(Err(anyhow!("failed to determine buffer and selection")));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -11538,7 +11537,7 @@ impl Editor {
|
|||||||
};
|
};
|
||||||
|
|
||||||
project.update(cx, |project, cx| {
|
project.update(cx, |project, cx| {
|
||||||
project.get_permalink_to_line(&buffer, selection, cx)
|
project.get_permalink_to_line(&buffer, selection_rows, cx)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -458,10 +458,7 @@ impl Editor {
|
|||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
let multi_buffer = self.buffer.read(cx);
|
let multi_buffer = self.buffer.read(cx);
|
||||||
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
||||||
let (excerpt, range) = multi_buffer_snapshot
|
let (excerpt, range) = multi_buffer_snapshot.range_to_buffer_ranges(range).next()?;
|
||||||
.range_to_buffer_ranges(range)
|
|
||||||
.into_iter()
|
|
||||||
.next()?;
|
|
||||||
|
|
||||||
multi_buffer
|
multi_buffer
|
||||||
.buffer(excerpt.buffer_id())
|
.buffer(excerpt.buffer_id())
|
||||||
|
|||||||
@@ -1468,10 +1468,11 @@ impl SearchableItem for Editor {
|
|||||||
search_within_ranges
|
search_within_ranges
|
||||||
};
|
};
|
||||||
|
|
||||||
for (excerpt_id, search_buffer, search_range) in
|
for (excerpt, search_range) in
|
||||||
buffer.excerpts_in_ranges(search_within_ranges)
|
buffer.disjoint_ranges_to_buffer_ranges(search_within_ranges)
|
||||||
{
|
{
|
||||||
if !search_range.is_empty() {
|
if !search_range.is_empty() {
|
||||||
|
let search_buffer = excerpt.buffer();
|
||||||
ranges.extend(
|
ranges.extend(
|
||||||
query
|
query
|
||||||
.search(search_buffer, Some(search_range.clone()))
|
.search(search_buffer, Some(search_range.clone()))
|
||||||
@@ -1482,8 +1483,8 @@ impl SearchableItem for Editor {
|
|||||||
.anchor_after(search_range.start + match_range.start);
|
.anchor_after(search_range.start + match_range.start);
|
||||||
let end = search_buffer
|
let end = search_buffer
|
||||||
.anchor_before(search_range.start + match_range.end);
|
.anchor_before(search_range.start + match_range.end);
|
||||||
buffer.anchor_in_excerpt(excerpt_id, start).unwrap()
|
buffer.anchor_in_excerpt(excerpt.id(), start).unwrap()
|
||||||
..buffer.anchor_in_excerpt(excerpt_id, end).unwrap()
|
..buffer.anchor_in_excerpt(excerpt.id(), end).unwrap()
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,12 +132,14 @@ impl SyntaxTreeView {
|
|||||||
.editor
|
.editor
|
||||||
.update(cx, |editor, cx| editor.snapshot(cx));
|
.update(cx, |editor, cx| editor.snapshot(cx));
|
||||||
let (excerpt, buffer, range) = editor_state.editor.update(cx, |editor, cx| {
|
let (excerpt, buffer, range) = editor_state.editor.update(cx, |editor, cx| {
|
||||||
|
let selection = editor.selections.last::<usize>(cx);
|
||||||
let selection_range = editor.selections.last::<usize>(cx).range();
|
let selection_range = editor.selections.last::<usize>(cx).range();
|
||||||
|
let selection_head = selection.head();
|
||||||
let multi_buffer = editor.buffer().read(cx);
|
let multi_buffer = editor.buffer().read(cx);
|
||||||
let (excerpt, range) = snapshot
|
let excerpt = snapshot
|
||||||
.buffer_snapshot
|
.buffer_snapshot
|
||||||
.range_to_buffer_ranges(selection_range)
|
.excerpt_containing(selection_head..selection_head)?;
|
||||||
.pop()?;
|
let range = excerpt.map_range_to_buffer(selection_range);
|
||||||
let buffer = multi_buffer.buffer(excerpt.buffer_id()).unwrap().clone();
|
let buffer = multi_buffer.buffer(excerpt.buffer_id()).unwrap().clone();
|
||||||
Some((excerpt, buffer, range))
|
Some((excerpt, buffer, range))
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
@@ -3894,7 +3894,7 @@ impl MultiBufferSnapshot {
|
|||||||
where
|
where
|
||||||
T: 'a + ToOffset,
|
T: 'a + ToOffset,
|
||||||
{
|
{
|
||||||
let mut ranges = self.range_to_buffer_ranges(range);
|
let mut ranges = self.range_to_buffer_ranges(range).collect::<Vec<_>>();
|
||||||
if reversed {
|
if reversed {
|
||||||
ranges.reverse();
|
ranges.reverse();
|
||||||
}
|
}
|
||||||
@@ -4157,80 +4157,60 @@ impl MultiBufferSnapshot {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range_to_buffer_ranges<T: ToOffset>(
|
/// Returns excerpts overlapping the given range. If range spans multiple excerpts returns one
|
||||||
&self,
|
/// range for each excerpt.
|
||||||
range: Range<T>,
|
|
||||||
) -> Vec<(MultiBufferExcerpt<'_>, Range<usize>)> {
|
|
||||||
let start = range.start.to_offset(self);
|
|
||||||
let end = range.end.to_offset(self);
|
|
||||||
|
|
||||||
let mut result = Vec::new();
|
|
||||||
let mut cursor = self.excerpts.cursor::<(usize, Point)>(&());
|
|
||||||
cursor.seek(&start, Bias::Right, &());
|
|
||||||
if cursor.item().is_none() {
|
|
||||||
cursor.prev(&());
|
|
||||||
}
|
|
||||||
|
|
||||||
while let Some(excerpt) = cursor.item() {
|
|
||||||
if cursor.start().0 > end {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut end_before_newline = cursor.end(&()).0;
|
|
||||||
if excerpt.has_trailing_newline {
|
|
||||||
end_before_newline -= 1;
|
|
||||||
}
|
|
||||||
let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
|
|
||||||
let start = excerpt_start + (cmp::max(start, cursor.start().0) - cursor.start().0);
|
|
||||||
let end = excerpt_start + (cmp::min(end, end_before_newline) - cursor.start().0);
|
|
||||||
result.push((
|
|
||||||
MultiBufferExcerpt::new(&excerpt, *cursor.start()),
|
|
||||||
start..end,
|
|
||||||
));
|
|
||||||
cursor.next(&());
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns excerpts overlapping the given ranges. If range spans multiple excerpts returns one range for each excerpt
|
|
||||||
///
|
///
|
||||||
/// The ranges are specified in the coordinate space of the multibuffer, not the individual excerpted buffers.
|
/// The ranges are specified in the coordinate space of the multibuffer, not the individual excerpted buffers.
|
||||||
/// Each returned excerpt's range is in the coordinate space of its source buffer.
|
/// Each returned excerpt's range is in the coordinate space of its source buffer.
|
||||||
pub fn excerpts_in_ranges(
|
pub fn range_to_buffer_ranges<T: ToOffset>(
|
||||||
&self,
|
&self,
|
||||||
ranges: impl IntoIterator<Item = Range<Anchor>>,
|
range: Range<T>,
|
||||||
) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, Range<usize>)> {
|
) -> impl Iterator<Item = (MultiBufferExcerpt<'_>, Range<usize>)> {
|
||||||
let mut ranges = ranges.into_iter().map(|range| range.to_offset(self));
|
self.disjoint_ranges_to_buffer_ranges(iter::once(range))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns excerpts overlapping the given ranges, which must be disjoint and sorted by start position.
|
||||||
|
/// If range spans multiple excerpts returns one range for each excerpt
|
||||||
|
///
|
||||||
|
/// The ranges are specified in the coordinate space of the multibuffer, not the individual excerpted buffers.
|
||||||
|
/// Each returned excerpt's range is in the coordinate space of its source buffer.
|
||||||
|
pub fn disjoint_ranges_to_buffer_ranges<T: ToOffset>(
|
||||||
|
&self,
|
||||||
|
ranges: impl IntoIterator<Item = Range<T>>,
|
||||||
|
) -> impl Iterator<Item = (MultiBufferExcerpt<'_>, Range<usize>)> {
|
||||||
|
let mut ranges = ranges.into_iter();
|
||||||
let mut cursor = self.excerpts.cursor::<(usize, Point)>(&());
|
let mut cursor = self.excerpts.cursor::<(usize, Point)>(&());
|
||||||
cursor.next(&());
|
cursor.next(&());
|
||||||
let mut current_range = ranges.next();
|
let mut current_range = ranges.next();
|
||||||
iter::from_fn(move || {
|
iter::from_fn(move || {
|
||||||
let range = current_range.clone()?;
|
let range = current_range.as_ref()?;
|
||||||
if range.start >= cursor.end(&()).0 {
|
let start = range.start.to_offset(self);
|
||||||
cursor.seek_forward(&range.start, Bias::Right, &());
|
let end = range.end.to_offset(self);
|
||||||
if range.start == self.len() {
|
if start >= cursor.end(&()).0 {
|
||||||
|
cursor.seek_forward(&start, Bias::Right, &());
|
||||||
|
if start == self.len() {
|
||||||
cursor.prev(&());
|
cursor.prev(&());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let excerpt = cursor.item()?;
|
let excerpt = cursor.item()?;
|
||||||
let range_start_in_excerpt = cmp::max(range.start, cursor.start().0);
|
let range_start_in_excerpt = cmp::max(start, cursor.start().0);
|
||||||
let range_end_in_excerpt = if excerpt.has_trailing_newline {
|
let range_end_in_excerpt = if excerpt.has_trailing_newline {
|
||||||
cmp::min(range.end, cursor.end(&()).0 - 1)
|
cmp::min(end, cursor.end(&()).0 - 1)
|
||||||
} else {
|
} else {
|
||||||
cmp::min(range.end, cursor.end(&()).0)
|
cmp::min(end, cursor.end(&()).0)
|
||||||
};
|
};
|
||||||
let buffer_range = MultiBufferExcerpt::new(excerpt, *cursor.start())
|
let multi_buffer_excerpt = MultiBufferExcerpt::new(excerpt, *cursor.start());
|
||||||
|
let buffer_range = multi_buffer_excerpt
|
||||||
.map_range_to_buffer(range_start_in_excerpt..range_end_in_excerpt);
|
.map_range_to_buffer(range_start_in_excerpt..range_end_in_excerpt);
|
||||||
|
|
||||||
if range.end > cursor.end(&()).0 {
|
if end > cursor.end(&()).0 {
|
||||||
cursor.next(&());
|
cursor.next(&());
|
||||||
} else {
|
} else {
|
||||||
current_range = ranges.next();
|
current_range = ranges.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some((excerpt.id, &excerpt.buffer, buffer_range))
|
Some((multi_buffer_excerpt, buffer_range))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1235,7 +1235,9 @@ fn test_random_multibuffer(cx: &mut AppContext, mut rng: StdRng) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let snapshot = multibuffer.read(cx).snapshot(cx);
|
let snapshot = multibuffer.read(cx).snapshot(cx);
|
||||||
let excerpted_buffer_ranges = snapshot.range_to_buffer_ranges(start_ix..end_ix);
|
let excerpted_buffer_ranges = snapshot
|
||||||
|
.range_to_buffer_ranges(start_ix..end_ix)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
let excerpted_buffers_text = excerpted_buffer_ranges
|
let excerpted_buffers_text = excerpted_buffer_ranges
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(excerpt, buffer_range)| {
|
.map(|(excerpt, buffer_range)| {
|
||||||
@@ -1488,7 +1490,7 @@ fn test_excerpts_in_ranges_no_ranges(cx: &mut AppContext) {
|
|||||||
|
|
||||||
let snapshot = multibuffer.update(cx, |multibuffer, cx| multibuffer.snapshot(cx));
|
let snapshot = multibuffer.update(cx, |multibuffer, cx| multibuffer.snapshot(cx));
|
||||||
|
|
||||||
let mut excerpts = snapshot.excerpts_in_ranges(iter::from_fn(|| None));
|
let mut excerpts = snapshot.disjoint_ranges_to_buffer_ranges::<usize>(iter::from_fn(|| None));
|
||||||
|
|
||||||
assert!(excerpts.next().is_none());
|
assert!(excerpts.next().is_none());
|
||||||
}
|
}
|
||||||
@@ -1587,12 +1589,12 @@ fn test_excerpts_in_ranges_range_inside_the_excerpt(cx: &mut AppContext) {
|
|||||||
)];
|
)];
|
||||||
|
|
||||||
let excerpts = snapshot
|
let excerpts = snapshot
|
||||||
.excerpts_in_ranges(vec![range.clone()].into_iter())
|
.disjoint_ranges_to_buffer_ranges(vec![range.clone()].into_iter())
|
||||||
.map(|(excerpt_id, buffer, actual_range)| {
|
.map(|(excerpt, actual_range)| {
|
||||||
(
|
(
|
||||||
excerpt_id,
|
excerpt.id(),
|
||||||
buffer.remote_id(),
|
excerpt.buffer().remote_id(),
|
||||||
map_range_from_excerpt(&snapshot, excerpt_id, buffer, actual_range),
|
map_range_from_excerpt(&snapshot, excerpt.id(), excerpt.buffer(), actual_range),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
@@ -1652,12 +1654,12 @@ fn test_excerpts_in_ranges_range_crosses_excerpts_boundary(cx: &mut AppContext)
|
|||||||
];
|
];
|
||||||
|
|
||||||
let excerpts = snapshot
|
let excerpts = snapshot
|
||||||
.excerpts_in_ranges(vec![expected_range.clone()].into_iter())
|
.disjoint_ranges_to_buffer_ranges(vec![expected_range.clone()].into_iter())
|
||||||
.map(|(excerpt_id, buffer, actual_range)| {
|
.map(|(excerpt, actual_range)| {
|
||||||
(
|
(
|
||||||
excerpt_id,
|
excerpt.id(),
|
||||||
buffer.remote_id(),
|
excerpt.buffer().remote_id(),
|
||||||
map_range_from_excerpt(&snapshot, excerpt_id, buffer, actual_range),
|
map_range_from_excerpt(&snapshot, excerpt.id(), excerpt.buffer(), actual_range),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
@@ -1728,12 +1730,12 @@ fn test_excerpts_in_ranges_range_encloses_excerpt(cx: &mut AppContext) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let excerpts = snapshot
|
let excerpts = snapshot
|
||||||
.excerpts_in_ranges(vec![expected_range.clone()].into_iter())
|
.disjoint_ranges_to_buffer_ranges(vec![expected_range.clone()].into_iter())
|
||||||
.map(|(excerpt_id, buffer, actual_range)| {
|
.map(|(excerpt, actual_range)| {
|
||||||
(
|
(
|
||||||
excerpt_id,
|
excerpt.id(),
|
||||||
buffer.remote_id(),
|
excerpt.buffer().remote_id(),
|
||||||
map_range_from_excerpt(&snapshot, excerpt_id, buffer, actual_range),
|
map_range_from_excerpt(&snapshot, excerpt.id(), excerpt.buffer(), actual_range),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
@@ -1794,12 +1796,12 @@ fn test_excerpts_in_ranges_multiple_ranges(cx: &mut AppContext) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let excerpts = snapshot
|
let excerpts = snapshot
|
||||||
.excerpts_in_ranges(ranges)
|
.disjoint_ranges_to_buffer_ranges(ranges)
|
||||||
.map(|(excerpt_id, buffer, actual_range)| {
|
.map(|(excerpt, actual_range)| {
|
||||||
(
|
(
|
||||||
excerpt_id,
|
excerpt.id(),
|
||||||
buffer.remote_id(),
|
excerpt.buffer().remote_id(),
|
||||||
map_range_from_excerpt(&snapshot, excerpt_id, buffer, actual_range),
|
map_range_from_excerpt(&snapshot, excerpt.id(), excerpt.buffer(), actual_range),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
@@ -1860,12 +1862,12 @@ fn test_excerpts_in_ranges_range_ends_at_excerpt_end(cx: &mut AppContext) {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let excerpts = snapshot
|
let excerpts = snapshot
|
||||||
.excerpts_in_ranges(ranges.into_iter())
|
.disjoint_ranges_to_buffer_ranges(ranges.into_iter())
|
||||||
.map(|(excerpt_id, buffer, actual_range)| {
|
.map(|(excerpt, actual_range)| {
|
||||||
(
|
(
|
||||||
excerpt_id,
|
excerpt.id(),
|
||||||
buffer.remote_id(),
|
excerpt.buffer().remote_id(),
|
||||||
map_range_from_excerpt(&snapshot, excerpt_id, buffer, actual_range),
|
map_range_from_excerpt(&snapshot, excerpt.id(), excerpt.buffer(), actual_range),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect_vec();
|
.collect_vec();
|
||||||
|
|||||||
Reference in New Issue
Block a user