on master help sign in
transaction: Merge consecutive inserts on compose.
19fb4edBlaž Hrastnik
helix-core/src/transaction.rs+43−3
@@ -94,8 +94,14 @@ impl ChangeSet {
94 head_b = b;
94 head_b = b;
95 }
95 }
96 // insertion in B
96 // insertion in B
97− (a, Some(change @ Insert(..))) => {
97+ (a, Some(Insert(current))) => {
98+ // merge onto previous insert if possible
99+ // TODO: do these as operations on a changeset
100+ if let Some(Insert(prev)) = changes.last_mut() {
101+ prev.push_tendril(&current);
102+ } else {
98− changes.push(change);
103+ changes.push(Insert(current));
104+ }
99 head_a = a;
105 head_a = a;
100 head_b = changes_b.next();
106 head_b = changes_b.next();
101 }
107 }
@@ -422,7 +428,9 @@ impl Transaction {
422 let mut last = 0;
428 let mut last = 0;
423 for (from, to, tendril) in changes {
429 for (from, to, tendril) in changes {
424 // Retain from last "to" to current "from"
430 // Retain from last "to" to current "from"
431+ if from - last > 0 {
425− acc.push(Operation::Retain(from - last));
432+ acc.push(Operation::Retain(from - last));
433+ }
426 let span = to - from;
434 let span = to - from;
427 match tendril {
435 match tendril {
428 Some(text) => {
436 Some(text) => {
@@ -581,4 +589,36 @@ mod test {
581 transaction.apply(&mut state);
589 transaction.apply(&mut state);
582 assert_eq!(state.doc, Rope::from_str("hello void! 123"));
590 assert_eq!(state.doc, Rope::from_str("hello void! 123"));
583 }
591 }
592+
593+ #[test]
594+ fn insert_composition() {
595+ let mut state = State::new("".into());
596+ let t1 = Transaction::insert(&state, Tendril::from_char('h'));
597+ t1.apply(&mut state);
598+ let t2 = Transaction::insert(&state, Tendril::from_char('e'));
599+ t2.apply(&mut state);
600+ let t3 = Transaction::insert(&state, Tendril::from_char('l'));
601+ t3.apply(&mut state);
602+ let t4 = Transaction::insert(&state, Tendril::from_char('l'));
603+ t4.apply(&mut state);
604+ let t5 = Transaction::insert(&state, Tendril::from_char('o'));
605+ t5.apply(&mut state);
606+
607+ assert_eq!(state.doc, Rope::from_str("hello"));
608+
609+ // changesets as follows:
610+ // h
611+ // retain 1, e
612+ // retain 2, l
613+
614+ let mut changes = t1
615+ .changes
616+ .compose(t2.changes)
617+ .compose(t3.changes)
618+ .compose(t4.changes)
619+ .compose(t5.changes);
620+
621+ use Operation::*;
622+ assert_eq!(changes.changes, &[Insert("hello".into())]);
623+ }
584}
624}