Skip to content

Commit 74c98b8

Browse files
committed
Force Undo Groups To Break When Starting/Ending Forced Groups
1 parent 82bc832 commit 74c98b8

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

Sources/CodeEditTextView/Utils/CEUndoManager.swift

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ public class CEUndoManager {
8383

8484
private weak var textView: TextView?
8585
private(set) public var isGrouping: Bool = false
86+
87+
/// After ``endUndoGrouping`` is called, we'd expect the next mutation to be exclusive no matter what. This
88+
/// flag facilitates that, and is set by ``endUndoGrouping``
89+
private var shouldBreakNextGroup: Bool = false
90+
8691
/// True when the manager is ignoring mutations.
8792
private var isDisabled: Bool = false
8893

@@ -154,18 +159,19 @@ public class CEUndoManager {
154159
return
155160
}
156161
let newMutation = Mutation(mutation: mutation, inverse: textStorage.inverseMutation(for: mutation))
157-
if !undoStack.isEmpty, let lastMutation = undoStack.last?.mutations.last {
158-
if isGrouping || shouldContinueGroup(newMutation, lastMutation: lastMutation) {
159-
undoStack[undoStack.count - 1].mutations.append(newMutation)
160-
} else {
161-
undoStack.append(UndoGroup(mutations: [newMutation]))
162-
}
162+
// We can continue a group if:
163+
// - A group exists
164+
// - We're not direct to break the current group
165+
// - We're forced grouping OR we automagically detect we can group.
166+
if !undoStack.isEmpty,
167+
let lastMutation = undoStack.last?.mutations.last,
168+
!shouldBreakNextGroup,
169+
isGrouping || shouldContinueGroup(newMutation, lastMutation: lastMutation) {
170+
undoStack[undoStack.count - 1].mutations.append(newMutation)
163171
} else {
164-
undoStack.append(
165-
UndoGroup(mutations: [newMutation])
166-
)
172+
undoStack.append(UndoGroup(mutations: [newMutation]))
173+
shouldBreakNextGroup = false
167174
}
168-
169175
redoStack.removeAll()
170176
}
171177

@@ -178,6 +184,8 @@ public class CEUndoManager {
178184
return
179185
}
180186
isGrouping = true
187+
// This is a new undo group, break for it.
188+
shouldBreakNextGroup = true
181189
}
182190

183191
/// Stops grouping all incoming mutations.
@@ -187,6 +195,8 @@ public class CEUndoManager {
187195
return
188196
}
189197
isGrouping = false
198+
// We just ended a group, do not allow the next mutation to be added to the group we just made.
199+
shouldBreakNextGroup = true
190200
}
191201

192202
/// Determines whether or not two mutations should be grouped.

0 commit comments

Comments
 (0)