Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 3 additions & 16 deletions Sources/CodeEditSourceEditor/Highlighting/Highlighter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,9 @@ private extension Highlighter {
func queryHighlights(for rangesToHighlight: [NSRange]) {
guard let textView else { return }

if !Thread.isMainThread {
DispatchQueue.main.async { [weak self] in
for range in rangesToHighlight {
self?.highlightProvider?.queryHighlightsFor(
textView: textView,
range: range
) { [weak self] highlights in
assert(Thread.isMainThread, "Highlighted ranges called on non-main thread.")
self?.applyHighlightResult(highlights, rangeToHighlight: range)
}
}
}
} else {
DispatchQueue.dispatchMainIfNot {
for range in rangesToHighlight {
highlightProvider?.queryHighlightsFor(textView: textView, range: range) { [weak self] highlights in
self.highlightProvider?.queryHighlightsFor(textView: textView, range: range) { [weak self] highlights in
assert(Thread.isMainThread, "Highlighted ranges called on non-main thread.")
self?.applyHighlightResult(highlights, rangeToHighlight: range)
}
Expand Down Expand Up @@ -222,7 +210,6 @@ private extension Highlighter {
validSet.formUnion(IndexSet(integersIn: rangeToHighlight))

// Loop through each highlight and modify the textStorage accordingly.
textView?.layoutManager.beginTransaction()
textView?.textStorage.beginEditing()

// Create a set of indexes that were not highlighted.
Expand All @@ -249,7 +236,7 @@ private extension Highlighter {
}

textView?.textStorage.endEditing()
textView?.layoutManager.endTransaction()
textView?.layoutManager.invalidateLayoutForRange(rangeToHighlight)
}
}

Expand Down
42 changes: 25 additions & 17 deletions Sources/CodeEditSourceEditor/TreeSitter/TreeSitterClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import OSLog
/// can throw an ``TreeSitterClientExecutor/Error/syncUnavailable`` error if an asynchronous or synchronous call is
/// already being made on the object. In those cases it is up to the caller to decide whether or not to retry
/// asynchronously.
///
///
/// The only exception to the above rule is the ``HighlightProviding`` conformance methods. The methods for that
/// implementation may return synchronously or asynchronously depending on a variety of factors such as document
/// length, edit length, highlight length and if the object is available for a synchronous call.
Expand Down Expand Up @@ -156,23 +156,26 @@ public final class TreeSitterClient: HighlightProviding {
}

let operation = { [weak self] in
let invalidatedRanges = self?.applyEdit(edit: edit) ?? IndexSet()
DispatchQueue.dispatchMainIfNot { completion(.success(invalidatedRanges)) }
return self?.applyEdit(edit: edit) ?? IndexSet()
}

let longEdit = range.length > Constants.maxSyncEditLength
let longDocument = textView.documentRange.length > Constants.maxSyncContentLength

if forceSyncOperation {
executor.execSync(operation)
return
let execAsync = longEdit || longDocument

if !execAsync || forceSyncOperation {
let result = executor.execSync(operation)
if case .success(let invalidatedRanges) = result {
DispatchQueue.dispatchMainIfNot { completion(.success(invalidatedRanges)) }
return
}
}

if longEdit || longDocument || !executor.execSync(operation).isSuccess {
if !forceSyncOperation {
executor.cancelAll(below: .reset) // Cancel all edits, add it to the pending edit queue
executor.execAsync(
priority: .edit,
operation: operation,
operation: { completion(.success(operation())) },
onCancel: { [weak self] in
self?.pendingEdits.mutate { edits in
edits.append(edit)
Expand Down Expand Up @@ -205,22 +208,27 @@ public final class TreeSitterClient: HighlightProviding {
completion: @escaping @MainActor (Result<[HighlightRange], Error>) -> Void
) {
let operation = { [weak self] in
let highlights = self?.queryHighlightsForRange(range: range)
DispatchQueue.dispatchMainIfNot { completion(.success(highlights ?? [])) }
return self?.queryHighlightsForRange(range: range) ?? []
}

let longQuery = range.length > Constants.maxSyncQueryLength
let longDocument = textView.documentRange.length > Constants.maxSyncContentLength

if forceSyncOperation {
executor.execSync(operation)
return
let execAsync = longQuery || longDocument

if !execAsync || forceSyncOperation {
let result = executor.execSync(operation)
if case .success(let highlights) = result {
DispatchQueue.dispatchMainIfNot { completion(.success(highlights)) }
return
}
}

if longQuery || longDocument || !executor.execSync(operation).isSuccess {
if execAsync && !forceSyncOperation {
executor.execAsync(
priority: .access,
operation: operation,
operation: {
DispatchQueue.dispatchMainIfNot { completion(.success(operation())) }
},
onCancel: {
DispatchQueue.dispatchMainIfNot {
completion(.failure(HighlightProvidingError.operationCancelled))
Expand Down
Loading