diff --git a/Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index cf13c167c..9be37aec1 100644 --- a/Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Example/CodeEditSourceEditorExample/CodeEditSourceEditorExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/CodeEditApp/CodeEditTextView.git", "state" : { - "revision" : "6653c21a603babf365a12d4d331fadc8f8b52d99", - "version" : "0.7.2" + "revision" : "86b980464bcb67693e2053283c7a99bdc6f358bc", + "version" : "0.7.3" } }, { diff --git a/Package.swift b/Package.swift index 62d3537d2..8362b19be 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( // A fast, efficient, text view for code. .package( url: "https://github.com/CodeEditApp/CodeEditTextView.git", - from: "0.7.2" + from: "0.7.3" ), // tree-sitter languages .package( diff --git a/Sources/CodeEditSourceEditor/Extensions/TextMutation+isEmpty.swift b/Sources/CodeEditSourceEditor/Extensions/TextMutation+isEmpty.swift new file mode 100644 index 000000000..6b07fe40d --- /dev/null +++ b/Sources/CodeEditSourceEditor/Extensions/TextMutation+isEmpty.swift @@ -0,0 +1,17 @@ +// +// TextMutation+isEmpty.swift +// CodeEditSourceEditor +// +// Created by Khan Winter on 3/1/24. +// + +import TextStory + +extension TextMutation { + /// Determines if the mutation is an empty mutation. + /// + /// Will return `true` if the mutation is neither a delete operation nor an insert operation. + var isEmpty: Bool { + self.string.isEmpty && self.range.isEmpty + } +} diff --git a/Sources/CodeEditSourceEditor/Extensions/TextView+/TextView+TextFormation.swift b/Sources/CodeEditSourceEditor/Extensions/TextView+/TextView+TextFormation.swift index 6af20638e..61fd3ef73 100644 --- a/Sources/CodeEditSourceEditor/Extensions/TextView+/TextView+TextFormation.swift +++ b/Sources/CodeEditSourceEditor/Extensions/TextView+/TextView+TextFormation.swift @@ -33,13 +33,25 @@ extension TextView: TextInterface { } /// Applies the mutation to the text view. + /// + /// If the mutation is empty it will be ignored. + /// /// - Parameter mutation: The mutation to apply. public func applyMutation(_ mutation: TextMutation) { + guard !mutation.isEmpty else { return } + + layoutManager.beginTransaction() + textStorage.beginEditing() + layoutManager.willReplaceCharactersInRange(range: mutation.range, with: mutation.string) + _undoManager?.registerMutation(mutation) + textStorage.replaceCharacters(in: mutation.range, with: mutation.string) selectionManager.didReplaceCharacters( in: mutation.range, replacementLength: (mutation.string as NSString).length ) - textStorage.replaceCharacters(in: mutation.range, with: mutation.string) + + textStorage.endEditing() + layoutManager.endTransaction() } } diff --git a/Sources/CodeEditSourceEditor/Filters/TabReplacementFilter.swift b/Sources/CodeEditSourceEditor/Filters/TabReplacementFilter.swift index c61c20089..104f4ea34 100644 --- a/Sources/CodeEditSourceEditor/Filters/TabReplacementFilter.swift +++ b/Sources/CodeEditSourceEditor/Filters/TabReplacementFilter.swift @@ -20,9 +20,13 @@ struct TabReplacementFilter: Filter { with providers: WhitespaceProviders ) -> FilterAction { if mutation.string == "\t" && indentOption != .tab && mutation.delta > 0 { - interface.applyMutation(TextMutation(insert: indentOption.stringValue, - at: mutation.range.location, - limit: mutation.limit)) + interface.applyMutation( + TextMutation( + insert: indentOption.stringValue, + at: mutation.range.location, + limit: mutation.limit + ) + ) return .discard } else { return .none