aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-core/src/history.rs31
-rw-r--r--helix-term/tests/test/commands.rs3
2 files changed, 24 insertions, 10 deletions
diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs
index 5f9fa71e..82509242 100644
--- a/helix-core/src/history.rs
+++ b/helix-core/src/history.rs
@@ -126,16 +126,27 @@ impl History {
match revision.cmp(&self.current) {
Equal => None,
- Greater => self.revisions[self.current + 1..=revision]
- .iter()
- .map(|revision| &revision.inversion)
- .cloned()
- .reduce(|acc, inversion| acc.compose(inversion)),
- Less => self.revisions[revision + 1..=self.current]
- .iter()
- .map(|revision| &revision.transaction)
- .cloned()
- .reduce(|acc, transaction| acc.compose(transaction)),
+ Less => {
+ let mut child = self.revisions[revision].last_child?.get();
+ let mut transaction = self.revisions[child].transaction.clone();
+ while child != self.current {
+ child = self.revisions[child].last_child?.get();
+ transaction = transaction.compose(self.revisions[child].transaction.clone());
+ }
+ Some(transaction)
+ }
+ Greater => {
+ let mut inversion = self.revisions[revision].inversion.clone();
+ let mut parent = self.revisions[revision].parent;
+ while parent != self.current {
+ parent = self.revisions[parent].parent;
+ if parent == 0 {
+ return None;
+ }
+ inversion = inversion.compose(self.revisions[parent].inversion.clone());
+ }
+ Some(inversion)
+ }
}
}
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index 01295704..95bd95b7 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -306,5 +306,8 @@ async fn test_undo_redo() -> anyhow::Result<()> {
// * <C-i> Jump forward to line 1.
test(("#[|]#", "[<space><C-s>kduU<C-o><C-i>", "#[|]#")).await?;
+ // In this case we 'redo' manually to ensure that the transactions are composing correctly.
+ test(("#[|]#", "[<space>u[<space>u", "#[|]#")).await?;
+
Ok(())
}