Skip to content

Commit f90bb94

Browse files
simplify the editing callback hell
By wrapping the `Mutable` part in `CustomTextStorageBase` in begin/end editing calls, now deletions will be wrapped in an endEditing call, making the custom callback dance obsolete.
1 parent af3ae47 commit f90bb94

File tree

2 files changed

+9
-39
lines changed

2 files changed

+9
-39
lines changed

Typewriter/TypewriterTextStorage.swift

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,50 +34,24 @@ fileprivate extension String {
3434
}
3535

3636
protocol TypewriterTextStorageDelegate: class {
37-
/// Like `textStorage(_:willProcessEditing:range:changeInLength:)` called
38-
/// before the actual processing begins.
39-
func typewriterTextStorageWillProcessEditing(_ typewriterTextStorage: TypewriterTextStorage)
40-
41-
/// Called after `typewriterTextStorageDidEndEditing`, if `processEditing()`
42-
/// does emit that message.
43-
func typewriterTextStorageDidProcessEditing(_ typewriterTextStorage: TypewriterTextStorage)
44-
45-
/// Called to notify about the end of `endEditing()`, or in case of an edit
46-
/// outside of a begin/end editing block, at the end of `processEditing()`
47-
/// but before `typewriterTextStorageDidProcessEditing(_:)`.
48-
func typewriterTextStorageDidEndEditing(
49-
_ typewriterTextStorage: TypewriterTextStorage,
50-
butItReallyOnlyProcessedTheEdit endingAfterProcessing: Bool)
37+
/// Called to notify about the end of `endEditing()`.
38+
func typewriterTextStorageDidEndEditing(_ typewriterTextStorage: TypewriterTextStorage)
5139
}
5240

5341
class TypewriterTextStorage: CustomTextStorageBase {
5442

5543
weak var typewriterDelegate: TypewriterTextStorageDelegate?
5644

57-
private var isBlockEditing = false
58-
private var wasBlockEditing = false
59-
6045
override func beginEditing() {
61-
isBlockEditing = true
6246
super.beginEditing()
6347
}
6448

6549
override func processEditing() {
66-
typewriterDelegate?.typewriterTextStorageWillProcessEditing(self)
67-
6850
super.processEditing()
69-
70-
if !wasBlockEditing { typewriterDelegate?.typewriterTextStorageDidEndEditing(self, butItReallyOnlyProcessedTheEdit: true) }
71-
wasBlockEditing = false
72-
73-
typewriterDelegate?.typewriterTextStorageDidProcessEditing(self)
7451
}
7552

7653
override func endEditing() {
77-
// `super.endEditing()` triggers `processEditing`, so `wasBlockEditing` needs to be set first
78-
wasBlockEditing = isBlockEditing
79-
isBlockEditing = false
8054
super.endEditing()
81-
typewriterDelegate?.typewriterTextStorageDidEndEditing(self, butItReallyOnlyProcessedTheEdit: false)
55+
typewriterDelegate?.typewriterTextStorageDidEndEditing(self)
8256
}
8357
}

Typewriter/ViewController.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,10 @@ class ViewController: NSViewController, NSTextStorageDelegate, TypewriterTextSto
8787

8888
// MARK: Preparation
8989

90-
func typewriterTextStorageWillProcessEditing(_ typewriterTextStorage: TypewriterTextStorage) {
91-
isProcessingEdit = true
92-
}
90+
func textStorage(_ textStorage: NSTextStorage, willProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int) {
9391

94-
func typewriterTextStorageDidProcessEditing(_ typewriterTextStorage: TypewriterTextStorage) {
95-
isProcessingEdit = false
92+
guard isInTypewriterMode else { return }
93+
isProcessingEdit = true
9694
}
9795

9896
func textStorage(_ textStorage: NSTextStorage, didProcessEditing editedMask: NSTextStorageEditActions, range editedRange: NSRange, changeInLength delta: Int) {
@@ -133,16 +131,14 @@ class ViewController: NSViewController, NSTextStorageDelegate, TypewriterTextSto
133131
private(set) var pendingPreparation: TypewriterScrollPreparation?
134132

135133
func prepareScroll(_ preparation: TypewriterScrollPreparation) {
134+
136135
self.pendingPreparation = preparation
137136
}
138137

139-
func typewriterTextStorageDidEndEditing(_ typewriterTextStorage: TypewriterTextStorage, butItReallyOnlyProcessedTheEdit endingAfterProcessing: Bool) {
138+
func typewriterTextStorageDidEndEditing(_ typewriterTextStorage: TypewriterTextStorage) {
140139

141-
// If we would not schedule for later here, the layout manager would not be in
142-
// a valid state for querying and the app crashes. So we schedule the command for later.
143-
// Affects deletion only, it seems, so the tradeoff (making it an async problem) isn't that bad.
144-
guard !endingAfterProcessing else { RunLoop.current.perform(processScrollPreparation); return }
145140
processScrollPreparation()
141+
isProcessingEdit = false
146142
}
147143

148144
fileprivate func processScrollPreparation() {

0 commit comments

Comments
 (0)