Detailed changes
@@ -1629,7 +1629,7 @@ impl Editor {
pub fn select_to_beginning(&mut self, _: &(), cx: &mut ViewContext<Self>) {
let mut selection = self.selections(cx.as_ref()).last().unwrap().clone();
- selection.set_head(self.buffer.read(cx), Anchor::Start);
+ selection.set_head(self.buffer.read(cx), Anchor::min());
self.update_selections(vec![selection], true, cx);
}
@@ -1648,15 +1648,15 @@ impl Editor {
pub fn select_to_end(&mut self, _: &(), cx: &mut ViewContext<Self>) {
let mut selection = self.selections(cx.as_ref()).last().unwrap().clone();
- selection.set_head(self.buffer.read(cx), Anchor::End);
+ selection.set_head(self.buffer.read(cx), Anchor::max());
self.update_selections(vec![selection], true, cx);
}
pub fn select_all(&mut self, _: &(), cx: &mut ViewContext<Self>) {
let selection = Selection {
id: post_inc(&mut self.next_selection_id),
- start: Anchor::Start,
- end: Anchor::End,
+ start: Anchor::min(),
+ end: Anchor::max(),
reversed: false,
goal: SelectionGoal::None,
};
@@ -1493,14 +1493,8 @@ impl Buffer {
Operation::UpdateSelections { selections, .. } => {
if let Some(selections) = selections {
selections.iter().all(|selection| {
- let contains_start = match &selection.start {
- Anchor::Middle { version, .. } => self.version >= *version,
- _ => true,
- };
- let contains_end = match &selection.end {
- Anchor::Middle { version, .. } => self.version >= *version,
- _ => true,
- };
+ let contains_start = self.version >= selection.start.version;
+ let contains_end = self.version >= selection.end.version;
contains_start && contains_end
})
} else {
@@ -1645,76 +1639,42 @@ impl Buffer {
let offset = position.to_offset(self);
let max_offset = self.len();
assert!(offset <= max_offset, "offset is out of range");
-
- if offset == 0 && bias == Bias::Left {
- Anchor::Start
- } else if offset == max_offset && bias == Bias::Right {
- Anchor::End
- } else {
- let mut cursor = self.fragments.cursor::<usize, FragmentTextSummary>();
- cursor.seek(&offset, bias, &None);
- Anchor::Middle {
- offset: offset + cursor.start().deleted,
- bias,
- version: self.version(),
- }
+ let mut cursor = self.fragments.cursor::<usize, FragmentTextSummary>();
+ cursor.seek(&offset, bias, &None);
+ Anchor {
+ offset: offset + cursor.start().deleted,
+ bias,
+ version: self.version(),
}
}
fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
- match anchor {
- Anchor::Start => TextSummary::default(),
- Anchor::End => self.text_summary(),
- Anchor::Middle {
- offset,
- bias,
- version,
- } => {
- let mut cursor = self
- .fragments
- .cursor::<VersionedOffset, (VersionedOffset, usize)>();
- cursor.seek(
- &VersionedOffset::Offset(*offset),
- *bias,
- &Some(version.clone()),
- );
- let fragment = cursor.item().unwrap();
- let overshoot = if fragment.visible {
- offset - cursor.start().0.offset()
- } else {
- 0
- };
-
- self.text_summary_for_range(0..cursor.start().1 + overshoot)
- }
- }
+ let cx = Some(anchor.version.clone());
+ let mut cursor = self
+ .fragments
+ .cursor::<VersionedOffset, (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.start().0.offset()
+ } else {
+ 0
+ };
+ self.text_summary_for_range(0..cursor.start().1 + overshoot)
}
fn full_offset_for_anchor(&self, anchor: &Anchor) -> usize {
- match anchor {
- Anchor::Start => 0,
- Anchor::End => {
- let summary = self.fragments.summary();
- summary.text.visible + summary.text.deleted
- }
- Anchor::Middle {
- offset,
- bias,
- version,
- } => {
- let mut cursor = self
- .fragments
- .cursor::<VersionedOffset, (VersionedOffset, FragmentTextSummary)>();
- cursor.seek(
- &VersionedOffset::Offset(*offset),
- *bias,
- &Some(version.clone()),
- );
- let overshoot = offset - cursor.start().0.offset();
- let summary = cursor.start().1;
- summary.visible + summary.deleted + overshoot
- }
- }
+ let cx = Some(anchor.version.clone());
+ let mut cursor = self
+ .fragments
+ .cursor::<VersionedOffset, (VersionedOffset, FragmentTextSummary)>();
+ cursor.seek(&VersionedOffset::Offset(anchor.offset), anchor.bias, &cx);
+ let overshoot = if cursor.item().is_some() {
+ anchor.offset - cursor.start().0.offset()
+ } else {
+ 0
+ };
+ let summary = cursor.start().1;
+ summary.visible + summary.deleted + overshoot
}
pub fn point_for_offset(&self, offset: usize) -> Result<Point> {
@@ -2311,34 +2271,19 @@ impl<'a> Into<proto::operation::Edit> for &'a EditOperation {
impl<'a> Into<proto::Anchor> for &'a Anchor {
fn into(self) -> proto::Anchor {
- match self {
- Anchor::Middle {
- offset,
- bias,
- version,
- } => proto::Anchor {
- version: version
- .iter()
- .map(|entry| proto::VectorClockEntry {
- replica_id: entry.replica_id as u32,
- timestamp: entry.value,
- })
- .collect(),
- offset: *offset as u64,
- bias: match bias {
- Bias::Left => proto::anchor::Bias::Left as i32,
- Bias::Right => proto::anchor::Bias::Right as i32,
- },
- },
- Anchor::Start => proto::Anchor {
- version: Vec::new(),
- bias: proto::anchor::Bias::Left as i32,
- offset: 0,
- },
- Anchor::End => proto::Anchor {
- version: Vec::new(),
- bias: proto::anchor::Bias::Right as i32,
- offset: u64::MAX,
+ proto::Anchor {
+ version: self
+ .version
+ .iter()
+ .map(|entry| proto::VectorClockEntry {
+ replica_id: entry.replica_id as u32,
+ timestamp: entry.value,
+ })
+ .collect(),
+ offset: self.offset as u64,
+ bias: match self.bias {
+ Bias::Left => proto::anchor::Bias::Left as i32,
+ Bias::Right => proto::anchor::Bias::Right as i32,
},
}
}
@@ -2449,7 +2394,7 @@ impl TryFrom<proto::Anchor> for Anchor {
});
}
- Ok(Self::Middle {
+ Ok(Self {
offset: message.offset as usize,
bias: if message.bias == proto::anchor::Bias::Left as i32 {
Bias::Left
@@ -4,67 +4,58 @@ use anyhow::Result;
use std::{cmp::Ordering, ops::Range};
#[derive(Clone, Eq, PartialEq, Debug, Hash)]
-pub enum Anchor {
- Start,
- End,
- Middle {
- offset: usize,
- bias: Bias,
- version: time::Global,
- },
+pub struct Anchor {
+ pub offset: usize,
+ pub bias: Bias,
+ pub version: time::Global,
}
impl Anchor {
+ pub fn min() -> Self {
+ Self {
+ offset: 0,
+ bias: Bias::Left,
+ version: Default::default(),
+ }
+ }
+
+ pub fn max() -> Self {
+ Self {
+ offset: usize::MAX,
+ bias: Bias::Right,
+ version: Default::default(),
+ }
+ }
+
pub fn cmp(&self, other: &Anchor, buffer: &Buffer) -> Result<Ordering> {
if self == other {
return Ok(Ordering::Equal);
}
- Ok(match (self, other) {
- (Anchor::Start, _) | (_, Anchor::End) => Ordering::Less,
- (Anchor::End, _) | (_, Anchor::Start) => Ordering::Greater,
- (
- Anchor::Middle {
- offset: self_offset,
- bias: self_bias,
- version: self_version,
- },
- Anchor::Middle {
- offset: other_offset,
- bias: other_bias,
- version: other_version,
- },
- ) => {
- let offset_comparison = if self_version == other_version {
- self_offset.cmp(other_offset)
- } else {
- buffer
- .full_offset_for_anchor(self)
- .cmp(&buffer.full_offset_for_anchor(other))
- };
+ let offset_comparison = if self.version == other.version {
+ self.offset.cmp(&other.offset)
+ } else {
+ buffer
+ .full_offset_for_anchor(self)
+ .cmp(&buffer.full_offset_for_anchor(other))
+ };
- offset_comparison.then_with(|| self_bias.cmp(&other_bias))
- }
- })
+ Ok(offset_comparison.then_with(|| self.bias.cmp(&other.bias)))
}
pub fn bias_left(&self, buffer: &Buffer) -> Anchor {
- match self {
- Anchor::Start
- | Anchor::Middle {
- bias: Bias::Left, ..
- } => self.clone(),
- _ => buffer.anchor_before(self),
+ if self.bias == Bias::Left {
+ self.clone()
+ } else {
+ buffer.anchor_before(self)
}
}
pub fn bias_right(&self, buffer: &Buffer) -> Anchor {
- match self {
- Anchor::End
- | Anchor::Middle {
- bias: Bias::Right, ..
- } => self.clone(),
- _ => buffer.anchor_after(self),
+ if self.bias == Bias::Right {
+ self.clone()
+ } else {
+ buffer.anchor_after(self)
}
}
}
@@ -313,7 +313,7 @@ impl FoldMap {
let anchor = buffer.anchor_before(edit.new_range.start);
let mut folds_cursor = self.folds.cursor::<_, ()>();
- folds_cursor.seek(&Fold(anchor..Anchor::End), Bias::Left, buffer);
+ folds_cursor.seek(&Fold(anchor..Anchor::max()), Bias::Left, buffer);
let mut folds = iter::from_fn(move || {
let item = folds_cursor
.item()
@@ -597,7 +597,7 @@ struct Fold(Range<Anchor>);
impl Default for Fold {
fn default() -> Self {
- Self(Anchor::Start..Anchor::End)
+ Self(Anchor::min()..Anchor::max())
}
}
@@ -627,10 +627,10 @@ struct FoldSummary {
impl Default for FoldSummary {
fn default() -> Self {
Self {
- start: Anchor::Start,
- end: Anchor::End,
- min_start: Anchor::End,
- max_end: Anchor::Start,
+ start: Anchor::min(),
+ end: Anchor::max(),
+ min_start: Anchor::max(),
+ max_end: Anchor::min(),
count: 0,
}
}