summaryrefslogtreecommitdiff
path: root/helix-core/src/transaction.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2020-09-13 02:32:37 +0000
committerBlaž Hrastnik2020-09-13 02:32:37 +0000
commitd466882d0432b7e9cf905041aa7a4f8d56047de0 (patch)
tree4f4a935feb4c4cf2a77cc3c6a2e4ad822d1a9825 /helix-core/src/transaction.rs
parentf098166571fd8fc2046d49355dffc0d2aad29e50 (diff)
Abstract Transaction::change_by_selection, working del/backspace.
Diffstat (limited to 'helix-core/src/transaction.rs')
-rw-r--r--helix-core/src/transaction.rs42
1 files changed, 24 insertions, 18 deletions
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index 2f40be76..130f77b8 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -342,31 +342,37 @@ impl Transaction {
true
}
- pub fn insert(state: &State, text: Tendril) -> Self {
+ pub fn change_by_selection<F>(state: &State, f: F) -> Self
+ where
+ F: Fn(&SelectionRange) -> (usize, usize, Option<Tendril>),
+ {
let len = state.doc.len_chars();
let ranges = state.selection.ranges();
- let mut changes = Vec::with_capacity(2 * ranges.len() + 1);
- let mut last = 0;
+ let mut acc = Vec::with_capacity(2 * ranges.len() + 1);
+
+ let changes = ranges.iter().map(f);
+
+ // TODO: verify ranges are ordered and not overlapping.
- for range in state.selection.ranges() {
- let cur = range.head;
- changes.push(Change::Retain(cur));
- changes.push(Change::Insert(text.clone()));
- last = cur;
+ let mut last = 0;
+ for (from, to, tendril) in changes {
+ // TODO: need to fill the in-between ranges too
+ // Retain from last "to" to current "from"
+ acc.push(Change::Retain(from - last));
+ match tendril {
+ Some(text) => acc.push(Change::Insert(text)),
+ None => acc.push(Change::Delete(to - from)),
+ }
+ last = to;
}
- changes.push(Change::Retain(len - last));
+ acc.push(Change::Retain(len - last));
- Self::from(ChangeSet { changes, len })
+ Self::from(ChangeSet { changes: acc, len })
}
- pub fn change_selection<F>(selection: Selection, f: F) -> Self
- where
- F: Fn(SelectionRange) -> ChangeSet,
- {
- selection.ranges().iter().map(|range| true);
- // TODO: most idiomatic would be to return a
- // Change { from: x, to: y, insert: "str" }
- unimplemented!()
+ /// Insert text at each selection head.
+ pub fn insert(state: &State, text: Tendril) -> Self {
+ Self::change_by_selection(state, |range| (range.head, range.head, Some(text.clone())))
}
}