diff options
author | Michael Davis | 2022-11-23 19:02:00 +0000 |
---|---|---|
committer | Blaž Hrastnik | 2022-11-24 01:57:12 +0000 |
commit | a3f321a531554b51160f3fe7e6da1c269030f3b6 (patch) | |
tree | 7db59452f9db54ef9f04840eb048abf38c504d44 | |
parent | 4a103db6228ba54e0f36bbebb95d25867458f473 (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.rs | 31 | ||||
-rw-r--r-- | helix-term/tests/test/commands.rs | 3 |
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(()) } |