Skip to content

Commit 2bf09e1

Browse files
committed
Add Operation::Load to History
Add to the todo_file History a load operation tracker, that will acts as a sentinel value for the start of the undo history queue. This will enable hooking into the start of the history queue. In order to expose the additional information, the Operation is now returned from the History undo/redo methods.
1 parent f8262b5 commit 2bf09e1

File tree

5 files changed

+174
-84
lines changed

5 files changed

+174
-84
lines changed

src/todo_file/src/history/history_item.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ pub(crate) struct HistoryItem {
99
}
1010

1111
impl HistoryItem {
12+
pub(crate) const fn new_load() -> Self {
13+
Self {
14+
operation: Operation::Load,
15+
start_index: 0,
16+
end_index: 0,
17+
lines: vec![],
18+
}
19+
}
20+
1221
pub(crate) fn new_modify(start_index: usize, end_index: usize, lines: Vec<Line>) -> Self {
1322
Self {
1423
operation: Operation::Modify,

src/todo_file/src/history/mod.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ impl History {
2323
pub(crate) fn new(limit: u32) -> Self {
2424
Self {
2525
redo_history: VecDeque::new(),
26-
undo_history: VecDeque::new(),
26+
undo_history: VecDeque::from([HistoryItem::new_load()]),
2727
limit: limit.try_into().expect("History limit is too large"),
2828
}
2929
}
3030

3131
pub(crate) fn apply_operation(lines: &mut Vec<Line>, operation: &HistoryItem) -> HistoryItem {
3232
match operation.operation {
33+
Operation::Load => HistoryItem::new_load(),
3334
Operation::Modify => {
3435
let range = if operation.end_index <= operation.start_index {
3536
operation.end_index..=operation.start_index
@@ -73,32 +74,40 @@ impl History {
7374
}
7475
}
7576

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+
}
7985
let update_range = Self::get_last_index_range(&history, current.len());
8086
self.redo_history.push_back(history);
81-
update_range
87+
(history_item.operation, update_range.0, update_range.1)
8288
})
8389
}
8490

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);
8896
let update_range = Self::get_last_index_range(&history, current.len());
8997
self.undo_history.push_back(history);
90-
update_range
98+
(history_item.operation, update_range.0, update_range.1)
9199
})
92100
}
93101

94102
pub(crate) fn reset(&mut self) {
95103
self.undo_history.clear();
104+
self.undo_history.push_back(HistoryItem::new_load());
96105
self.redo_history.clear();
97106
}
98107

99108
fn get_last_index_range(history_item: &HistoryItem, list_length: usize) -> (usize, usize) {
100109
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),
102111
Operation::Remove => {
103112
let index = min(history_item.start_index, history_item.end_index);
104113
if index == 0 || list_length == 0 {

src/todo_file/src/history/operation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#[derive(Debug, PartialEq, Eq)]
22
pub(crate) enum Operation {
3+
Load,
34
Modify,
45
SwapUp,
56
SwapDown,

0 commit comments

Comments
 (0)