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
74
75
76
77
78
79
80
81
82
//! Type definitions for undo/redo history management
use VecDeque;
/// Default maximum history size
pub const DEFAULT_MAX_HISTORY: usize = 100;
/// Trait for operations that can be merged (coalesced)
///
/// Implement this trait to enable automatic merging of consecutive
/// similar operations (e.g., multiple character insertions into one).
///
/// # Example
///
/// ```rust,ignore
/// impl Mergeable for TextOp {
/// fn can_merge(&self, other: &Self) -> bool {
/// match (self, other) {
/// (TextOp::Insert { pos: p1, .. }, TextOp::Insert { pos: p2, .. }) => {
/// // Can merge if inserting at consecutive positions
/// *p2 == *p1 + 1
/// }
/// _ => false,
/// }
/// }
///
/// fn merge(self, other: Self) -> Self {
/// match (self, other) {
/// (TextOp::Insert { pos, text: mut t1 }, TextOp::Insert { text: t2, .. }) => {
/// t1.push_str(&t2);
/// TextOp::Insert { pos, text: t1 }
/// }
/// _ => self,
/// }
/// }
/// }
/// ```
/// A generic undo/redo history manager
///
/// Stores operations in two stacks (undo and redo) and provides
/// methods to navigate through the history.
///
/// # Type Parameters
///
/// * `T` - The operation type. Each widget can define its own operation enum.
///
/// # Usage Pattern
///
/// 1. When user performs an action, `push()` the operation
/// 2. When user requests undo, `undo()` returns the operation to reverse
/// 3. When user requests redo, `redo()` returns the operation to re-apply
///
/// The history manager doesn't apply operations - it just tracks them.
/// Your code is responsible for applying/reversing operations on your state.