@@ -22,7 +22,7 @@ import OSLog
2222/// can throw an ``TreeSitterClientExecutor/Error/syncUnavailable`` error if an asynchronous or synchronous call is
2323/// already being made on the object. In those cases it is up to the caller to decide whether or not to retry
2424/// asynchronously.
25- ///
25+ ///
2626/// The only exception to the above rule is the ``HighlightProviding`` conformance methods. The methods for that
2727/// implementation may return synchronously or asynchronously depending on a variety of factors such as document
2828/// length, edit length, highlight length and if the object is available for a synchronous call.
@@ -156,23 +156,26 @@ public final class TreeSitterClient: HighlightProviding {
156156 }
157157
158158 let operation = { [ weak self] in
159- let invalidatedRanges = self ? . applyEdit ( edit: edit) ?? IndexSet ( )
160- DispatchQueue . dispatchMainIfNot { completion ( . success( invalidatedRanges) ) }
159+ return self ? . applyEdit ( edit: edit) ?? IndexSet ( )
161160 }
162161
163162 let longEdit = range. length > Constants . maxSyncEditLength
164163 let longDocument = textView. documentRange. length > Constants . maxSyncContentLength
165-
166- if forceSyncOperation {
167- executor. execSync ( operation)
168- return
164+ let execAsync = longEdit || longDocument
165+
166+ if !execAsync || forceSyncOperation {
167+ let result = executor. execSync ( operation)
168+ if case . success( let invalidatedRanges) = result {
169+ DispatchQueue . dispatchMainIfNot { completion ( . success( invalidatedRanges) ) }
170+ return
171+ }
169172 }
170173
171- if longEdit || longDocument || !executor . execSync ( operation ) . isSuccess {
174+ if !forceSyncOperation {
172175 executor. cancelAll ( below: . reset) // Cancel all edits, add it to the pending edit queue
173176 executor. execAsync (
174177 priority: . edit,
175- operation: operation,
178+ operation: { completion ( . success ( operation ( ) ) ) } ,
176179 onCancel: { [ weak self] in
177180 self ? . pendingEdits. mutate { edits in
178181 edits. append ( edit)
@@ -205,22 +208,27 @@ public final class TreeSitterClient: HighlightProviding {
205208 completion: @escaping @MainActor ( Result < [ HighlightRange ] , Error > ) -> Void
206209 ) {
207210 let operation = { [ weak self] in
208- let highlights = self ? . queryHighlightsForRange ( range: range)
209- DispatchQueue . dispatchMainIfNot { completion ( . success( highlights ?? [ ] ) ) }
211+ return self ? . queryHighlightsForRange ( range: range) ?? [ ]
210212 }
211213
212214 let longQuery = range. length > Constants . maxSyncQueryLength
213215 let longDocument = textView. documentRange. length > Constants . maxSyncContentLength
214-
215- if forceSyncOperation {
216- executor. execSync ( operation)
217- return
216+ let execAsync = longQuery || longDocument
217+
218+ if !execAsync || forceSyncOperation {
219+ let result = executor. execSync ( operation)
220+ if case . success( let highlights) = result {
221+ DispatchQueue . dispatchMainIfNot { completion ( . success( highlights) ) }
222+ return
223+ }
218224 }
219225
220- if longQuery || longDocument || !executor . execSync ( operation ) . isSuccess {
226+ if execAsync && !forceSyncOperation {
221227 executor. execAsync (
222228 priority: . access,
223- operation: operation,
229+ operation: {
230+ DispatchQueue . dispatchMainIfNot { completion ( . success( operation ( ) ) ) }
231+ } ,
224232 onCancel: {
225233 DispatchQueue . dispatchMainIfNot {
226234 completion ( . failure( HighlightProvidingError . operationCancelled) )
0 commit comments