Extract an ExcerptRange containing a context field in multi_buffer

This lays the groundwork for adding an optional `primary` field that can
be supplied to provide the "jump to" feature.
This commit is contained in:
Antonio Scandurra 2022-06-08 12:13:04 +02:00
parent d56cc1a5c1
commit ffb75b0f02
6 changed files with 231 additions and 100 deletions

View file

@ -5,7 +5,8 @@ use collections::{BTreeMap, HashSet};
use editor::{ use editor::{
diagnostic_block_renderer, diagnostic_block_renderer,
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock}, display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset, highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, ExcerptRange, MultiBuffer,
ToOffset,
}; };
use gpui::{ use gpui::{
actions, elements::*, fonts::TextStyle, impl_internal_actions, platform::CursorStyle, actions, elements::*, fonts::TextStyle, impl_internal_actions, platform::CursorStyle,
@ -348,7 +349,9 @@ impl ProjectDiagnosticsEditor {
.insert_excerpts_after( .insert_excerpts_after(
&prev_excerpt_id, &prev_excerpt_id,
buffer.clone(), buffer.clone(),
[excerpt_start..excerpt_end], [ExcerptRange {
context: excerpt_start..excerpt_end,
}],
excerpts_cx, excerpts_cx,
) )
.pop() .pop()

View file

@ -2,7 +2,7 @@ use super::{
wrap_map::{self, WrapEdit, WrapPoint, WrapSnapshot}, wrap_map::{self, WrapEdit, WrapPoint, WrapSnapshot},
TextHighlights, TextHighlights,
}; };
use crate::{Anchor, ToPoint as _}; use crate::{Anchor, ExcerptRange, ToPoint as _};
use collections::{Bound, HashMap, HashSet}; use collections::{Bound, HashMap, HashSet};
use gpui::{ElementBox, RenderContext}; use gpui::{ElementBox, RenderContext};
use language::{BufferSnapshot, Chunk, Patch}; use language::{BufferSnapshot, Chunk, Patch};
@ -98,7 +98,7 @@ pub enum TransformBlock {
Custom(Arc<Block>), Custom(Arc<Block>),
ExcerptHeader { ExcerptHeader {
buffer: BufferSnapshot, buffer: BufferSnapshot,
range: Range<text::Anchor>, range: ExcerptRange<text::Anchor>,
height: u8, height: u8,
starts_new_buffer: bool, starts_new_buffer: bool,
}, },

View file

@ -36,7 +36,8 @@ use language::{
}; };
use multi_buffer::MultiBufferChunks; use multi_buffer::MultiBufferChunks;
pub use multi_buffer::{ pub use multi_buffer::{
Anchor, AnchorRangeExt, ExcerptId, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint, Anchor, AnchorRangeExt, ExcerptId, ExcerptRange, MultiBuffer, MultiBufferSnapshot, ToOffset,
ToPoint,
}; };
use ordered_float::OrderedFloat; use ordered_float::OrderedFloat;
use project::{HoverBlock, Project, ProjectTransaction}; use project::{HoverBlock, Project, ProjectTransaction};
@ -2833,11 +2834,11 @@ impl Editor {
let start = highlight let start = highlight
.range .range
.start .start
.max(&excerpt_range.start, cursor_buffer_snapshot); .max(&excerpt_range.context.start, cursor_buffer_snapshot);
let end = highlight let end = highlight
.range .range
.end .end
.min(&excerpt_range.end, cursor_buffer_snapshot); .min(&excerpt_range.context.end, cursor_buffer_snapshot);
if start.cmp(&end, cursor_buffer_snapshot).is_ge() { if start.cmp(&end, cursor_buffer_snapshot).is_ge() {
continue; continue;
} }
@ -7718,12 +7719,16 @@ mod tests {
let mut multibuffer = MultiBuffer::new(0); let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts( multibuffer.push_excerpts(
toml_buffer.clone(), toml_buffer.clone(),
[Point::new(0, 0)..Point::new(2, 0)], [ExcerptRange {
context: Point::new(0, 0)..Point::new(2, 0),
}],
cx, cx,
); );
multibuffer.push_excerpts( multibuffer.push_excerpts(
rust_buffer.clone(), rust_buffer.clone(),
[Point::new(0, 0)..Point::new(1, 0)], [ExcerptRange {
context: Point::new(0, 0)..Point::new(1, 0),
}],
cx, cx,
); );
multibuffer multibuffer
@ -9595,8 +9600,12 @@ mod tests {
multibuffer.push_excerpts( multibuffer.push_excerpts(
buffer.clone(), buffer.clone(),
[ [
Point::new(0, 0)..Point::new(0, 4), ExcerptRange {
Point::new(1, 0)..Point::new(1, 4), context: Point::new(0, 0)..Point::new(0, 4),
},
ExcerptRange {
context: Point::new(1, 0)..Point::new(1, 4),
},
], ],
cx, cx,
); );
@ -9634,6 +9643,9 @@ mod tests {
[aaaa [aaaa
(bbbb] (bbbb]
cccc)"}); cccc)"});
let excerpt_ranges = excerpt_ranges
.into_iter()
.map(|context| ExcerptRange { context });
let buffer = cx.add_model(|cx| Buffer::new(0, initial_text, cx)); let buffer = cx.add_model(|cx| Buffer::new(0, initial_text, cx));
let multibuffer = cx.add_model(|cx| { let multibuffer = cx.add_model(|cx| {
let mut multibuffer = MultiBuffer::new(0); let mut multibuffer = MultiBuffer::new(0);
@ -9687,8 +9699,12 @@ mod tests {
.push_excerpts( .push_excerpts(
buffer.clone(), buffer.clone(),
[ [
Point::new(0, 0)..Point::new(1, 4), ExcerptRange {
Point::new(1, 0)..Point::new(2, 4), context: Point::new(0, 0)..Point::new(1, 4),
},
ExcerptRange {
context: Point::new(1, 0)..Point::new(2, 4),
},
], ],
cx, cx,
) )
@ -9771,8 +9787,12 @@ mod tests {
.push_excerpts( .push_excerpts(
buffer.clone(), buffer.clone(),
[ [
Point::new(0, 0)..Point::new(1, 4), ExcerptRange {
Point::new(1, 0)..Point::new(2, 4), context: Point::new(0, 0)..Point::new(1, 4),
},
ExcerptRange {
context: Point::new(1, 0)..Point::new(2, 4),
},
], ],
cx, cx,
) )

View file

@ -272,7 +272,7 @@ pub fn surrounding_word(map: &DisplaySnapshot, position: DisplayPoint) -> Range<
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::{test::marked_display_snapshot, Buffer, DisplayMap, MultiBuffer}; use crate::{test::marked_display_snapshot, Buffer, DisplayMap, ExcerptRange, MultiBuffer};
use language::Point; use language::Point;
use settings::Settings; use settings::Settings;
@ -494,8 +494,12 @@ mod tests {
multibuffer.push_excerpts( multibuffer.push_excerpts(
buffer.clone(), buffer.clone(),
[ [
Point::new(0, 0)..Point::new(1, 4), ExcerptRange {
Point::new(2, 0)..Point::new(3, 2), context: Point::new(0, 0)..Point::new(1, 4),
},
ExcerptRange {
context: Point::new(2, 0)..Point::new(3, 2),
},
], ],
cx, cx,
); );

View file

@ -104,7 +104,7 @@ pub struct ExcerptBoundary {
pub id: ExcerptId, pub id: ExcerptId,
pub row: u32, pub row: u32,
pub buffer: BufferSnapshot, pub buffer: BufferSnapshot,
pub range: Range<text::Anchor>, pub range: ExcerptRange<text::Anchor>,
pub starts_new_buffer: bool, pub starts_new_buffer: bool,
} }
@ -113,12 +113,17 @@ struct Excerpt {
id: ExcerptId, id: ExcerptId,
buffer_id: usize, buffer_id: usize,
buffer: BufferSnapshot, buffer: BufferSnapshot,
range: Range<text::Anchor>, range: ExcerptRange<text::Anchor>,
max_buffer_row: u32, max_buffer_row: u32,
text_summary: TextSummary, text_summary: TextSummary,
has_trailing_newline: bool, has_trailing_newline: bool,
} }
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ExcerptRange<T> {
pub context: Range<T>,
}
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct ExcerptSummary { struct ExcerptSummary {
excerpt_id: ExcerptId, excerpt_id: ExcerptId,
@ -215,7 +220,13 @@ impl MultiBuffer {
pub fn singleton(buffer: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self { pub fn singleton(buffer: ModelHandle<Buffer>, cx: &mut ModelContext<Self>) -> Self {
let mut this = Self::new(buffer.read(cx).replica_id()); let mut this = Self::new(buffer.read(cx).replica_id());
this.singleton = true; this.singleton = true;
this.push_excerpts(buffer, [text::Anchor::MIN..text::Anchor::MAX], cx); this.push_excerpts(
buffer,
[ExcerptRange {
context: text::Anchor::MIN..text::Anchor::MAX,
}],
cx,
);
this.snapshot.borrow_mut().singleton = true; this.snapshot.borrow_mut().singleton = true;
this this
} }
@ -343,8 +354,12 @@ impl MultiBuffer {
} }
let start_excerpt = cursor.item().expect("start offset out of bounds"); let start_excerpt = cursor.item().expect("start offset out of bounds");
let start_overshoot = range.start - cursor.start(); let start_overshoot = range.start - cursor.start();
let buffer_start = let buffer_start = start_excerpt
start_excerpt.range.start.to_offset(&start_excerpt.buffer) + start_overshoot; .range
.context
.start
.to_offset(&start_excerpt.buffer)
+ start_overshoot;
cursor.seek(&range.end, Bias::Right, &()); cursor.seek(&range.end, Bias::Right, &());
if cursor.item().is_none() && range.end == *cursor.start() { if cursor.item().is_none() && range.end == *cursor.start() {
@ -352,7 +367,12 @@ impl MultiBuffer {
} }
let end_excerpt = cursor.item().expect("end offset out of bounds"); let end_excerpt = cursor.item().expect("end offset out of bounds");
let end_overshoot = range.end - cursor.start(); let end_overshoot = range.end - cursor.start();
let buffer_end = end_excerpt.range.start.to_offset(&end_excerpt.buffer) + end_overshoot; let buffer_end = end_excerpt
.range
.context
.start
.to_offset(&end_excerpt.buffer)
+ end_overshoot;
if start_excerpt.id == end_excerpt.id { if start_excerpt.id == end_excerpt.id {
buffer_edits buffer_edits
@ -360,10 +380,18 @@ impl MultiBuffer {
.or_insert(Vec::new()) .or_insert(Vec::new())
.push((buffer_start..buffer_end, new_text, true)); .push((buffer_start..buffer_end, new_text, true));
} else { } else {
let start_excerpt_range = let start_excerpt_range = buffer_start
buffer_start..start_excerpt.range.end.to_offset(&start_excerpt.buffer); ..start_excerpt
let end_excerpt_range = .range
end_excerpt.range.start.to_offset(&end_excerpt.buffer)..buffer_end; .context
.end
.to_offset(&start_excerpt.buffer);
let end_excerpt_range = end_excerpt
.range
.context
.start
.to_offset(&end_excerpt.buffer)
..buffer_end;
buffer_edits buffer_edits
.entry(start_excerpt.buffer_id) .entry(start_excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
@ -383,7 +411,7 @@ impl MultiBuffer {
.entry(excerpt.buffer_id) .entry(excerpt.buffer_id)
.or_insert(Vec::new()) .or_insert(Vec::new())
.push(( .push((
excerpt.range.to_offset(&excerpt.buffer), excerpt.range.context.to_offset(&excerpt.buffer),
new_text.clone(), new_text.clone(),
false, false,
)); ));
@ -523,8 +551,8 @@ impl MultiBuffer {
break; break;
} }
let mut start = excerpt.range.start.clone(); let mut start = excerpt.range.context.start.clone();
let mut end = excerpt.range.end.clone(); let mut end = excerpt.range.context.end.clone();
if excerpt.id == selection.start.excerpt_id { if excerpt.id == selection.start.excerpt_id {
start = selection.start.text_anchor.clone(); start = selection.start.text_anchor.clone();
} }
@ -644,7 +672,7 @@ impl MultiBuffer {
pub fn push_excerpts<O>( pub fn push_excerpts<O>(
&mut self, &mut self,
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
ranges: impl IntoIterator<Item = Range<O>>, ranges: impl IntoIterator<Item = ExcerptRange<O>>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Vec<ExcerptId> ) -> Vec<ExcerptId>
where where
@ -692,7 +720,9 @@ impl MultiBuffer {
} }
} }
excerpt_ranges.push(excerpt_start..excerpt_end); excerpt_ranges.push(ExcerptRange {
context: excerpt_start..excerpt_end,
});
range_counts.push(ranges_in_excerpt); range_counts.push(ranges_in_excerpt);
} }
@ -722,7 +752,7 @@ impl MultiBuffer {
&mut self, &mut self,
prev_excerpt_id: &ExcerptId, prev_excerpt_id: &ExcerptId,
buffer: ModelHandle<Buffer>, buffer: ModelHandle<Buffer>,
ranges: impl IntoIterator<Item = Range<O>>, ranges: impl IntoIterator<Item = ExcerptRange<O>>,
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Vec<ExcerptId> ) -> Vec<ExcerptId>
where where
@ -786,8 +816,10 @@ impl MultiBuffer {
if let Err(ix) = buffer_state.excerpts.binary_search(&id) { if let Err(ix) = buffer_state.excerpts.binary_search(&id) {
buffer_state.excerpts.insert(ix, id.clone()); buffer_state.excerpts.insert(ix, id.clone());
} }
let range = buffer_snapshot.anchor_before(&range.start) let range = ExcerptRange {
..buffer_snapshot.anchor_after(&range.end); context: buffer_snapshot.anchor_before(&range.context.start)
..buffer_snapshot.anchor_after(&range.context.end),
};
let excerpt = Excerpt::new( let excerpt = Excerpt::new(
id.clone(), id.clone(),
buffer_id, buffer_id,
@ -846,7 +878,7 @@ impl MultiBuffer {
&self, &self,
buffer: &ModelHandle<Buffer>, buffer: &ModelHandle<Buffer>,
cx: &AppContext, cx: &AppContext,
) -> Vec<(ExcerptId, Range<text::Anchor>)> { ) -> Vec<(ExcerptId, ExcerptRange<text::Anchor>)> {
let mut excerpts = Vec::new(); let mut excerpts = Vec::new();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
@ -894,7 +926,7 @@ impl MultiBuffer {
.unwrap() .unwrap()
.buffer .buffer
.clone(), .clone(),
excerpt.range.clone(), excerpt.range.context.clone(),
) )
}) })
} }
@ -914,7 +946,7 @@ impl MultiBuffer {
} }
cursor.item().map(|excerpt| { cursor.item().map(|excerpt| {
let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let buffer_point = excerpt_start + offset - *cursor.start(); let buffer_point = excerpt_start + offset - *cursor.start();
let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone(); let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone();
@ -943,7 +975,7 @@ impl MultiBuffer {
if excerpt.has_trailing_newline { if excerpt.has_trailing_newline {
end_before_newline -= 1; end_before_newline -= 1;
} }
let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let start = excerpt_start + (cmp::max(start, *cursor.start()) - *cursor.start()); let start = excerpt_start + (cmp::max(start, *cursor.start()) - *cursor.start());
let end = excerpt_start + (cmp::min(end, end_before_newline) - *cursor.start()); let end = excerpt_start + (cmp::min(end, end_before_newline) - *cursor.start());
let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone(); let buffer = self.buffers.borrow()[&excerpt.buffer_id].buffer.clone();
@ -1234,7 +1266,7 @@ impl MultiBuffer {
buffer buffer
.edits_since_in_range::<usize>( .edits_since_in_range::<usize>(
old_excerpt.buffer.version(), old_excerpt.buffer.version(),
old_excerpt.range.clone(), old_excerpt.range.context.clone(),
) )
.map(|mut edit| { .map(|mut edit| {
let excerpt_old_start = cursor.start().1; let excerpt_old_start = cursor.start().1;
@ -1384,7 +1416,9 @@ impl MultiBuffer {
let end_ix = let end_ix =
buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right); buffer.clip_offset(rng.gen_range(0..=buffer.len()), Bias::Right);
let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left); let start_ix = buffer.clip_offset(rng.gen_range(0..=end_ix), Bias::Left);
start_ix..end_ix ExcerptRange {
context: start_ix..end_ix,
}
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
log::info!( log::info!(
@ -1393,7 +1427,7 @@ impl MultiBuffer {
ranges, ranges,
ranges ranges
.iter() .iter()
.map(|range| &buffer_text[range.clone()]) .map(|range| &buffer_text[range.context.clone()])
.collect::<Vec<_>>() .collect::<Vec<_>>()
); );
@ -1465,7 +1499,7 @@ impl MultiBufferSnapshot {
cursor.seek(&offset, Bias::Left, &()); cursor.seek(&offset, Bias::Left, &());
let mut excerpt_chunks = cursor.item().map(|excerpt| { let mut excerpt_chunks = cursor.item().map(|excerpt| {
let end_before_footer = cursor.start() + excerpt.text_summary.bytes; let end_before_footer = cursor.start() + excerpt.text_summary.bytes;
let start = excerpt.range.start.to_offset(&excerpt.buffer); let start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let end = start + (cmp::min(offset, end_before_footer) - cursor.start()); let end = start + (cmp::min(offset, end_before_footer) - cursor.start());
excerpt.buffer.reversed_chunks_in_range(start..end) excerpt.buffer.reversed_chunks_in_range(start..end)
}); });
@ -1476,7 +1510,7 @@ impl MultiBufferSnapshot {
excerpt_chunks = Some( excerpt_chunks = Some(
excerpt excerpt
.buffer .buffer
.reversed_chunks_in_range(excerpt.range.clone()), .reversed_chunks_in_range(excerpt.range.context.clone()),
); );
} }
@ -1581,7 +1615,7 @@ impl MultiBufferSnapshot {
let mut cursor = self.excerpts.cursor::<usize>(); let mut cursor = self.excerpts.cursor::<usize>();
cursor.seek(&offset, Bias::Right, &()); cursor.seek(&offset, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let buffer_offset = excerpt let buffer_offset = excerpt
.buffer .buffer
.clip_offset(excerpt_start + (offset - cursor.start()), bias); .clip_offset(excerpt_start + (offset - cursor.start()), bias);
@ -1600,7 +1634,7 @@ impl MultiBufferSnapshot {
let mut cursor = self.excerpts.cursor::<Point>(); let mut cursor = self.excerpts.cursor::<Point>();
cursor.seek(&point, Bias::Right, &()); cursor.seek(&point, Bias::Right, &());
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer);
let buffer_point = excerpt let buffer_point = excerpt
.buffer .buffer
.clip_point(excerpt_start + (point - cursor.start()), bias); .clip_point(excerpt_start + (point - cursor.start()), bias);
@ -1621,7 +1655,7 @@ impl MultiBufferSnapshot {
let overshoot = if let Some(excerpt) = cursor.item() { let overshoot = if let Some(excerpt) = cursor.item() {
let excerpt_start = excerpt let excerpt_start = excerpt
.buffer .buffer
.offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer)); .offset_to_point_utf16(excerpt.range.context.start.to_offset(&excerpt.buffer));
let buffer_point = excerpt let buffer_point = excerpt
.buffer .buffer
.clip_point_utf16(excerpt_start + (point - cursor.start()), bias); .clip_point_utf16(excerpt_start + (point - cursor.start()), bias);
@ -1690,8 +1724,8 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
let overshoot = offset - start_offset; let overshoot = offset - start_offset;
let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer);
let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer);
let buffer_point = excerpt let buffer_point = excerpt
.buffer .buffer
.offset_to_point(excerpt_start_offset + overshoot); .offset_to_point(excerpt_start_offset + overshoot);
@ -1711,8 +1745,8 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
let overshoot = offset - start_offset; let overshoot = offset - start_offset;
let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer);
let excerpt_start_point = excerpt.range.start.to_point_utf16(&excerpt.buffer); let excerpt_start_point = excerpt.range.context.start.to_point_utf16(&excerpt.buffer);
let buffer_point = excerpt let buffer_point = excerpt
.buffer .buffer
.offset_to_point_utf16(excerpt_start_offset + overshoot); .offset_to_point_utf16(excerpt_start_offset + overshoot);
@ -1732,8 +1766,9 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_offset, start_point) = cursor.start(); let (start_offset, start_point) = cursor.start();
let overshoot = point - start_offset; let overshoot = point - start_offset;
let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer);
let excerpt_start_point_utf16 = excerpt.range.start.to_point_utf16(&excerpt.buffer); let excerpt_start_point_utf16 =
excerpt.range.context.start.to_point_utf16(&excerpt.buffer);
let buffer_point = excerpt let buffer_point = excerpt
.buffer .buffer
.point_to_point_utf16(excerpt_start_point + overshoot); .point_to_point_utf16(excerpt_start_point + overshoot);
@ -1753,8 +1788,8 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_point, start_offset) = cursor.start(); let (start_point, start_offset) = cursor.start();
let overshoot = point - start_point; let overshoot = point - start_point;
let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer);
let excerpt_start_point = excerpt.range.start.to_point(&excerpt.buffer); let excerpt_start_point = excerpt.range.context.start.to_point(&excerpt.buffer);
let buffer_offset = excerpt let buffer_offset = excerpt
.buffer .buffer
.point_to_offset(excerpt_start_point + overshoot); .point_to_offset(excerpt_start_point + overshoot);
@ -1774,10 +1809,10 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let (start_point, start_offset) = cursor.start(); let (start_point, start_offset) = cursor.start();
let overshoot = point - start_point; let overshoot = point - start_point;
let excerpt_start_offset = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start_offset = excerpt.range.context.start.to_offset(&excerpt.buffer);
let excerpt_start_point = excerpt let excerpt_start_point = excerpt
.buffer .buffer
.offset_to_point_utf16(excerpt.range.start.to_offset(&excerpt.buffer)); .offset_to_point_utf16(excerpt.range.context.start.to_offset(&excerpt.buffer));
let buffer_offset = excerpt let buffer_offset = excerpt
.buffer .buffer
.point_utf16_to_offset(excerpt_start_point + overshoot); .point_utf16_to_offset(excerpt_start_point + overshoot);
@ -1811,8 +1846,8 @@ impl MultiBufferSnapshot {
cursor.seek(&Point::new(row, 0), Bias::Right, &()); cursor.seek(&Point::new(row, 0), Bias::Right, &());
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let overshoot = row - cursor.start().row; let overshoot = row - cursor.start().row;
let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer);
let excerpt_end = excerpt.range.end.to_point(&excerpt.buffer); let excerpt_end = excerpt.range.context.end.to_point(&excerpt.buffer);
let buffer_row = excerpt_start.row + overshoot; let buffer_row = excerpt_start.row + overshoot;
let line_start = Point::new(buffer_row, 0); let line_start = Point::new(buffer_row, 0);
let line_end = Point::new(buffer_row, excerpt.buffer.line_len(buffer_row)); let line_end = Point::new(buffer_row, excerpt.buffer.line_len(buffer_row));
@ -1847,7 +1882,7 @@ impl MultiBufferSnapshot {
end_before_newline -= 1; end_before_newline -= 1;
} }
let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let start_in_excerpt = excerpt_start + (range.start - cursor.start()); let start_in_excerpt = excerpt_start + (range.start - cursor.start());
let end_in_excerpt = let end_in_excerpt =
excerpt_start + (cmp::min(end_before_newline, range.end) - cursor.start()); excerpt_start + (cmp::min(end_before_newline, range.end) - cursor.start());
@ -1881,7 +1916,7 @@ impl MultiBufferSnapshot {
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
range.end = cmp::max(*cursor.start(), range.end); range.end = cmp::max(*cursor.start(), range.end);
let excerpt_start = excerpt.range.start.to_offset(&excerpt.buffer); let excerpt_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let end_in_excerpt = excerpt_start + (range.end - cursor.start()); let end_in_excerpt = excerpt_start + (range.end - cursor.start());
summary.add_assign( summary.add_assign(
&excerpt &excerpt
@ -1907,8 +1942,9 @@ impl MultiBufferSnapshot {
let mut position = D::from_text_summary(&cursor.start().text); let mut position = D::from_text_summary(&cursor.start().text);
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
if excerpt.id == anchor.excerpt_id { if excerpt.id == anchor.excerpt_id {
let excerpt_buffer_start = excerpt.range.start.summary::<D>(&excerpt.buffer); let excerpt_buffer_start =
let excerpt_buffer_end = excerpt.range.end.summary::<D>(&excerpt.buffer); excerpt.range.context.start.summary::<D>(&excerpt.buffer);
let excerpt_buffer_end = excerpt.range.context.end.summary::<D>(&excerpt.buffer);
let buffer_position = cmp::min( let buffer_position = cmp::min(
excerpt_buffer_end, excerpt_buffer_end,
anchor.text_anchor.summary::<D>(&excerpt.buffer), anchor.text_anchor.summary::<D>(&excerpt.buffer),
@ -1954,8 +1990,10 @@ impl MultiBufferSnapshot {
let position = D::from_text_summary(&cursor.start().text); let position = D::from_text_summary(&cursor.start().text);
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
if excerpt.id == *excerpt_id { if excerpt.id == *excerpt_id {
let excerpt_buffer_start = excerpt.range.start.summary::<D>(&excerpt.buffer); let excerpt_buffer_start =
let excerpt_buffer_end = excerpt.range.end.summary::<D>(&excerpt.buffer); excerpt.range.context.start.summary::<D>(&excerpt.buffer);
let excerpt_buffer_end =
excerpt.range.context.end.summary::<D>(&excerpt.buffer);
summaries.extend( summaries.extend(
excerpt excerpt
.buffer .buffer
@ -2036,10 +2074,14 @@ impl MultiBufferSnapshot {
anchor = if let Some(excerpt) = next_excerpt { anchor = if let Some(excerpt) = next_excerpt {
let mut text_anchor = excerpt let mut text_anchor = excerpt
.range .range
.context
.start .start
.bias(anchor.text_anchor.bias, &excerpt.buffer); .bias(anchor.text_anchor.bias, &excerpt.buffer);
if text_anchor.cmp(&excerpt.range.end, &excerpt.buffer).is_gt() { if text_anchor
text_anchor = excerpt.range.end.clone(); .cmp(&excerpt.range.context.end, &excerpt.buffer)
.is_gt()
{
text_anchor = excerpt.range.context.end.clone();
} }
Anchor { Anchor {
buffer_id: Some(excerpt.buffer_id), buffer_id: Some(excerpt.buffer_id),
@ -2049,13 +2091,14 @@ impl MultiBufferSnapshot {
} else if let Some(excerpt) = prev_excerpt { } else if let Some(excerpt) = prev_excerpt {
let mut text_anchor = excerpt let mut text_anchor = excerpt
.range .range
.context
.end .end
.bias(anchor.text_anchor.bias, &excerpt.buffer); .bias(anchor.text_anchor.bias, &excerpt.buffer);
if text_anchor if text_anchor
.cmp(&excerpt.range.start, &excerpt.buffer) .cmp(&excerpt.range.context.start, &excerpt.buffer)
.is_lt() .is_lt()
{ {
text_anchor = excerpt.range.start.clone(); text_anchor = excerpt.range.context.start.clone();
} }
Anchor { Anchor {
buffer_id: Some(excerpt.buffer_id), buffer_id: Some(excerpt.buffer_id),
@ -2106,7 +2149,7 @@ impl MultiBufferSnapshot {
bias = Bias::Right; bias = Bias::Right;
} }
let buffer_start = excerpt.range.start.to_offset(&excerpt.buffer); let buffer_start = excerpt.range.context.start.to_offset(&excerpt.buffer);
let text_anchor = let text_anchor =
excerpt.clip_anchor(excerpt.buffer.anchor_at(buffer_start + overshoot, bias)); excerpt.clip_anchor(excerpt.buffer.anchor_at(buffer_start + overshoot, bias));
Anchor { Anchor {
@ -2239,8 +2282,11 @@ impl MultiBufferSnapshot {
return None; return None;
} }
let excerpt_buffer_start = let excerpt_buffer_start = start_excerpt
start_excerpt.range.start.to_offset(&start_excerpt.buffer); .range
.context
.start
.to_offset(&start_excerpt.buffer);
let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes; let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes;
let start_in_buffer = let start_in_buffer =
@ -2340,8 +2386,11 @@ impl MultiBufferSnapshot {
return None; return None;
} }
let excerpt_buffer_start = let excerpt_buffer_start = start_excerpt
start_excerpt.range.start.to_offset(&start_excerpt.buffer); .range
.context
.start
.to_offset(&start_excerpt.buffer);
let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes; let excerpt_buffer_end = excerpt_buffer_start + start_excerpt.text_summary.bytes;
let start_in_buffer = let start_in_buffer =
@ -2427,7 +2476,8 @@ impl MultiBufferSnapshot {
cursor cursor
.take_while(move |excerpt| excerpt.id <= range.end.excerpt_id) .take_while(move |excerpt| excerpt.id <= range.end.excerpt_id)
.flat_map(move |excerpt| { .flat_map(move |excerpt| {
let mut query_range = excerpt.range.start.clone()..excerpt.range.end.clone(); let mut query_range =
excerpt.range.context.start.clone()..excerpt.range.context.end.clone();
if excerpt.id == range.start.excerpt_id { if excerpt.id == range.start.excerpt_id {
query_range.start = range.start.text_anchor.clone(); query_range.start = range.start.text_anchor.clone();
} }
@ -2619,13 +2669,14 @@ impl Excerpt {
id: ExcerptId, id: ExcerptId,
buffer_id: usize, buffer_id: usize,
buffer: BufferSnapshot, buffer: BufferSnapshot,
range: Range<text::Anchor>, range: ExcerptRange<text::Anchor>,
has_trailing_newline: bool, has_trailing_newline: bool,
) -> Self { ) -> Self {
Excerpt { Excerpt {
id, id,
max_buffer_row: range.end.to_point(&buffer).row, max_buffer_row: range.context.end.to_point(&buffer).row,
text_summary: buffer.text_summary_for_range::<TextSummary, _>(range.to_offset(&buffer)), text_summary: buffer
.text_summary_for_range::<TextSummary, _>(range.context.to_offset(&buffer)),
buffer_id, buffer_id,
buffer, buffer,
range, range,
@ -2638,7 +2689,7 @@ impl Excerpt {
range: Range<usize>, range: Range<usize>,
language_aware: bool, language_aware: bool,
) -> ExcerptChunks<'a> { ) -> ExcerptChunks<'a> {
let content_start = self.range.start.to_offset(&self.buffer); let content_start = self.range.context.start.to_offset(&self.buffer);
let chunks_start = content_start + range.start; let chunks_start = content_start + range.start;
let chunks_end = content_start + cmp::min(range.end, self.text_summary.bytes); let chunks_end = content_start + cmp::min(range.end, self.text_summary.bytes);
@ -2660,7 +2711,7 @@ impl Excerpt {
} }
fn bytes_in_range(&self, range: Range<usize>) -> ExcerptBytes { fn bytes_in_range(&self, range: Range<usize>) -> ExcerptBytes {
let content_start = self.range.start.to_offset(&self.buffer); let content_start = self.range.context.start.to_offset(&self.buffer);
let bytes_start = content_start + range.start; let bytes_start = content_start + range.start;
let bytes_end = content_start + cmp::min(range.end, self.text_summary.bytes); let bytes_end = content_start + cmp::min(range.end, self.text_summary.bytes);
let footer_height = if self.has_trailing_newline let footer_height = if self.has_trailing_newline
@ -2680,10 +2731,16 @@ impl Excerpt {
} }
fn clip_anchor(&self, text_anchor: text::Anchor) -> text::Anchor { fn clip_anchor(&self, text_anchor: text::Anchor) -> text::Anchor {
if text_anchor.cmp(&self.range.start, &self.buffer).is_lt() { if text_anchor
self.range.start.clone() .cmp(&self.range.context.start, &self.buffer)
} else if text_anchor.cmp(&self.range.end, &self.buffer).is_gt() { .is_lt()
self.range.end.clone() {
self.range.context.start.clone()
} else if text_anchor
.cmp(&self.range.context.end, &self.buffer)
.is_gt()
{
self.range.context.end.clone()
} else { } else {
text_anchor text_anchor
} }
@ -2693,11 +2750,13 @@ impl Excerpt {
Some(self.buffer_id) == anchor.buffer_id Some(self.buffer_id) == anchor.buffer_id
&& self && self
.range .range
.context
.start .start
.cmp(&anchor.text_anchor, &self.buffer) .cmp(&anchor.text_anchor, &self.buffer)
.is_le() .is_le()
&& self && self
.range .range
.context
.end .end
.cmp(&anchor.text_anchor, &self.buffer) .cmp(&anchor.text_anchor, &self.buffer)
.is_ge() .is_ge()
@ -2802,7 +2861,7 @@ impl<'a> MultiBufferRows<'a> {
if let Some(excerpt) = self.excerpts.item() { if let Some(excerpt) = self.excerpts.item() {
let overshoot = row - self.excerpts.start().row; let overshoot = row - self.excerpts.start().row;
let excerpt_start = excerpt.range.start.to_point(&excerpt.buffer).row; let excerpt_start = excerpt.range.context.start.to_point(&excerpt.buffer).row;
self.buffer_row_range.start = excerpt_start + overshoot; self.buffer_row_range.start = excerpt_start + overshoot;
self.buffer_row_range.end = excerpt_start + excerpt.text_summary.lines.row + 1; self.buffer_row_range.end = excerpt_start + excerpt.text_summary.lines.row + 1;
} }
@ -2822,7 +2881,7 @@ impl<'a> Iterator for MultiBufferRows<'a> {
self.excerpts.item()?; self.excerpts.item()?;
self.excerpts.next(&()); self.excerpts.next(&());
let excerpt = self.excerpts.item()?; let excerpt = self.excerpts.item()?;
self.buffer_row_range.start = excerpt.range.start.to_point(&excerpt.buffer).row; self.buffer_row_range.start = excerpt.range.context.start.to_point(&excerpt.buffer).row;
self.buffer_row_range.end = self.buffer_row_range.end =
self.buffer_row_range.start + excerpt.text_summary.lines.row + 1; self.buffer_row_range.start + excerpt.text_summary.lines.row + 1;
} }
@ -3079,7 +3138,13 @@ mod tests {
let subscription = multibuffer.update(cx, |multibuffer, cx| { let subscription = multibuffer.update(cx, |multibuffer, cx| {
let subscription = multibuffer.subscribe(); let subscription = multibuffer.subscribe();
multibuffer.push_excerpts(buffer_1.clone(), [Point::new(1, 2)..Point::new(2, 5)], cx); multibuffer.push_excerpts(
buffer_1.clone(),
[ExcerptRange {
context: Point::new(1, 2)..Point::new(2, 5),
}],
cx,
);
assert_eq!( assert_eq!(
subscription.consume().into_inner(), subscription.consume().into_inner(),
[Edit { [Edit {
@ -3088,8 +3153,20 @@ mod tests {
}] }]
); );
multibuffer.push_excerpts(buffer_1.clone(), [Point::new(3, 3)..Point::new(4, 4)], cx); multibuffer.push_excerpts(
multibuffer.push_excerpts(buffer_2.clone(), [Point::new(3, 1)..Point::new(3, 3)], cx); buffer_1.clone(),
[ExcerptRange {
context: Point::new(3, 3)..Point::new(4, 4),
}],
cx,
);
multibuffer.push_excerpts(
buffer_2.clone(),
[ExcerptRange {
context: Point::new(3, 1)..Point::new(3, 3),
}],
cx,
);
assert_eq!( assert_eq!(
subscription.consume().into_inner(), subscription.consume().into_inner(),
[Edit { [Edit {
@ -3253,7 +3330,7 @@ mod tests {
boundary.row, boundary.row,
boundary boundary
.buffer .buffer
.text_for_range(boundary.range) .text_for_range(boundary.range.context)
.collect::<String>(), .collect::<String>(),
boundary.starts_new_buffer, boundary.starts_new_buffer,
) )
@ -3334,8 +3411,8 @@ mod tests {
let buffer_2 = cx.add_model(|cx| Buffer::new(0, "efghi", cx)); let buffer_2 = cx.add_model(|cx| Buffer::new(0, "efghi", cx));
let multibuffer = cx.add_model(|cx| { let multibuffer = cx.add_model(|cx| {
let mut multibuffer = MultiBuffer::new(0); let mut multibuffer = MultiBuffer::new(0);
multibuffer.push_excerpts(buffer_1.clone(), [0..4], cx); multibuffer.push_excerpts(buffer_1.clone(), [ExcerptRange { context: 0..4 }], cx);
multibuffer.push_excerpts(buffer_2.clone(), [0..5], cx); multibuffer.push_excerpts(buffer_2.clone(), [ExcerptRange { context: 0..5 }], cx);
multibuffer multibuffer
}); });
let old_snapshot = multibuffer.read(cx).snapshot(cx); let old_snapshot = multibuffer.read(cx).snapshot(cx);
@ -3385,7 +3462,7 @@ mod tests {
buffer_1.update(cx, |buffer, cx| buffer.edit([(4..4, "123")], cx)); buffer_1.update(cx, |buffer, cx| buffer.edit([(4..4, "123")], cx));
let excerpt_id_1 = multibuffer.update(cx, |multibuffer, cx| { let excerpt_id_1 = multibuffer.update(cx, |multibuffer, cx| {
multibuffer multibuffer
.push_excerpts(buffer_1.clone(), [0..7], cx) .push_excerpts(buffer_1.clone(), [ExcerptRange { context: 0..7 }], cx)
.pop() .pop()
.unwrap() .unwrap()
}); });
@ -3397,7 +3474,15 @@ mod tests {
let (excerpt_id_2, excerpt_id_3) = multibuffer.update(cx, |multibuffer, cx| { let (excerpt_id_2, excerpt_id_3) = multibuffer.update(cx, |multibuffer, cx| {
multibuffer.remove_excerpts([&excerpt_id_1], cx); multibuffer.remove_excerpts([&excerpt_id_1], cx);
let mut ids = multibuffer let mut ids = multibuffer
.push_excerpts(buffer_2.clone(), [0..4, 6..10, 12..16], cx) .push_excerpts(
buffer_2.clone(),
[
ExcerptRange { context: 0..4 },
ExcerptRange { context: 6..10 },
ExcerptRange { context: 12..16 },
],
cx,
)
.into_iter(); .into_iter();
(ids.next().unwrap(), ids.next().unwrap()) (ids.next().unwrap(), ids.next().unwrap())
}); });
@ -3437,7 +3522,12 @@ mod tests {
let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| { let excerpt_id_5 = multibuffer.update(cx, |multibuffer, cx| {
multibuffer.remove_excerpts([&excerpt_id_3], cx); multibuffer.remove_excerpts([&excerpt_id_3], cx);
multibuffer multibuffer
.insert_excerpts_after(&excerpt_id_3, buffer_2.clone(), [5..8], cx) .insert_excerpts_after(
&excerpt_id_3,
buffer_2.clone(),
[ExcerptRange { context: 5..8 }],
cx,
)
.pop() .pop()
.unwrap() .unwrap()
}); });
@ -3584,7 +3674,9 @@ mod tests {
.insert_excerpts_after( .insert_excerpts_after(
&prev_excerpt_id, &prev_excerpt_id,
buffer_handle.clone(), buffer_handle.clone(),
[start_ix..end_ix], [ExcerptRange {
context: start_ix..end_ix,
}],
cx, cx,
) )
.pop() .pop()
@ -3893,8 +3985,20 @@ mod tests {
let multibuffer = cx.add_model(|_| MultiBuffer::new(0)); let multibuffer = cx.add_model(|_| MultiBuffer::new(0));
let group_interval = multibuffer.read(cx).history.group_interval; let group_interval = multibuffer.read(cx).history.group_interval;
multibuffer.update(cx, |multibuffer, cx| { multibuffer.update(cx, |multibuffer, cx| {
multibuffer.push_excerpts(buffer_1.clone(), [0..buffer_1.read(cx).len()], cx); multibuffer.push_excerpts(
multibuffer.push_excerpts(buffer_2.clone(), [0..buffer_2.read(cx).len()], cx); buffer_1.clone(),
[ExcerptRange {
context: 0..buffer_1.read(cx).len(),
}],
cx,
);
multibuffer.push_excerpts(
buffer_2.clone(),
[ExcerptRange {
context: 0..buffer_2.read(cx).len(),
}],
cx,
);
}); });
let mut now = Instant::now(); let mut now = Instant::now();

View file

@ -485,7 +485,7 @@ impl BufferSearchBar {
); );
} else { } else {
for excerpt in buffer.excerpt_boundaries_in_range(0..buffer.len()) { for excerpt in buffer.excerpt_boundaries_in_range(0..buffer.len()) {
let excerpt_range = excerpt.range.to_offset(&excerpt.buffer); let excerpt_range = excerpt.range.context.to_offset(&excerpt.buffer);
let rope = excerpt.buffer.as_rope().slice(excerpt_range.clone()); let rope = excerpt.buffer.as_rope().slice(excerpt_range.clone());
ranges.extend(query.search(&rope).await.into_iter().map(|range| { ranges.extend(query.search(&rope).await.into_iter().map(|range| {
let start = excerpt let start = excerpt