Avoid ending the pending selection until updating selections
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
9dc3c74260
commit
c07d794249
6 changed files with 160 additions and 115 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue