Skip to content

Commit

Permalink
Add range check to highlightsFromCursor (#187)
Browse files Browse the repository at this point in the history
<!--- IMPORTANT: If this PR addresses multiple unrelated issues, it will
be closed until separated. -->

### Description
Fixes a bug found found by @cengelbart39 [on
discord](https://canary.discord.com/channels/951544472238444645/952640521812193411/1104143145765187644)
where a parser would consume ranges already consumed by injected
languages. This caused the injected ranges to be realized as plain text,
when they should have been kept as their injected language's highlights.

This should have been avoided by the call to `query.setRange(range)` on
line [43 in
TreeSitterClient+Highlight.swift](https://github.com/CodeEditApp/CodeEditTextView/blob/045bd359ef9c4addf2a5bf51e22ba660d69c5d10/Sources/CodeEditTextView/TreeSitter/TreeSitterClient%2BHighlight.swift#L44)
but it was found that for some reason in the case found by @cengelbart39
it just didn't work.

To fix, an additional check was added in `highlightsFromCursor` to only
take any ranges that have indices in the intersection of it's range and
the included range.

### Related Issues

<!--- REQUIRED: Tag all related issues (e.g. * #123) -->
<!--- If this PR resolves the issue please specify (e.g. * closes #123)
-->
<!--- If this PR addresses multiple issues, these issues must be related
to one other -->

* See discord link.

### Checklist

<!--- Add things that are not yet implemented above -->

- [x] I read and understood the [contributing
guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md)
as well as the [code of
conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md)
- [x] The issues this PR addresses are related to each other
- [x] My changes generate no new warnings
- [x] My code builds and runs on my machine
- [x] My changes are all related to the related issue above
- [x] I documented my code

### Screenshots

Before:


https://user-images.githubusercontent.com/35942988/236696171-d30dfd7b-8545-4396-8aa8-490ceac65551.mov

After:


https://user-images.githubusercontent.com/35942988/236697575-3f605c0d-3dda-45c2-8f69-0f41148f1c2d.mov
thecoolwinter authored May 10, 2023

Verified

This commit was signed with the committer’s verified signature.
Eliulm Elias Wahl
1 parent b60e0fc commit 521dd43
Showing 1 changed file with 10 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -44,23 +44,28 @@ extension TreeSitterClient {
cursor.setRange(range)
cursor.matchLimit = Constants.treeSitterMatchLimit

return highlightsFromCursor(cursor: ResolvingQueryCursor(cursor: cursor))
return highlightsFromCursor(cursor: ResolvingQueryCursor(cursor: cursor), includedRange: range)
}

/// Resolves a query cursor to the highlight ranges it contains.
/// **Must be called on the main thread**
/// - Parameter cursor: The cursor to resolve.
/// - Parameters:
/// - cursor: The cursor to resolve.
/// - includedRange: The range to include highlights from.
/// - Returns: Any highlight ranges contained in the cursor.
internal func highlightsFromCursor(cursor: ResolvingQueryCursor) -> [HighlightRange] {
internal func highlightsFromCursor(cursor: ResolvingQueryCursor, includedRange: NSRange) -> [HighlightRange] {
cursor.prepare(with: self.textProvider)
return cursor
.flatMap { $0.captures }
.compactMap {
// Sometimes `cursor.setRange` just doesnt work :( so we have to do a redundant check for a valid range
// in the included range
let intersectionRange = $0.range.intersection(includedRange) ?? .zero
// Some languages add an "@spell" capture to indicate a portion of text that should be spellchecked
// (usually comments). But this causes other captures in the same range to be overriden. So we ignore
// that specific capture type.
if $0.name != "spell" && $0.name != "injection.content" {
return HighlightRange(range: $0.range, capture: CaptureName.fromString($0.name ?? ""))
if intersectionRange.length > 0 && $0.name != "spell" && $0.name != "injection.content" {
return HighlightRange(range: intersectionRange, capture: CaptureName.fromString($0.name ?? ""))
}
return nil
}

0 comments on commit 521dd43

Please sign in to comment.