mirror of
https://github.com/helix-editor/helix.git
synced 2024-09-11 18:58:00 +03:00
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:
parent
4a103db622
commit
a3f321a531
@ -126,16 +126,27 @@ pub fn changes_since(&self, revision: usize) -> Option<Transaction> {
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user