on master help sign in
Selection mapping over changesets.
1984410Blaž Hrastnik
helix-core/src/lib.rs+1−1
@@ -13,4 +13,4 @@ pub use selection::Selection;
13
13
14pub use state::State;
14pub use state::State;
15
15
16−pub use transaction::{Change, ChangeSet, Transaction};
16+pub use transaction::{Assoc, Change, ChangeSet, Transaction};
helix-core/src/selection.rs+29−1
@@ -2,6 +2,7 @@
2//! single selection range.
2//! single selection range.
3//!
3//!
4//! All positioning is done via `char` offsets into the buffer.
4//! All positioning is done via `char` offsets into the buffer.
5+use crate::{Assoc, ChangeSet};
5use smallvec::{smallvec, SmallVec};
6use smallvec::{smallvec, SmallVec};
6
7
7#[inline]
8#[inline]
@@ -59,7 +60,18 @@ impl Range {
59 }
60 }
60 }
61 }
61
62
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+ }
63
75
64 /// Extend the range to cover at least `from` `to`.
76 /// Extend the range to cover at least `from` `to`.
65 #[must_use]
77 #[must_use]
@@ -115,6 +127,22 @@ impl Selection {
115 // add_range // push
127 // add_range // push
116 // replace_range
128 // replace_range
117
129
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+
118 #[must_use]
146 #[must_use]
119 /// Constructs a selection holding a single range.
147 /// Constructs a selection holding a single range.
120 pub fn single(anchor: usize, head: usize) -> Self {
148 pub fn single(anchor: usize, head: usize) -> Self {
helix-core/src/transaction.rs+7
@@ -242,6 +242,13 @@ impl ChangeSet {
242 }
242 }
243 }
243 }
244
244
245+ /// `true` when the set is empty.
246+ #[inline]
247+ pub fn is_empty(&self) -> bool {
248+ let len = self.changes.len();
249+ len == 0 || (len == 1 && self.changes[0] == Change::Retain(self.len))
250+ }
251+
245 /// Map a position through the changes.
252 /// Map a position through the changes.
246 ///
253 ///
247 /// `assoc` indicates which size to associate the position with. `Before` will keep the
254 /// `assoc` indicates which size to associate the position with. `Before` will keep the