Avoid ending the pending selection until updating selections

Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-11-03 19:07:06 +01:00
parent 9dc3c74260
commit c07d794249
6 changed files with 160 additions and 115 deletions

View file

@ -113,6 +113,14 @@ impl Anchor {
buffer.anchor_after(self)
}
}
pub fn summary<'a, D, C>(&self, content: C) -> D
where
D: TextDimension<'a>,
C: Into<Content<'a>>,
{
content.into().summary_for_anchor(self)
}
}
impl<T> AnchorMap<T> {
@ -124,24 +132,15 @@ impl<T> AnchorMap<T> {
self.entries.len()
}
pub fn offsets<'a>(
&'a self,
content: impl Into<Content<'a>> + 'a,
) -> impl Iterator<Item = (usize, &'a T)> + 'a {
pub fn iter<'a, D, C>(&'a self, content: C) -> impl Iterator<Item = (D, &'a T)> + 'a
where
D: 'a + TextDimension<'a>,
C: 'a + Into<Content<'a>>,
{
let content = content.into();
content
.summaries_for_anchors(self)
.map(move |(sum, value)| (sum.bytes, value))
}
pub fn points<'a>(
&'a self,
content: impl Into<Content<'a>> + 'a,
) -> impl Iterator<Item = (Point, &'a T)> + 'a {
let content = content.into();
content
.summaries_for_anchors(self)
.map(move |(sum, value)| (sum.lines, value))
.map(move |(sum, value)| (sum, value))
}
}
@ -154,18 +153,12 @@ impl AnchorSet {
self.0.len()
}
pub fn offsets<'a>(
&'a self,
content: impl Into<Content<'a>> + 'a,
) -> impl Iterator<Item = usize> + 'a {
self.0.offsets(content).map(|(offset, _)| offset)
}
pub fn points<'a>(
&'a self,
content: impl Into<Content<'a>> + 'a,
) -> impl Iterator<Item = Point> + 'a {
self.0.points(content).map(|(point, _)| point)
pub fn iter<'a, D, C>(&'a self, content: C) -> impl Iterator<Item = D> + 'a
where
D: 'a + TextDimension<'a>,
C: 'a + Into<Content<'a>>,
{
self.0.iter(content).map(|(position, _)| position)
}
}

View file

@ -1719,7 +1719,10 @@ impl<'a> Content<'a> {
result
}
fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary {
fn summary_for_anchor<D>(&self, anchor: &Anchor) -> D
where
D: TextDimension<'a>,
{
let cx = Some(anchor.version.clone());
let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
cursor.seek(
@ -1735,16 +1738,19 @@ impl<'a> Content<'a> {
self.text_summary_for_range(0..cursor.start().1 + overshoot)
}
fn text_summary_for_range(&self, range: Range<usize>) -> TextSummary {
fn text_summary_for_range<D>(&self, range: Range<usize>) -> D
where
D: TextDimension<'a>,
{
self.visible_text.cursor(range.start).summary(range.end)
}
fn summaries_for_anchors<T>(
&self,
map: &'a AnchorMap<T>,
) -> impl Iterator<Item = (TextSummary, &'a T)> {
fn summaries_for_anchors<D, T>(&self, map: &'a AnchorMap<T>) -> impl Iterator<Item = (D, &'a T)>
where
D: TextDimension<'a>,
{
let cx = Some(map.version.clone());
let mut summary = TextSummary::default();
let mut summary = D::default();
let mut rope_cursor = self.visible_text.cursor(0);
let mut cursor = self.fragments.cursor::<(VersionedFullOffset, usize)>();
map.entries.iter().map(move |((offset, bias), value)| {
@ -1754,7 +1760,7 @@ impl<'a> Content<'a> {
} else {
0
};
summary += rope_cursor.summary::<TextSummary>(cursor.start().1 + overshoot);
summary.add_assign(&rope_cursor.summary(cursor.start().1 + overshoot));
(summary.clone(), value)
})
}
@ -1928,7 +1934,7 @@ impl<'a> Content<'a> {
fn point_for_offset(&self, offset: usize) -> Result<Point> {
if offset <= self.len() {
Ok(self.text_summary_for_range(0..offset).lines)
Ok(self.text_summary_for_range(0..offset))
} else {
Err(anyhow!("offset out of bounds"))
}
@ -2316,13 +2322,13 @@ impl ToOffset for usize {
impl ToOffset for Anchor {
fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize {
content.into().summary_for_anchor(self).bytes
content.into().summary_for_anchor(self)
}
}
impl<'a> ToOffset for &'a Anchor {
fn to_offset<'b>(&self, content: impl Into<Content<'b>>) -> usize {
content.into().summary_for_anchor(self).bytes
content.into().summary_for_anchor(self)
}
}
@ -2332,7 +2338,7 @@ pub trait ToPoint {
impl ToPoint for Anchor {
fn to_point<'a>(&self, content: impl Into<Content<'a>>) -> Point {
content.into().summary_for_anchor(self).lines
content.into().summary_for_anchor(self)
}
}

View file

@ -36,19 +36,29 @@ pub struct SelectionState {
pub goal: SelectionGoal,
}
impl<T: Clone> Selection<T> {
pub fn head(&self) -> T {
if self.reversed {
self.start.clone()
} else {
self.end.clone()
}
}
pub fn tail(&self) -> T {
if self.reversed {
self.end.clone()
} else {
self.start.clone()
}
}
}
impl<T: ToOffset + ToPoint + Copy + Ord> Selection<T> {
pub fn is_empty(&self) -> bool {
self.start == self.end
}
pub fn head(&self) -> T {
if self.reversed {
self.start
} else {
self.end
}
}
pub fn set_head(&mut self, head: T) {
if head.cmp(&self.tail()) < Ordering::Equal {
if !self.reversed {
@ -65,14 +75,6 @@ impl<T: ToOffset + ToPoint + Copy + Ord> Selection<T> {
}
}
pub fn tail(&self) -> T {
if self.reversed {
self.end
} else {
self.start
}
}
pub fn point_range(&self, buffer: &Buffer) -> Range<Point> {
let start = self.start.to_point(buffer);
let end = self.end.to_point(buffer);