From f35c419f432ea85f657b5ffaf5d536e04ddc029c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 10 Dec 2021 18:08:26 -0700 Subject: [PATCH] Return optional transaction ids from undo/redo This will allow the editor to restore selections that it associated with the start or end of a transaction. --- crates/editor/src/multi_buffer.rs | 4 ++-- crates/language/src/buffer.rs | 28 ++++++++++++++++++---------- crates/text/src/text.rs | 18 ++++++++++++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/crates/editor/src/multi_buffer.rs b/crates/editor/src/multi_buffer.rs index cc1425f1cf7d4aa7bdc5f3a6ffa48ddb78fb4e5a..8163a7bd23554aae8a35843d374820c71130411f 100644 --- a/crates/editor/src/multi_buffer.rs +++ b/crates/editor/src/multi_buffer.rs @@ -224,14 +224,14 @@ impl MultiBuffer { }) } - pub fn undo(&mut self, cx: &mut ModelContext) { + pub fn undo(&mut self, cx: &mut ModelContext) -> Option { // TODO self.as_singleton() .unwrap() .update(cx, |buffer, cx| buffer.undo(cx)) } - pub fn redo(&mut self, cx: &mut ModelContext) { + pub fn redo(&mut self, cx: &mut ModelContext) -> Option { // TODO self.as_singleton() .unwrap() diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index ddeb5328cbb430a7f28e9623e60dfa85ba0f674d..1830e49bf76d7a96a1822a748bcf15e939a7d8cf 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -1443,26 +1443,34 @@ impl Buffer { cx.notify(); } - pub fn undo(&mut self, cx: &mut ModelContext) { + pub fn undo(&mut self, cx: &mut ModelContext) -> Option { let was_dirty = self.is_dirty(); let old_version = self.version.clone(); - for operation in self.text.undo() { - self.send_operation(Operation::Buffer(operation), cx); + if let Some((transaction_id, operations)) = self.text.undo() { + for operation in operations { + self.send_operation(Operation::Buffer(operation), cx); + } + self.did_edit(&old_version, was_dirty, cx); + Some(transaction_id) + } else { + None } - - self.did_edit(&old_version, was_dirty, cx); } - pub fn redo(&mut self, cx: &mut ModelContext) { + pub fn redo(&mut self, cx: &mut ModelContext) -> Option { let was_dirty = self.is_dirty(); let old_version = self.version.clone(); - for operation in self.text.redo() { - self.send_operation(Operation::Buffer(operation), cx); + if let Some((transaction_id, operations)) = self.text.redo() { + for operation in operations { + self.send_operation(Operation::Buffer(operation), cx); + } + self.did_edit(&old_version, was_dirty, cx); + Some(transaction_id) + } else { + None } - - self.did_edit(&old_version, was_dirty, cx); } } diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index a8eb32888f39c0abf1f185613d7f30dd88bbd6f7..525cbc43662a03af9eadec7b5ea868a6d3c8a1e4 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1221,28 +1221,34 @@ impl Buffer { self.history.ops.values() } - pub fn undo(&mut self) -> Vec { - let mut ops = Vec::new(); + pub fn undo(&mut self) -> Option<(TransactionId, Vec)> { if let Some(transaction) = self.history.pop_undo().cloned() { + let transaction_id = transaction.id; let selections = transaction.selections_before.clone(); + let mut ops = Vec::new(); ops.push(self.undo_or_redo(transaction).unwrap()); for (set_id, selections) in selections { ops.extend(self.restore_selection_set(set_id, selections)); } + Some((transaction_id, ops)) + } else { + None } - ops } - pub fn redo(&mut self) -> Vec { - let mut ops = Vec::new(); + pub fn redo(&mut self) -> Option<(TransactionId, Vec)> { if let Some(transaction) = self.history.pop_redo().cloned() { + let transaction_id = transaction.id; let selections = transaction.selections_after.clone(); + let mut ops = Vec::new(); ops.push(self.undo_or_redo(transaction).unwrap()); for (set_id, selections) in selections { ops.extend(self.restore_selection_set(set_id, selections)); } + Some((transaction_id, ops)) + } else { + None } - ops } fn undo_or_redo(&mut self, transaction: Transaction) -> Result {