Skip to content

Commit

Permalink
Follow parent links when calculating changes since a revision
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
the-mikedavis committed Nov 23, 2022
1 parent 2c83569 commit a617261
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
31 changes: 21 additions & 10 deletions helix-core/src/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions helix-term/tests/test/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}

0 comments on commit a617261

Please sign in to comment.