mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-04 18:15:21 +00:00
Introduce buffer::Content<'a> struct to share logic with buffer::Snapshot
We want to move a bunch of methods on FoldMap to fold_map::Snapshot. This captures a buffer snapshot, and we'll need a bunch of methods that currently are on Buffer to also be implemented on buffer::Snapshot. This Content reference struct will be a good zero-cost place to store that logic.
This commit is contained in:
parent
be954872d0
commit
09afba9251
2 changed files with 78 additions and 34 deletions
|
@ -1215,8 +1215,8 @@ impl Editor {
|
|||
String::from_iter(clipboard_chars.by_ref().take(clipboard_selection.len));
|
||||
|
||||
self.buffer.update(cx, |buffer, cx| {
|
||||
let selection_start = selection.start.to_point(buffer);
|
||||
let selection_end = selection.end.to_point(buffer);
|
||||
let selection_start = selection.start.to_point(&*buffer);
|
||||
let selection_end = selection.end.to_point(&*buffer);
|
||||
|
||||
// If the corresponding selection was empty when this slice of the
|
||||
// clipboard text was written, then the entire line containing the
|
||||
|
|
|
@ -601,6 +601,7 @@ impl Buffer {
|
|||
pub fn snapshot(&self) -> Snapshot {
|
||||
Snapshot {
|
||||
text: self.visible_text.clone(),
|
||||
fragments: self.fragments.clone(),
|
||||
tree: self.syntax_tree(),
|
||||
language: self.language.clone(),
|
||||
query_cursor: QueryCursorHandle::new(),
|
||||
|
@ -1005,10 +1006,6 @@ impl Buffer {
|
|||
self.visible_text.summary()
|
||||
}
|
||||
|
||||
pub fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
|
||||
self.visible_text.cursor(range.start).summary(range.end)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.fragments.extent::<usize>(&None)
|
||||
}
|
||||
|
@ -1149,7 +1146,7 @@ impl Buffer {
|
|||
// Skip invalid ranges and coalesce contiguous ones.
|
||||
let mut ranges: Vec<Range<usize>> = Vec::new();
|
||||
for range in ranges_iter {
|
||||
let range = range.start.to_offset(self)..range.end.to_offset(self);
|
||||
let range = range.start.to_offset(&*self)..range.end.to_offset(&*self);
|
||||
if has_new_text || !range.is_empty() {
|
||||
if let Some(prev_range) = ranges.last_mut() {
|
||||
if prev_range.end >= range.start {
|
||||
|
@ -1860,6 +1857,14 @@ impl Buffer {
|
|||
edit
|
||||
}
|
||||
|
||||
fn content<'a>(&'a self) -> Content<'a> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
pub fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
|
||||
self.content().text_summary_for_range(range)
|
||||
}
|
||||
|
||||
pub fn anchor_before<T: ToOffset>(&self, position: T) -> Anchor {
|
||||
self.anchor_at(position, Bias::Left)
|
||||
}
|
||||
|
@ -1881,18 +1886,6 @@ impl Buffer {
|
|||
}
|
||||
}
|
||||
|
||||
fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
|
||||
let cx = Some(anchor.version.clone());
|
||||
let mut cursor = self.fragments.cursor::<VersionedOffset, usize>();
|
||||
cursor.seek(&VersionedOffset::Offset(anchor.offset), anchor.bias, &cx);
|
||||
let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
|
||||
anchor.offset - cursor.seek_start().offset()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.text_summary_for_range(0..*cursor.sum_start() + overshoot)
|
||||
}
|
||||
|
||||
fn full_offset_for_anchor(&self, anchor: &Anchor) -> usize {
|
||||
let cx = Some(anchor.version.clone());
|
||||
let mut cursor = self
|
||||
|
@ -1910,7 +1903,7 @@ impl Buffer {
|
|||
|
||||
pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
|
||||
if offset <= self.len() {
|
||||
Ok(self.text_summary_for_range(0..offset).lines)
|
||||
Ok(self.content().text_summary_for_range(0..offset).lines)
|
||||
} else {
|
||||
Err(anyhow!("offset out of bounds"))
|
||||
}
|
||||
|
@ -1957,6 +1950,7 @@ impl Clone for Buffer {
|
|||
|
||||
pub struct Snapshot {
|
||||
text: Rope,
|
||||
fragments: SumTree<Fragment>,
|
||||
tree: Option<Tree>,
|
||||
language: Option<Arc<Language>>,
|
||||
query_cursor: QueryCursorHandle,
|
||||
|
@ -2020,6 +2014,56 @@ impl Snapshot {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Content<'a> {
|
||||
visible_text: &'a Rope,
|
||||
fragments: &'a SumTree<Fragment>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Snapshot> for Content<'a> {
|
||||
fn from(snapshot: &'a Snapshot) -> Self {
|
||||
Self {
|
||||
visible_text: &snapshot.text,
|
||||
fragments: &snapshot.fragments,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Buffer> for Content<'a> {
|
||||
fn from(buffer: &'a Buffer) -> Self {
|
||||
Self {
|
||||
visible_text: &buffer.visible_text,
|
||||
fragments: &buffer.fragments,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a mut Buffer> for Content<'a> {
|
||||
fn from(buffer: &'a mut Buffer) -> Self {
|
||||
Self {
|
||||
visible_text: &buffer.visible_text,
|
||||
fragments: &buffer.fragments,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Content<'a> {
|
||||
fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
|
||||
let cx = Some(anchor.version.clone());
|
||||
let mut cursor = self.fragments.cursor::<VersionedOffset, usize>();
|
||||
cursor.seek(&VersionedOffset::Offset(anchor.offset), anchor.bias, &cx);
|
||||
let overshoot = if cursor.item().map_or(false, |fragment| fragment.visible) {
|
||||
anchor.offset - cursor.seek_start().offset()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
self.text_summary_for_range(0..*cursor.sum_start() + overshoot)
|
||||
}
|
||||
|
||||
pub fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
|
||||
self.visible_text.cursor(range.start).summary(range.end)
|
||||
}
|
||||
}
|
||||
|
||||
struct RopeBuilder<'a> {
|
||||
old_visible_cursor: rope::Cursor<'a>,
|
||||
old_deleted_cursor: rope::Cursor<'a>,
|
||||
|
@ -2704,46 +2748,46 @@ impl operation_queue::Operation for Operation {
|
|||
}
|
||||
|
||||
pub trait ToOffset {
|
||||
fn to_offset(&self, buffer: &Buffer) -> usize;
|
||||
fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize;
|
||||
}
|
||||
|
||||
impl ToOffset for Point {
|
||||
fn to_offset(&self, buffer: &Buffer) -> usize {
|
||||
buffer.visible_text.to_offset(*self)
|
||||
fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize {
|
||||
content.into().visible_text.to_offset(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOffset for usize {
|
||||
fn to_offset(&self, _: &Buffer) -> usize {
|
||||
fn to_offset<'a>(&self, _: impl Into<Content<'a>>) -> usize {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl ToOffset for Anchor {
|
||||
fn to_offset(&self, buffer: &Buffer) -> usize {
|
||||
buffer.summary_for_anchor(self).bytes
|
||||
fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize {
|
||||
content.into().summary_for_anchor(self).bytes
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToOffset for &'a Anchor {
|
||||
fn to_offset(&self, buffer: &Buffer) -> usize {
|
||||
buffer.summary_for_anchor(self).bytes
|
||||
fn to_offset<'b>(&self, content: impl Into<Content<'b>>) -> usize {
|
||||
content.into().summary_for_anchor(self).bytes
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToPoint {
|
||||
fn to_point(&self, buffer: &Buffer) -> Point;
|
||||
fn to_point<'a>(&self, content: impl Into<Content<'a>>) -> Point;
|
||||
}
|
||||
|
||||
impl ToPoint for Anchor {
|
||||
fn to_point(&self, buffer: &Buffer) -> Point {
|
||||
buffer.summary_for_anchor(self).lines
|
||||
fn to_point<'a>(&self, content: impl Into<Content<'a>>) -> Point {
|
||||
content.into().summary_for_anchor(self).lines
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPoint for usize {
|
||||
fn to_point(&self, buffer: &Buffer) -> Point {
|
||||
buffer.visible_text.to_point(*self)
|
||||
fn to_point<'a>(&self, content: impl Into<Content<'a>>) -> Point {
|
||||
content.into().visible_text.to_point(*self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3411,7 +3455,7 @@ mod tests {
|
|||
.iter()
|
||||
.map(|selection| {
|
||||
assert_eq!(selection.start, selection.end);
|
||||
selection.start.to_point(&buffer)
|
||||
selection.start.to_point(&*buffer)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
|
|
Loading…
Reference in a new issue