@@ -0,0 +1,127 @@
1+use crate::{ChangeSet, Rope, State, Transaction};
3+/// Undo-tree style history store.
5+ revisions: Vec<Revision>,
14+ /// The transaction to revert to previous state.
16+ // selection before, selection after?
19+impl Default for History {
20+ fn default() -> Self {
21+ // Add a dummy root revision with empty transaction
23+ revisions: vec![Revision {
25+ revert: Transaction::from(ChangeSet::new(&Rope::new())),
33+ 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
36+ let revert = transaction.invert(original);
38+ let new_cursor = self.revisions.len();
39+ self.revisions.push(Revision {
43+ self.cursor = new_cursor;
45+ // TODO: child tracking too?
49+ pub fn at_root(&self) -> bool {
53+ pub fn undo(&mut self, state: &mut State) {
55+ // We're at the root of undo, nothing to do.
59+ let current_revision = &self.revisions[self.cursor];
60+ // unimplemented!("{:?}", revision);
61+ // unimplemented!("{:?}", state.doc().len_chars());
62+ // TODO: pass the return value through?
63+ let success = current_revision.revert.apply(state);
66+ panic!("Failed to apply undo!");
69+ self.cursor = current_revision.parent;
72+ pub fn redo(&mut self, state: &mut State) {
73+ let current_revision = &self.revisions[self.cursor];
75+ // TODO: pick the latest child
78+ // panic!("Failed to apply undo!");
90+ fn test_undo_redo() {
91+ let mut history = History::default();
92+ let doc = Rope::from("hello");
93+ let mut state = State::new(doc);
96+ Transaction::change(&state, vec![(5, 5, Some(" world!".into()))].into_iter());
98+ // Need to commit before applying!
99+ history.commit_revision(&transaction1, &state);
100+ transaction1.apply(&mut state);
101+ assert_eq!("hello world!", state.doc());
106+ Transaction::change(&state, vec![(6, 11, Some("世界".into()))].into_iter());
108+ // Need to commit before applying!
109+ history.commit_revision(&transaction2, &state);
110+ transaction2.apply(&mut state);
111+ assert_eq!("hello 世界!", state.doc());
115+ history.undo(&mut state);
116+ assert_eq!("hello world!", state.doc());
117+ history.redo(&mut state);
118+ assert_eq!("hello 世界!", state.doc());
119+ history.undo(&mut state);
120+ history.undo(&mut state);
121+ assert_eq!("hello", state.doc());
123+ // undo at root is a no-op
124+ history.undo(&mut state);
125+ assert_eq!("hello", state.doc());