Fix undo/redo not updating the syntax tree.
This commit is contained in:
parent
b39849dde1
commit
c0e17dd324
|
@ -57,37 +57,31 @@ pub fn at_root(&self) -> bool {
|
|||
self.cursor == 0
|
||||
}
|
||||
|
||||
pub fn undo(&mut self, state: &mut State) {
|
||||
// TODO: I'd like to pass Transaction by reference but it fights with the borrowck
|
||||
|
||||
pub fn undo(&mut self) -> Option<Transaction> {
|
||||
if self.at_root() {
|
||||
// We're at the root of undo, nothing to do.
|
||||
return;
|
||||
return None;
|
||||
}
|
||||
|
||||
let current_revision = &self.revisions[self.cursor];
|
||||
|
||||
// TODO: pass the return value through? It should always succeed
|
||||
let success = current_revision.revert.apply(state);
|
||||
|
||||
if !success {
|
||||
panic!("Failed to apply undo!");
|
||||
}
|
||||
|
||||
self.cursor = current_revision.parent;
|
||||
|
||||
Some(current_revision.revert.clone())
|
||||
}
|
||||
|
||||
pub fn redo(&mut self, state: &mut State) {
|
||||
pub fn redo(&mut self) -> Option<Transaction> {
|
||||
let current_revision = &self.revisions[self.cursor];
|
||||
|
||||
// for now, simply pick the latest child (linear undo / redo)
|
||||
if let Some((index, transaction)) = current_revision.children.last() {
|
||||
let success = transaction.apply(state);
|
||||
|
||||
if !success {
|
||||
panic!("Failed to apply redo!");
|
||||
}
|
||||
|
||||
self.cursor = *index;
|
||||
|
||||
return Some(transaction.clone());
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,17 +114,27 @@ fn test_undo_redo() {
|
|||
assert_eq!("hello 世界!", state.doc());
|
||||
|
||||
// ---
|
||||
fn undo(history: &mut History, state: &mut State) {
|
||||
if let Some(transaction) = history.undo() {
|
||||
transaction.apply(state);
|
||||
}
|
||||
}
|
||||
fn redo(history: &mut History, state: &mut State) {
|
||||
if let Some(transaction) = history.redo() {
|
||||
transaction.apply(state);
|
||||
}
|
||||
}
|
||||
|
||||
history.undo(&mut state);
|
||||
undo(&mut history, &mut state);
|
||||
assert_eq!("hello world!", state.doc());
|
||||
history.redo(&mut state);
|
||||
redo(&mut history, &mut state);
|
||||
assert_eq!("hello 世界!", state.doc());
|
||||
history.undo(&mut state);
|
||||
history.undo(&mut state);
|
||||
undo(&mut history, &mut state);
|
||||
undo(&mut history, &mut state);
|
||||
assert_eq!("hello", state.doc());
|
||||
|
||||
// undo at root is a no-op
|
||||
history.undo(&mut state);
|
||||
undo(&mut history, &mut state);
|
||||
assert_eq!("hello", state.doc());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -509,13 +509,17 @@ pub fn insert_char_prompt(prompt: &mut Prompt, c: char) {
|
|||
// Undo / Redo
|
||||
|
||||
pub fn undo(view: &mut View, _count: usize) {
|
||||
view.doc.history.undo(&mut view.doc.state);
|
||||
if let Some(revert) = view.doc.history.undo() {
|
||||
view.doc.apply(&revert);
|
||||
}
|
||||
|
||||
// TODO: each command could simply return a Option<transaction>, then the higher level handles storing it?
|
||||
}
|
||||
|
||||
pub fn redo(view: &mut View, _count: usize) {
|
||||
view.doc.history.redo(&mut view.doc.state);
|
||||
if let Some(transaction) = view.doc.history.redo() {
|
||||
view.doc.apply(&transaction);
|
||||
}
|
||||
}
|
||||
|
||||
// Yank / Paste
|
||||
|
|
|
@ -108,7 +108,6 @@ pub fn set_language(&mut self, scope: &str, scopes: &[String]) {
|
|||
};
|
||||
}
|
||||
|
||||
// TODO: needs to run on undo/redo
|
||||
pub fn apply(&mut self, transaction: &Transaction) -> bool {
|
||||
let old_doc = self.text().clone();
|
||||
|
||||
|
|
Loading…
Reference in a new issue