aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Davis2022-11-23 19:02:00 +0000
committerBlaž Hrastnik2022-11-24 01:57:12 +0000
commita3f321a531554b51160f3fe7e6da1c269030f3b6 (patch)
tree7db59452f9db54ef9f04840eb048abf38c504d44
parent4a103db6228ba54e0f36bbebb95d25867458f473 (diff)
Follow parent links when calculating changes since a revision
The 'revisions' field on History can't be treated as linear: each Revision in the revisions Vec has a parent link and an optional child link. We can follow those to unroll the recent history.
-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(())
}