diff options
author | Blaž Hrastnik | 2021-02-15 15:15:49 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2021-02-15 15:15:49 +0000 |
commit | 19fb4ed835558cc9212ae4923baf2854c7a3ad69 (patch) | |
tree | c548b3238b309835c6ad96a93a3805ac7a689bcc | |
parent | 65893a2cbc0c91ad9e6f82f81d77111caacbffb7 (diff) |
transaction: Merge consecutive inserts on compose.
-rw-r--r-- | helix-core/src/transaction.rs | 46 |
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(¤t); + } 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())]); + } } |