on master help sign in
Fix undo/redo not updating the syntax tree.
c0e17ddBlaž Hrastnik
helix-core/src/history.rs+25−21
@@ -57,37 +57,31 @@ impl History {
57 self.cursor == 0
57 self.cursor == 0
58 }
58 }
59
59
60+ // TODO: I'd like to pass Transaction by reference but it fights with the borrowck
61+
60− pub fn undo(&mut self, state: &mut State) {
62+ pub fn undo(&mut self) -> Option<Transaction> {
61 if self.at_root() {
63 if self.at_root() {
62 // We're at the root of undo, nothing to do.
64 // We're at the root of undo, nothing to do.
63− return;
65+ return None;
64 }
66 }
65
67
66 let current_revision = &self.revisions[self.cursor];
68 let current_revision = &self.revisions[self.cursor];
67
69
68− // TODO: pass the return value through? It should always succeed
69− let success = current_revision.revert.apply(state);
70−
71− if !success {
72− panic!("Failed to apply undo!");
73− }
74−
75 self.cursor = current_revision.parent;
70 self.cursor = current_revision.parent;
71+
72+ Some(current_revision.revert.clone())
76 }
73 }
77
74
78− pub fn redo(&mut self, state: &mut State) {
75+ pub fn redo(&mut self) -> Option<Transaction> {
79 let current_revision = &self.revisions[self.cursor];
76 let current_revision = &self.revisions[self.cursor];
80
77
81 // for now, simply pick the latest child (linear undo / redo)
78 // for now, simply pick the latest child (linear undo / redo)
82 if let Some((index, transaction)) = current_revision.children.last() {
79 if let Some((index, transaction)) = current_revision.children.last() {
83− let success = transaction.apply(state);
84−
85− if !success {
86− panic!("Failed to apply redo!");
87− }
88−
89 self.cursor = *index;
80 self.cursor = *index;
81+
82+ return Some(transaction.clone());
90 }
83 }
84+ None
91 }
85 }
92}
86}
93
87
@@ -120,17 +114,27 @@ mod test {
120 assert_eq!("hello 世界!", state.doc());
114 assert_eq!("hello 世界!", state.doc());
121
115
122 // ---
116 // ---
117+ fn undo(history: &mut History, state: &mut State) {
118+ if let Some(transaction) = history.undo() {
119+ transaction.apply(state);
120+ }
121+ }
122+ fn redo(history: &mut History, state: &mut State) {
123+ if let Some(transaction) = history.redo() {
124+ transaction.apply(state);
125+ }
126+ }
123
127
124− history.undo(&mut state);
128+ undo(&mut history, &mut state);
125 assert_eq!("hello world!", state.doc());
129 assert_eq!("hello world!", state.doc());
126− history.redo(&mut state);
130+ redo(&mut history, &mut state);
127 assert_eq!("hello 世界!", state.doc());
131 assert_eq!("hello 世界!", state.doc());
128− history.undo(&mut state);
132+ undo(&mut history, &mut state);
129− history.undo(&mut state);
133+ undo(&mut history, &mut state);
130 assert_eq!("hello", state.doc());
134 assert_eq!("hello", state.doc());
131
135
132 // undo at root is a no-op
136 // undo at root is a no-op
133− history.undo(&mut state);
137+ undo(&mut history, &mut state);
134 assert_eq!("hello", state.doc());
138 assert_eq!("hello", state.doc());
135 }
139 }
136}
140}
helix-view/src/commands.rs+6−2
@@ -509,13 +509,17 @@ pub fn insert_char_prompt(prompt: &mut Prompt, c: char) {
509// Undo / Redo
509// Undo / Redo
510
510
511pub fn undo(view: &mut View, _count: usize) {
511pub fn undo(view: &mut View, _count: usize) {
512− view.doc.history.undo(&mut view.doc.state);
512+ if let Some(revert) = view.doc.history.undo() {
513+ view.doc.apply(&revert);
514+ }
513
515
514 // TODO: each command could simply return a Option<transaction>, then the higher level handles storing it?
516 // TODO: each command could simply return a Option<transaction>, then the higher level handles storing it?
515}
517}
516
518
517pub fn redo(view: &mut View, _count: usize) {
519pub fn redo(view: &mut View, _count: usize) {
518− view.doc.history.redo(&mut view.doc.state);
520+ if let Some(transaction) = view.doc.history.redo() {
521+ view.doc.apply(&transaction);
522+ }
519}
523}
520
524
521// Yank / Paste
525// Yank / Paste
helix-view/src/document.rs−1
@@ -108,7 +108,6 @@ impl Document {
108 };
108 };
109 }
109 }
110
110
111− // TODO: needs to run on undo/redo
112 pub fn apply(&mut self, transaction: &Transaction) -> bool {
111 pub fn apply(&mut self, transaction: &Transaction) -> bool {
113 let old_doc = self.text().clone();
112 let old_doc = self.text().clone();
114
113