on master help sign in
history.redo()
commit04b15466347f3ae25125be081a159511ccbae670 authorBlaž Hrastnik <blaz@mxxn.io> dateMon 5 Oct 2020, 16:12 (6 years ago) parent8c7bc71
1 file changed+23−14
helix-core/src/history.rs+23−14
helix-core/src/history.rs+23−14
@@ -1,16 +1,16 @@
11use crate::{ChangeSet, Rope, State, Transaction};
2+use smallvec::{smallvec, SmallVec};
23
34/// Undo-tree style history store.
45pub struct History {
56 revisions: Vec<Revision>,
67 cursor: usize,
7− //
88}
99
1010#[derive(Debug)]
1111struct Revision {
12− // prev: usize,
1312 parent: usize,
13+ children: SmallVec<[(usize, Transaction); 1]>,
1414 /// The transaction to revert to previous state.
1515 revert: Transaction,
1616 // selection before, selection after?
@@ -22,6 +22,7 @@ impl Default for History {
2222 Self {
2323 revisions: vec![Revision {
2424 parent: 0,
25+ children: SmallVec::new(),
2526 revert: Transaction::from(ChangeSet::new(&Rope::new())),
2627 }],
2728 cursor: 0,
@@ -31,18 +32,24 @@ impl Default for History {
3132
3233impl History {
3334 pub fn commit_revision(&mut self, transaction: &Transaction, original: &State) {
34− // TODO: store both directions
35− // TODO: could store a single set if deletes also stored the text they delete
35+ // TODO: could store a single transaction, if deletes also stored the text they delete
3636 let revert = transaction.invert(original);
3737
3838 let new_cursor = self.revisions.len();
3939 self.revisions.push(Revision {
4040 parent: self.cursor,
41+ children: SmallVec::new(),
4142 revert,
4243 });
43− self.cursor = new_cursor;
4444
45− // TODO: child tracking too?
45+ // add a reference to the parent
46+ self.revisions
47+ .get_mut(self.cursor)
48+ .unwrap() // TODO: get_unchecked_mut
49+ .children
50+ .push((new_cursor, transaction.clone()));
51+
52+ self.cursor = new_cursor;
4653 }
4754
4855 #[inline]
@@ -57,9 +64,8 @@ impl History {
5764 }
5865
5966 let current_revision = &self.revisions[self.cursor];
60− // unimplemented!("{:?}", revision);
61− // unimplemented!("{:?}", state.doc().len_chars());
62− // TODO: pass the return value through?
67+
68+ // TODO: pass the return value through? It should always succeed
6369 let success = current_revision.revert.apply(state);
6470
6571 if !success {
@@ -72,13 +78,16 @@ impl History {
7278 pub fn redo(&mut self, state: &mut State) {
7379 let current_revision = &self.revisions[self.cursor];
7480
75− // TODO: pick the latest child
81+ // for now, simply pick the latest child (linear undo / redo)
82+ if let Some((index, transaction)) = current_revision.children.last() {
83+ let success = transaction.apply(state);
7684
77− // if !success {
78− // panic!("Failed to apply undo!");
79− // }
85+ if !success {
86+ panic!("Failed to apply redo!");
87+ }
8088
81− unimplemented!()
89+ self.cursor = *index;
90+ }
8291 }
8392}
8493