Skip to main content

fresh/app/
undo_actions.rs

1//! Undo and redo action handlers.
2
3use super::Editor;
4use rust_i18n::t;
5
6impl Editor {
7    /// Handle Undo action - revert the last edit operation.
8    pub fn handle_undo(&mut self) {
9        if self.is_editing_disabled() {
10            self.set_status_message(t!("buffer.editing_disabled").to_string());
11            return;
12        }
13
14        let event_log = self.active_event_log_mut();
15        let before_idx = event_log.current_index();
16        let can_undo = event_log.can_undo();
17        let events = event_log.undo();
18        let after_idx = self.active_event_log().current_index();
19
20        tracing::debug!(
21            "Undo: before_idx={}, after_idx={}, can_undo={}, events_count={}",
22            before_idx,
23            after_idx,
24            can_undo,
25            events.len()
26        );
27
28        // Apply all inverse events collected during undo.
29        // Each event may carry displaced markers that need restoration after apply.
30        for (event, displaced_markers) in &events {
31            tracing::debug!("Undo applying event: {:?}", event);
32            self.apply_event_to_active_buffer(event);
33
34            // Restore displaced markers from LogEntry (for single Delete events).
35            // Skip for BulkEdit — they handle displaced markers internally
36            // in state.apply(BulkEdit) via the Event's own displaced_markers field.
37            if !displaced_markers.is_empty()
38                && !matches!(event, crate::model::event::Event::BulkEdit { .. })
39            {
40                self.active_state_mut()
41                    .restore_displaced_markers(displaced_markers);
42            }
43        }
44
45        // Update modified status based on event log position
46        self.update_modified_from_event_log();
47    }
48
49    /// Handle Redo action - reapply an undone edit operation.
50    pub fn handle_redo(&mut self) {
51        if self.is_editing_disabled() {
52            self.set_status_message(t!("buffer.editing_disabled").to_string());
53            return;
54        }
55
56        let events = self.active_event_log_mut().redo();
57
58        // Apply all events collected during redo
59        for event in events {
60            self.apply_event_to_active_buffer(&event);
61        }
62
63        // Update modified status based on event log position
64        self.update_modified_from_event_log();
65    }
66}