aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/transaction.rs
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-02-15 15:15:49 +0000
committerBlaž Hrastnik2021-02-15 15:15:49 +0000
commit19fb4ed835558cc9212ae4923baf2854c7a3ad69 (patch)
treec548b3238b309835c6ad96a93a3805ac7a689bcc /helix-core/src/transaction.rs
parent65893a2cbc0c91ad9e6f82f81d77111caacbffb7 (diff)
transaction: Merge consecutive inserts on compose.
Diffstat (limited to 'helix-core/src/transaction.rs')
-rw-r--r--helix-core/src/transaction.rs46
1 files changed, 43 insertions, 3 deletions
diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs
index eec947df..25a1a762 100644
--- a/helix-core/src/transaction.rs
+++ b/helix-core/src/transaction.rs
@@ -94,8 +94,14 @@ impl ChangeSet {
head_b = b;
}
// insertion in B
- (a, Some(change @ Insert(..))) => {
- changes.push(change);
+ (a, Some(Insert(current))) => {
+ // merge onto previous insert if possible
+ // TODO: do these as operations on a changeset
+ if let Some(Insert(prev)) = changes.last_mut() {
+ prev.push_tendril(&current);
+ } else {
+ changes.push(Insert(current));
+ }
head_a = a;
head_b = changes_b.next();
}
@@ -422,7 +428,9 @@ impl Transaction {
let mut last = 0;
for (from, to, tendril) in changes {
// Retain from last "to" to current "from"
- acc.push(Operation::Retain(from - last));
+ if from - last > 0 {
+ acc.push(Operation::Retain(from - last));
+ }
let span = to - from;
match tendril {
Some(text) => {
@@ -581,4 +589,36 @@ mod test {
transaction.apply(&mut state);
assert_eq!(state.doc, Rope::from_str("hello void! 123"));
}
+
+ #[test]
+ fn insert_composition() {
+ let mut state = State::new("".into());
+ let t1 = Transaction::insert(&state, Tendril::from_char('h'));
+ t1.apply(&mut state);
+ let t2 = Transaction::insert(&state, Tendril::from_char('e'));
+ t2.apply(&mut state);
+ let t3 = Transaction::insert(&state, Tendril::from_char('l'));
+ t3.apply(&mut state);
+ let t4 = Transaction::insert(&state, Tendril::from_char('l'));
+ t4.apply(&mut state);
+ let t5 = Transaction::insert(&state, Tendril::from_char('o'));
+ t5.apply(&mut state);
+
+ assert_eq!(state.doc, Rope::from_str("hello"));
+
+ // changesets as follows:
+ // h
+ // retain 1, e
+ // retain 2, l
+
+ let mut changes = t1
+ .changes
+ .compose(t2.changes)
+ .compose(t3.changes)
+ .compose(t4.changes)
+ .compose(t5.changes);
+
+ use Operation::*;
+ assert_eq!(changes.changes, &[Insert("hello".into())]);
+ }
}