@@ -2,6 +2,7 @@
22//! single selection range.
33//!
44//! All positioning is done via `char` offsets into the buffer.
5+use crate::{Assoc, ChangeSet};
56use smallvec::{smallvec, SmallVec};
67
78#[inline]
@@ -59,7 +60,18 @@ impl Range {
5960 }
6061 }
6162
62− // TODO: map
63+ /// Map a range through a set of changes. Returns a new range representing the same position
64+ /// after the changes are applied.
65+ pub fn map(self, changes: &ChangeSet) -> Self {
66+ let anchor = changes.map_pos(self.anchor, Assoc::Before);
67+ let head = changes.map_pos(self.head, Assoc::Before);
68+
69+ // TODO: possibly unnecessary
70+ if self.anchor == anchor && self.head == head {
71+ return self;
72+ }
73+ Self { anchor, head }
74+ }
6375
6476 /// Extend the range to cover at least `from` `to`.
6577 #[must_use]
@@ -115,6 +127,22 @@ impl Selection {
115127 // add_range // push
116128 // replace_range
117129
130+ /// Map selections over a set of changes. Useful for adjusting the selection position after
131+ /// applying changes to a document.
132+ pub fn map(self, changes: &ChangeSet) -> Self {
133+ if changes.is_empty() {
134+ return self;
135+ }
136+
137+ Self::new(
138+ self.ranges
139+ .into_iter()
140+ .map(|range| range.map(changes))
141+ .collect(),
142+ self.primary_index,
143+ )
144+ }
145+
118146 #[must_use]
119147 /// Constructs a selection holding a single range.
120148 pub fn single(anchor: usize, head: usize) -> Self {