Simplify undo_to_transaction
and redo_to_transaction
We don't need to mutate the history anymore now that we render pending renames with a block decoration.
This commit is contained in:
parent
b573a39cbc
commit
cf7cc83f85
4 changed files with 29 additions and 141 deletions
|
@ -27,7 +27,6 @@ use text::{
|
||||||
AnchorRangeExt as _, Edit, Point, PointUtf16, TextSummary,
|
AnchorRangeExt as _, Edit, Point, PointUtf16, TextSummary,
|
||||||
};
|
};
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use util::CowMut;
|
|
||||||
|
|
||||||
const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize];
|
const NEWLINES: &'static [u8] = &[b'\n'; u8::MAX as usize];
|
||||||
|
|
||||||
|
@ -566,7 +565,7 @@ impl MultiBuffer {
|
||||||
if let Some(entry) = buffer.peek_undo_stack() {
|
if let Some(entry) = buffer.peek_undo_stack() {
|
||||||
*buffer_transaction_id = entry.transaction_id();
|
*buffer_transaction_id = entry.transaction_id();
|
||||||
}
|
}
|
||||||
buffer.undo_to_transaction(undo_to, true, cx)
|
buffer.undo_to_transaction(undo_to, cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -579,35 +578,6 @@ impl MultiBuffer {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo_to_transaction(
|
|
||||||
&mut self,
|
|
||||||
transaction_id: TransactionId,
|
|
||||||
push_redo: bool,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) -> bool {
|
|
||||||
if let Some(buffer) = self.as_singleton() {
|
|
||||||
return buffer.update(cx, |buffer, cx| {
|
|
||||||
buffer.undo_to_transaction(transaction_id, push_redo, cx)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut undone = false;
|
|
||||||
for transaction in &mut *self.history.remove_from_undo(transaction_id, push_redo) {
|
|
||||||
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, |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, true, cx)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
undone
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn redo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
|
pub fn redo(&mut self, cx: &mut ModelContext<Self>) -> Option<TransactionId> {
|
||||||
if let Some(buffer) = self.as_singleton() {
|
if let Some(buffer) = self.as_singleton() {
|
||||||
return buffer.update(cx, |buffer, cx| buffer.redo(cx));
|
return buffer.update(cx, |buffer, cx| buffer.redo(cx));
|
||||||
|
@ -622,7 +592,7 @@ impl MultiBuffer {
|
||||||
if let Some(entry) = buffer.peek_redo_stack() {
|
if let Some(entry) = buffer.peek_redo_stack() {
|
||||||
*buffer_transaction_id = entry.transaction_id();
|
*buffer_transaction_id = entry.transaction_id();
|
||||||
}
|
}
|
||||||
buffer.redo_to_transaction(redo_to, true, cx)
|
buffer.redo_to_transaction(redo_to, cx)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2345,31 +2315,6 @@ impl History {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_from_undo(
|
|
||||||
&mut self,
|
|
||||||
transaction_id: TransactionId,
|
|
||||||
push_redo: bool,
|
|
||||||
) -> CowMut<[Transaction]> {
|
|
||||||
assert_eq!(self.transaction_depth, 0);
|
|
||||||
|
|
||||||
if let Some(entry_ix) = self
|
|
||||||
.undo_stack
|
|
||||||
.iter()
|
|
||||||
.rposition(|transaction| transaction.id == transaction_id)
|
|
||||||
{
|
|
||||||
let transactions = self.undo_stack.drain(entry_ix..).rev();
|
|
||||||
if push_redo {
|
|
||||||
let redo_stack_start_len = self.redo_stack.len();
|
|
||||||
self.redo_stack.extend(transactions);
|
|
||||||
CowMut::Borrowed(&mut self.redo_stack[redo_stack_start_len..])
|
|
||||||
} else {
|
|
||||||
CowMut::Owned(transactions.collect())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
CowMut::Owned(Default::default())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pop_redo(&mut self) -> Option<&mut Transaction> {
|
fn pop_redo(&mut self) -> Option<&mut Transaction> {
|
||||||
assert_eq!(self.transaction_depth, 0);
|
assert_eq!(self.transaction_depth, 0);
|
||||||
if let Some(transaction) = self.redo_stack.pop() {
|
if let Some(transaction) = self.redo_stack.pop() {
|
||||||
|
|
|
@ -1738,13 +1738,12 @@ impl Buffer {
|
||||||
pub fn undo_to_transaction(
|
pub fn undo_to_transaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
transaction_id: TransactionId,
|
transaction_id: TransactionId,
|
||||||
push_redo: bool,
|
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let was_dirty = self.is_dirty();
|
let was_dirty = self.is_dirty();
|
||||||
let old_version = self.version.clone();
|
let old_version = self.version.clone();
|
||||||
|
|
||||||
let operations = self.text.undo_to_transaction(transaction_id, push_redo);
|
let operations = self.text.undo_to_transaction(transaction_id);
|
||||||
let undone = !operations.is_empty();
|
let undone = !operations.is_empty();
|
||||||
for operation in operations {
|
for operation in operations {
|
||||||
self.send_operation(Operation::Buffer(operation), cx);
|
self.send_operation(Operation::Buffer(operation), cx);
|
||||||
|
@ -1771,13 +1770,12 @@ impl Buffer {
|
||||||
pub fn redo_to_transaction(
|
pub fn redo_to_transaction(
|
||||||
&mut self,
|
&mut self,
|
||||||
transaction_id: TransactionId,
|
transaction_id: TransactionId,
|
||||||
push_undo: bool,
|
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let was_dirty = self.is_dirty();
|
let was_dirty = self.is_dirty();
|
||||||
let old_version = self.version.clone();
|
let old_version = self.version.clone();
|
||||||
|
|
||||||
let operations = self.text.redo_to_transaction(transaction_id, push_undo);
|
let operations = self.text.redo_to_transaction(transaction_id);
|
||||||
let redone = !operations.is_empty();
|
let redone = !operations.is_empty();
|
||||||
for operation in operations {
|
for operation in operations {
|
||||||
self.send_operation(Operation::Buffer(operation), cx);
|
self.send_operation(Operation::Buffer(operation), cx);
|
||||||
|
|
|
@ -285,31 +285,19 @@ impl History {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_from_undo(
|
fn remove_from_undo(&mut self, transaction_id: TransactionId) -> &[HistoryEntry] {
|
||||||
&mut self,
|
|
||||||
transaction_id: TransactionId,
|
|
||||||
push_redo: bool,
|
|
||||||
) -> Vec<Transaction> {
|
|
||||||
assert_eq!(self.transaction_depth, 0);
|
assert_eq!(self.transaction_depth, 0);
|
||||||
|
|
||||||
let mut transactions = Vec::new();
|
let redo_stack_start_len = self.redo_stack.len();
|
||||||
if let Some(entry_ix) = self
|
if let Some(entry_ix) = self
|
||||||
.undo_stack
|
.undo_stack
|
||||||
.iter()
|
.iter()
|
||||||
.rposition(|entry| entry.transaction.id == transaction_id)
|
.rposition(|entry| entry.transaction.id == transaction_id)
|
||||||
{
|
{
|
||||||
transactions.extend(
|
self.redo_stack
|
||||||
self.undo_stack[entry_ix..]
|
.extend(self.undo_stack.drain(entry_ix..).rev());
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.map(|entry| entry.transaction.clone()),
|
|
||||||
);
|
|
||||||
let transactions = self.undo_stack.drain(entry_ix..).rev();
|
|
||||||
if push_redo {
|
|
||||||
self.redo_stack.extend(transactions);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
transactions
|
&self.redo_stack[redo_stack_start_len..]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forget(&mut self, transaction_id: TransactionId) {
|
fn forget(&mut self, transaction_id: TransactionId) {
|
||||||
|
@ -339,31 +327,19 @@ impl History {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_from_redo(
|
fn remove_from_redo(&mut self, transaction_id: TransactionId) -> &[HistoryEntry] {
|
||||||
&mut self,
|
|
||||||
transaction_id: TransactionId,
|
|
||||||
push_undo: bool,
|
|
||||||
) -> Vec<Transaction> {
|
|
||||||
assert_eq!(self.transaction_depth, 0);
|
assert_eq!(self.transaction_depth, 0);
|
||||||
|
|
||||||
let mut transactions = Vec::new();
|
let undo_stack_start_len = self.undo_stack.len();
|
||||||
if let Some(entry_ix) = self
|
if let Some(entry_ix) = self
|
||||||
.redo_stack
|
.redo_stack
|
||||||
.iter()
|
.iter()
|
||||||
.rposition(|entry| entry.transaction.id == transaction_id)
|
.rposition(|entry| entry.transaction.id == transaction_id)
|
||||||
{
|
{
|
||||||
transactions.extend(
|
self.undo_stack
|
||||||
self.redo_stack[entry_ix..]
|
.extend(self.redo_stack.drain(entry_ix..).rev());
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.map(|entry| entry.transaction.clone()),
|
|
||||||
);
|
|
||||||
if push_undo {
|
|
||||||
self.undo_stack
|
|
||||||
.extend(self.redo_stack.drain(entry_ix..).rev());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
transactions
|
&self.undo_stack[undo_stack_start_len..]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1239,12 +1215,13 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo_to_transaction(
|
pub fn undo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec<Operation> {
|
||||||
&mut self,
|
let transactions = self
|
||||||
transaction_id: TransactionId,
|
.history
|
||||||
push_redo: bool,
|
.remove_from_undo(transaction_id)
|
||||||
) -> Vec<Operation> {
|
.iter()
|
||||||
let transactions = self.history.remove_from_undo(transaction_id, push_redo);
|
.map(|entry| entry.transaction.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
transactions
|
transactions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|transaction| self.undo_or_redo(transaction).unwrap())
|
.map(|transaction| self.undo_or_redo(transaction).unwrap())
|
||||||
|
@ -1266,12 +1243,13 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn redo_to_transaction(
|
pub fn redo_to_transaction(&mut self, transaction_id: TransactionId) -> Vec<Operation> {
|
||||||
&mut self,
|
let transactions = self
|
||||||
transaction_id: TransactionId,
|
.history
|
||||||
push_undo: bool,
|
.remove_from_redo(transaction_id)
|
||||||
) -> Vec<Operation> {
|
.iter()
|
||||||
let transactions = self.history.remove_from_redo(transaction_id, push_undo);
|
.map(|entry| entry.transaction.clone())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
transactions
|
transactions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|transaction| self.undo_or_redo(transaction).unwrap())
|
.map(|transaction| self.undo_or_redo(transaction).unwrap())
|
||||||
|
|
|
@ -3,9 +3,8 @@ pub mod test;
|
||||||
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Borrow, BorrowMut},
|
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
ops::{AddAssign, Deref, DerefMut},
|
ops::AddAssign,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
};
|
};
|
||||||
|
@ -124,38 +123,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CowMut<'a, T: ?Sized + ToOwned> {
|
|
||||||
Borrowed(&'a mut T),
|
|
||||||
Owned(T::Owned),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Deref for CowMut<'a, T>
|
|
||||||
where
|
|
||||||
T: ?Sized + ToOwned,
|
|
||||||
{
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
match self {
|
|
||||||
CowMut::Borrowed(value) => value,
|
|
||||||
CowMut::Owned(value) => value.borrow(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> DerefMut for CowMut<'a, T>
|
|
||||||
where
|
|
||||||
T: ?Sized + ToOwned,
|
|
||||||
T::Owned: BorrowMut<T>,
|
|
||||||
{
|
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
||||||
match self {
|
|
||||||
CowMut::Borrowed(value) => value,
|
|
||||||
CowMut::Owned(value) => value.borrow_mut(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue