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.
This commit is contained in:
Michael Davis 2022-11-23 13:02:00 -06:00 committed by Blaž Hrastnik
parent 4a103db622
commit a3f321a531
2 changed files with 24 additions and 10 deletions

View file

@ -126,16 +126,27 @@ impl History {
match revision.cmp(&self.current) { match revision.cmp(&self.current) {
Equal => None, Equal => None,
Greater => self.revisions[self.current + 1..=revision] Less => {
.iter() let mut child = self.revisions[revision].last_child?.get();
.map(|revision| &revision.inversion) let mut transaction = self.revisions[child].transaction.clone();
.cloned() while child != self.current {
.reduce(|acc, inversion| acc.compose(inversion)), child = self.revisions[child].last_child?.get();
Less => self.revisions[revision + 1..=self.current] transaction = transaction.compose(self.revisions[child].transaction.clone());
.iter() }
.map(|revision| &revision.transaction) Some(transaction)
.cloned() }
.reduce(|acc, transaction| acc.compose(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)
}
} }
} }

View file

@ -306,5 +306,8 @@ async fn test_undo_redo() -> anyhow::Result<()> {
// * <C-i> Jump forward to line 1. // * <C-i> Jump forward to line 1.
test(("#[|]#", "[<space><C-s>kduU<C-o><C-i>", "#[|]#")).await?; 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(()) Ok(())
} }