ass_editor/core/document/
undo_redo.rs1use super::EditorDocument;
8use crate::commands::CommandResult;
9use crate::core::errors::{EditorError, Result};
10use crate::core::history::UndoManager;
11use crate::core::position::{Position, Range};
12
13#[cfg(not(feature = "std"))]
14use alloc::string::ToString;
15
16impl EditorDocument {
17 pub fn undo(&mut self) -> Result<CommandResult> {
22 use crate::core::history::Operation;
23
24 if let Some(entry) = self.history.pop_undo_entry() {
26 let mut result = CommandResult::success();
27 result.content_changed = true;
28
29 match &entry.operation {
31 Operation::Insert { position, text } => {
32 let end_pos = Position::new(position.offset + text.len());
34 let range = Range::new(*position, end_pos);
35 self.delete_raw(range)?;
36 result.modified_range = Some(Range::new(*position, *position));
37 result.new_cursor = entry.cursor_before;
38 }
39 Operation::Delete {
40 range,
41 deleted_text,
42 } => {
43 self.insert_raw(range.start, deleted_text)?;
45 let end_pos = Position::new(range.start.offset + deleted_text.len());
46 result.modified_range = Some(Range::new(range.start, end_pos));
47 result.new_cursor = entry.cursor_before;
48 }
49 Operation::Replace {
50 range, old_text, ..
51 } => {
52 self.replace_raw(*range, old_text)?;
54 let end_pos = Position::new(range.start.offset + old_text.len());
55 result.modified_range = Some(Range::new(range.start, end_pos));
56 result.new_cursor = entry.cursor_before;
57 }
58 #[cfg(feature = "stream")]
59 Operation::Delta { forward, undo_data } => {
60 for (index, section_text) in undo_data.removed_sections.iter() {
62 self.insert_section_at(*index, section_text)?;
63 }
64
65 for (index, original_text) in undo_data.modified_sections.iter() {
67 self.replace_section(*index, original_text)?;
68 }
69
70 for _ in 0..forward.added.len() {
72 self.remove_last_section()?;
73 }
74
75 result.message = Some("Delta operation undone".to_string());
76 }
77 }
78
79 self.history.push_redo_entry(entry);
81
82 #[cfg(feature = "stream")]
84 if let Some(delta) = result.script_delta.as_ref() {
85 self.apply_script_delta(delta.clone())?;
86 }
87
88 result.message = Some("Undo successful".to_string());
89 Ok(result)
90 } else {
91 Err(EditorError::NothingToUndo)
92 }
93 }
94
95 pub fn redo(&mut self) -> Result<CommandResult> {
100 use crate::core::history::Operation;
101
102 if let Some(entry) = self.history.pop_redo_entry() {
104 let mut result = CommandResult::success();
105 result.content_changed = true;
106
107 match &entry.operation {
109 Operation::Insert { position, text } => {
110 self.insert_raw(*position, text)?;
112 let end_pos = Position::new(position.offset + text.len());
113 result.modified_range = Some(Range::new(*position, end_pos));
114 result.new_cursor = entry.cursor_after;
115 }
116 Operation::Delete { range, .. } => {
117 self.delete_raw(*range)?;
119 result.modified_range = Some(Range::new(range.start, range.start));
120 result.new_cursor = entry.cursor_after;
121 }
122 Operation::Replace {
123 range, new_text, ..
124 } => {
125 self.replace_raw(*range, new_text)?;
127 let end_pos = Position::new(range.start.offset + new_text.len());
128 result.modified_range = Some(Range::new(range.start, end_pos));
129 result.new_cursor = entry.cursor_after;
130 }
131 #[cfg(feature = "stream")]
132 Operation::Delta {
133 forward,
134 undo_data: _,
135 } => {
136 self.apply_script_delta(forward.clone())?;
138 result.message = Some("Delta re-applied".to_string());
139 }
140 }
141
142 if let Some(cursor) = result.new_cursor {
145 self.history.set_cursor(Some(cursor));
146 }
147
148 let new_entry = crate::core::history::HistoryEntry::new(
150 entry.operation,
151 entry.description,
152 &result,
153 entry.cursor_before,
154 );
155
156 self.history.stack_mut().push(new_entry);
158
159 result.message = Some("Redo successful".to_string());
160 Ok(result)
161 } else {
162 Err(EditorError::NothingToRedo)
163 }
164 }
165
166 pub fn can_undo(&self) -> bool {
168 self.history.can_undo()
169 }
170
171 pub fn can_redo(&self) -> bool {
173 self.history.can_redo()
174 }
175
176 pub fn next_undo_description(&self) -> Option<&str> {
178 self.history.next_undo_description()
179 }
180
181 pub fn next_redo_description(&self) -> Option<&str> {
183 self.history.next_redo_description()
184 }
185
186 pub fn undo_manager_mut(&mut self) -> &mut UndoManager {
188 &mut self.history
189 }
190
191 pub fn undo_manager(&self) -> &UndoManager {
193 &self.history
194 }
195}