diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index 7817618fb488b..305cca1c9aebe 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -8,7 +8,7 @@ use crate::{ prev_grapheme_boundary, }, movement::Direction, - Assoc, ChangeSet, RopeGraphemes, RopeSlice, + Assoc, ChangeSet, RopeGraphemes, RopeSlice, Tendril, }; use smallvec::{smallvec, SmallVec}; use std::borrow::Cow; @@ -329,6 +329,21 @@ impl Range { } } + /// Gets a range from [anchor, left-side block cursor]. + #[must_use] + #[inline] + pub fn cursor_selection(self, text: RopeSlice) -> Range { + let head = self.cursor(text); + Range::new(std::cmp::min(self.anchor, head), head) + } + + /// Gets a offset by tendril lenght, to be used with the cursor method. + #[must_use] + #[inline] + pub fn cursor_tendril_offset(self, tendril: &Tendril) -> Range { + Range::point(self.head + tendril.len() - (self.head - self.anchor)) + } + /// Puts the left side of the block cursor at `char_idx`, optionally extending. /// /// This follows "1-width" semantics, and therefore does a combination of anchor @@ -592,7 +607,7 @@ impl Selection { /// Transforms the selection into all of the left-side head positions, /// using block-cursor semantics. pub fn cursors(self, text: RopeSlice) -> Self { - self.transform(|range| Range::point(range.cursor(text))) + self.transform(|range| range.cursor_selection(text)) } pub fn fragments<'a>(&'a self, text: RopeSlice<'a>) -> impl Iterator> + 'a { diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index 482fd6d97e5e7..dec253efd55cf 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -511,8 +511,13 @@ impl Transaction { /// Insert text at each selection head. pub fn insert(doc: &Rope, selection: &Selection, text: Tendril) -> Self { Self::change_by_selection(doc, selection, |range| { - (range.head, range.head, Some(text.clone())) + (range.anchor, range.head, Some(text.clone())) }) + .with_selection( + selection + .clone() + .transform(|range| range.cursor_tendril_offset(&text)), + ) } pub fn changes_iter(&self) -> ChangeIterator {