From 93eb005f74d31ae0b1d805da7fc0c67774884ddd Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 10 Feb 2022 09:26:20 -0700 Subject: [PATCH] Correctly redo all undone edits after undoing in multi-buffer When undoing edits performed in the multi-buffer, we also undo subsequent edits that may have occurred outside of the multi-buffer. This commit makes us redo those edits as well. Co-Authored-By: Antonio Scandurra --- crates/editor/src/multi_buffer.rs | 28 ++++++++++++++++++---------- crates/text/src/text.rs | 8 ++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index ed3d67f8b3..acc7b22183 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -557,10 +557,14 @@ impl MultiBuffer { while let Some(transaction) = self.history.pop_undo() { let mut undone = false; - for (buffer_id, buffer_transaction_id) in &transaction.buffer_transactions { + for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions { if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) { - undone |= buffer.update(cx, |buf, cx| { - buf.undo_to_transaction(*buffer_transaction_id, cx) + undone |= buffer.update(cx, |buffer, cx| { + let undo_to = *buffer_transaction_id; + if let Some(entry) = buffer.peek_undo_stack() { + *buffer_transaction_id = entry.transaction_id(); + } + buffer.undo_to_transaction(undo_to, cx) }); } } @@ -580,10 +584,14 @@ impl MultiBuffer { while let Some(transaction) = self.history.pop_redo() { let mut redone = false; - for (buffer_id, buffer_transaction_id) in &transaction.buffer_transactions { + for (buffer_id, buffer_transaction_id) in &mut transaction.buffer_transactions { if let Some(BufferState { buffer, .. }) = self.buffers.borrow().get(&buffer_id) { - redone |= buffer.update(cx, |buf, cx| { - buf.redo_to_transaction(*buffer_transaction_id, cx) + redone |= buffer.update(cx, |buffer, cx| { + let redo_to = *buffer_transaction_id; + if let Some(entry) = buffer.peek_redo_stack() { + *buffer_transaction_id = entry.transaction_id(); + } + buffer.redo_to_transaction(redo_to, cx) }); } } @@ -2274,21 +2282,21 @@ impl History { } } - fn pop_undo(&mut self) -> Option<&Transaction> { + fn pop_undo(&mut self) -> Option<&mut Transaction> { assert_eq!(self.transaction_depth, 0); if let Some(transaction) = self.undo_stack.pop() { self.redo_stack.push(transaction); - self.redo_stack.last() + self.redo_stack.last_mut() } else { None } } - fn pop_redo(&mut self) -> Option<&Transaction> { + fn pop_redo(&mut self) -> Option<&mut Transaction> { assert_eq!(self.transaction_depth, 0); if let Some(transaction) = self.redo_stack.pop() { self.undo_stack.push(transaction); - self.undo_stack.last() + self.undo_stack.last_mut() } else { None } diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index 20f0e422c8..9b7f8dd230 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -84,6 +84,10 @@ pub struct Transaction { } impl HistoryEntry { + pub fn transaction_id(&self) -> TransactionId { + self.transaction.id + } + fn push_edit(&mut self, edit: &EditOperation) { self.transaction.edit_ids.push(edit.timestamp.local()); self.transaction.end.observe(edit.timestamp.local()); @@ -1150,6 +1154,10 @@ impl Buffer { self.history.undo_stack.last() } + pub fn peek_redo_stack(&self) -> Option<&HistoryEntry> { + self.history.redo_stack.last() + } + pub fn start_transaction(&mut self) -> Option { self.start_transaction_at(Instant::now()) }