Skip to content

Commit

Permalink
Apply inversions to Views on undo/redo
Browse files Browse the repository at this point in the history
When using undo/redo, the history revision can be decremented. In that
case we should apply the inversions since the given revision in
History::changes_since. This prevents panics with jumplist operations
when a session uses undo/redo to move the jumplist selection outside
of the document.
  • Loading branch information
the-mikedavis committed Nov 23, 2022
1 parent 8e62264 commit 8e49f7a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
24 changes: 14 additions & 10 deletions helix-core/src/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,21 @@ impl History {
/// Returns the changes since the given revision composed into a transaction.
/// Returns None if there are no changes between the current and given revisions.
pub fn changes_since(&self, revision: usize) -> Option<Transaction> {
if self.at_root() || self.current >= revision {
return None;
if revision == self.current {
None
} else if revision > self.current {
self.revisions[self.current..revision]
.iter()
.map(|revision| &revision.inversion)
.cloned()
.reduce(|acc, inversion| acc.compose(inversion))
} else {
self.revisions[revision + 1..=self.current]
.iter()
.map(|revision| &revision.transaction)
.cloned()
.reduce(|acc, transaction| acc.compose(transaction))
}

// The bounds are checked in the if condition above:
// `revision` is known to be `< self.current`.
self.revisions[revision..self.current]
.iter()
.map(|revision| &revision.transaction)
.cloned()
.reduce(|acc, transaction| acc.compose(transaction))
}

/// Undo the last edit.
Expand Down
2 changes: 1 addition & 1 deletion helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,7 @@ impl Component for EditorView {
// If the current document has been changed, apply the changes to all views.
// This ensures that selections in jumplists follow changes.
if doc.id() == original_doc_id
&& doc.get_current_revision() > original_doc_revision
&& doc.get_current_revision() != original_doc_revision
{
if let Some(transaction) =
doc.history.get_mut().changes_since(original_doc_revision)
Expand Down

0 comments on commit 8e49f7a

Please sign in to comment.