From 94f9603c7490bf1616ecc44af99063f044b4d2a4 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Wed, 14 Oct 2020 09:38:52 +0900 Subject: Fix compose not merging certain changesets correctly. --- helix-core/src/selection.rs | 10 +++++----- helix-core/src/transaction.rs | 17 ++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/helix-core/src/selection.rs b/helix-core/src/selection.rs index d3806cf3..13c820f1 100644 --- a/helix-core/src/selection.rs +++ b/helix-core/src/selection.rs @@ -371,17 +371,17 @@ mod test { assert_eq!( result.ranges(), &[ - Range::new(0, 4), - Range::new(5, 8), - Range::new(10, 12), - Range::new(15, 18), + Range::new(0, 3), + Range::new(5, 7), + Range::new(10, 11), + Range::new(15, 17), Range::new(19, 19), ] ); assert_eq!( result.fragments(&text.slice(..)).collect::>(), - &["abcd", "efg", "rs", "xyz", ""] + &["abcd", "efg", "rs", "xyz", "1"] ); } } diff --git a/helix-core/src/transaction.rs b/helix-core/src/transaction.rs index a84313b2..d41b68e4 100644 --- a/helix-core/src/transaction.rs +++ b/helix-core/src/transaction.rs @@ -133,10 +133,9 @@ impl ChangeSet { Ordering::Greater => { // figure out the byte index of the truncated string end let (pos, _) = s.char_indices().nth(j).unwrap(); - // calculate the difference - let to_drop = s.len() - pos; - s.pop_back(u32::try_from(to_drop).unwrap()); - head_a = Some(Insert(s)); + let pos = pos as u32; + changes.push(Insert(s.subtendril(0, pos))); + head_a = Some(Insert(s.subtendril(pos, s.len() as u32 - pos))); head_b = changes_b.next(); } } @@ -425,7 +424,7 @@ impl Transaction { let len = state.doc.len_chars(); let mut acc = Vec::with_capacity(2 * changes.len() + 1); - // TODO: verify ranges are ordered and not overlapping. + // TODO: verify ranges are ordered and not overlapping or change will panic. let mut last = 0; for (from, to, tendril) in changes { @@ -445,7 +444,11 @@ impl Transaction { } last = to; } - acc.push(Operation::Retain(len - last)); + + let span = len - last; + if span > 0 { + acc.push(Operation::Retain(span)); + } Self::from(ChangeSet { changes: acc, len }) } @@ -580,7 +583,7 @@ mod test { let transaction = Transaction::change( &state, // (1, 1, None) is a useless 0-width delete - vec![(6, 11, Some("void".into())), (12, 17, None), (1, 1, None)].into_iter(), + vec![(1, 1, None), (6, 11, Some("void".into())), (12, 17, None)].into_iter(), ); transaction.apply(&mut state); assert_eq!(state.doc, Rope::from_str("hello void! 123")); -- cgit v1.2.3-70-g09d2