Maintain a different undo/redo stack in MultiBuffer

This only applies to singleton mode.
This commit is contained in:
Antonio Scandurra 2021-12-14 17:43:41 +01:00
parent 523cbe781b
commit 08e9f3e1e3
3 changed files with 345 additions and 22 deletions

View file

@ -240,6 +240,17 @@ impl History {
}
}
fn remove_from_undo(&mut self, transaction_id: TransactionId) -> Option<&Transaction> {
assert_eq!(self.transaction_depth, 0);
if let Some(transaction_ix) = self.undo_stack.iter().rposition(|t| t.id == transaction_id) {
let transaction = self.undo_stack.remove(transaction_ix);
self.redo_stack.push(transaction);
self.redo_stack.last()
} else {
None
}
}
fn pop_redo(&mut self) -> Option<&Transaction> {
assert_eq!(self.transaction_depth, 0);
if let Some(transaction) = self.redo_stack.pop() {
@ -249,6 +260,17 @@ impl History {
None
}
}
fn remove_from_redo(&mut self, transaction_id: TransactionId) -> Option<&Transaction> {
assert_eq!(self.transaction_depth, 0);
if let Some(transaction_ix) = self.redo_stack.iter().rposition(|t| t.id == transaction_id) {
let transaction = self.redo_stack.remove(transaction_ix);
self.undo_stack.push(transaction);
self.undo_stack.last()
} else {
None
}
}
}
#[derive(Clone, Default, Debug)]
@ -1108,6 +1130,15 @@ impl Buffer {
}
}
pub fn undo_transaction(&mut self, transaction_id: TransactionId) -> Option<Operation> {
if let Some(transaction) = self.history.remove_from_undo(transaction_id).cloned() {
let op = self.undo_or_redo(transaction).unwrap();
Some(op)
} else {
None
}
}
pub fn redo(&mut self) -> Option<(TransactionId, Operation)> {
if let Some(transaction) = self.history.pop_redo().cloned() {
let transaction_id = transaction.id;
@ -1118,6 +1149,15 @@ impl Buffer {
}
}
pub fn redo_transaction(&mut self, transaction_id: TransactionId) -> Option<Operation> {
if let Some(transaction) = self.history.remove_from_redo(transaction_id).cloned() {
let op = self.undo_or_redo(transaction).unwrap();
Some(op)
} else {
None
}
}
fn undo_or_redo(&mut self, transaction: Transaction) -> Result<Operation> {
let mut counts = HashMap::default();
for edit_id in transaction.edits {