@@ -23,13 +23,14 @@ impl History {
23
23
pub ( crate ) fn new ( limit : u32 ) -> Self {
24
24
Self {
25
25
redo_history : VecDeque :: new ( ) ,
26
- undo_history : VecDeque :: new ( ) ,
26
+ undo_history : VecDeque :: from ( [ HistoryItem :: new_load ( ) ] ) ,
27
27
limit : limit. try_into ( ) . expect ( "History limit is too large" ) ,
28
28
}
29
29
}
30
30
31
31
pub ( crate ) fn apply_operation ( lines : & mut Vec < Line > , operation : & HistoryItem ) -> HistoryItem {
32
32
match operation. operation {
33
+ Operation :: Load => HistoryItem :: new_load ( ) ,
33
34
Operation :: Modify => {
34
35
let range = if operation. end_index <= operation. start_index {
35
36
operation. end_index ..=operation. start_index
@@ -73,32 +74,40 @@ impl History {
73
74
}
74
75
}
75
76
76
- pub ( crate ) fn undo ( & mut self , current : & mut Vec < Line > ) -> Option < ( usize , usize ) > {
77
- self . undo_history . pop_back ( ) . map ( |operation| {
78
- let history = Self :: apply_operation ( current, & operation) ;
77
+ pub ( crate ) fn undo ( & mut self , current : & mut Vec < Line > ) -> Option < ( Operation , usize , usize ) > {
78
+ self . undo_history . pop_back ( ) . map ( |history_item| {
79
+ let history = Self :: apply_operation ( current, & history_item) ;
80
+ // do not remove load operation from undo history, as it acts as a sentinel value
81
+ if history. operation == Operation :: Load {
82
+ self . undo_history . push_back ( history_item) ;
83
+ return ( history. operation , history. start_index , history. end_index ) ;
84
+ }
79
85
let update_range = Self :: get_last_index_range ( & history, current. len ( ) ) ;
80
86
self . redo_history . push_back ( history) ;
81
- update_range
87
+ ( history_item . operation , update_range. 0 , update_range . 1 )
82
88
} )
83
89
}
84
90
85
- pub ( crate ) fn redo ( & mut self , current : & mut Vec < Line > ) -> Option < ( usize , usize ) > {
86
- self . redo_history . pop_back ( ) . map ( |operation| {
87
- let history = Self :: apply_operation ( current, & operation) ;
91
+ pub ( crate ) fn redo ( & mut self , current : & mut Vec < Line > ) -> Option < ( Operation , usize , usize ) > {
92
+ self . redo_history . pop_back ( ) . map ( |history_item| {
93
+ // the load operation is not handled here, as it is in `undo` because the load operation should never be
94
+ // added to the redo history
95
+ let history = Self :: apply_operation ( current, & history_item) ;
88
96
let update_range = Self :: get_last_index_range ( & history, current. len ( ) ) ;
89
97
self . undo_history . push_back ( history) ;
90
- update_range
98
+ ( history_item . operation , update_range. 0 , update_range . 1 )
91
99
} )
92
100
}
93
101
94
102
pub ( crate ) fn reset ( & mut self ) {
95
103
self . undo_history . clear ( ) ;
104
+ self . undo_history . push_back ( HistoryItem :: new_load ( ) ) ;
96
105
self . redo_history . clear ( ) ;
97
106
}
98
107
99
108
fn get_last_index_range ( history_item : & HistoryItem , list_length : usize ) -> ( usize , usize ) {
100
109
match history_item. operation {
101
- Operation :: Add | Operation :: Modify => ( history_item. start_index , history_item. end_index ) ,
110
+ Operation :: Add | Operation :: Modify | Operation :: Load => ( history_item. start_index , history_item. end_index ) ,
102
111
Operation :: Remove => {
103
112
let index = min ( history_item. start_index , history_item. end_index ) ;
104
113
if index == 0 || list_length == 0 {
0 commit comments