1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// Represents a single edit operation for undo/redo functionality
#[derive(Debug, Clone)]
pub enum Edit {
/// Insert a character at a specific position
InsertChar { row: usize, col: usize, ch: char },
/// Delete a character at a specific position
DeleteChar { row: usize, col: usize, ch: char },
/// Insert a new line at a specific position
InsertLine { row: usize, content: String },
/// Delete a line at a specific position
DeleteLine { row: usize, content: String },
/// Split a line at a specific position
SplitLine { row: usize, col: usize },
/// Join two lines at a specific position
JoinLines { row: usize },
}
/// Manages edit history for undo/redo operations
pub struct EditHistory {
/// Stack of edits that can be undone
undo_stack: Vec<Edit>,
/// Stack of edits that can be redone
redo_stack: Vec<Edit>,
}
impl EditHistory {
/// Create a new empty edit history
pub fn new() -> Self {
Self {
undo_stack: Vec::new(),
redo_stack: Vec::new(),
}
}
/// Push a new edit to the undo stack and clear the redo stack
pub fn push(&mut self, edit: Edit) {
self.undo_stack.push(edit);
self.redo_stack.clear();
}
/// Pop an edit from the undo stack and push it to the redo stack
/// Returns None if the undo stack is empty
pub fn undo(&mut self) -> Option<Edit> {
if let Some(edit) = self.undo_stack.pop() {
self.redo_stack.push(edit.clone());
Some(edit)
} else {
None
}
}
/// Pop an edit from the redo stack and push it to the undo stack
/// Returns None if the redo stack is empty
pub fn redo(&mut self) -> Option<Edit> {
if let Some(edit) = self.redo_stack.pop() {
self.undo_stack.push(edit.clone());
Some(edit)
} else {
None
}
}
/// Clear the redo stack (called when new edits are made)
pub fn clear_redo(&mut self) {
self.redo_stack.clear();
}
}
impl Default for EditHistory {
fn default() -> Self {
Self::new()
}
}