Skip to content

Commit

Permalink
Query definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
mattmassicotte committed Oct 6, 2022
1 parent 2cff6df commit 3b1599b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

Swift API for the [tree-sitter](https://tree-sitter.github.io/) incremental parsing system.

- Close to full coverage of the C API
- Swift/Foundation types where possible
- Standard query result mapping for injections
- Query predicate support via `ResolvingQueryCursor`

SwiftTreeSitter is fairly low-level. If you are looking a higher-level system for syntax highlighting and other syntactic operations, you might want to have a look at [Neon](https://github.com/ChimeHQ/Neon).

📖 [Documentation][documentation] is available in DocC format.
Expand Down
47 changes: 47 additions & 0 deletions Sources/SwiftTreeSitter/QueryDefinitions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Foundation

/// A combined name and range
///
/// Useful for generalizing data from query matches.
public struct NamedRange {
public let name: String
public let range: NSRange

public init(name: String, range: NSRange) {
self.name = name
self.range = range
}
}

public extension QueryMatch {
/// Intrepret the match using the "injections.scm" definition
///
/// - `injection.content` defines the range of the injection
/// - a node with `injection.language` specifies the value of the language in the text
/// - if that is not prsent, uses `injection.language` metadata
///
/// If `textProvider` is nil and a node contents is needed, the injection is dropped.
func injection(with textProvider: ResolvingQueryCursor.TextProvider?) -> NamedRange? {
guard let range = captures(named: "injection.content").first?.range else {
return nil
}

let languageCapture = captures(named: "injection.language").first

let nodeLanguage: String?

if let node = languageCapture?.node {
nodeLanguage = textProvider?(node.range, node.pointRange)
} else {
nodeLanguage = nil
}

let setLanguage = metadata["injection.language"]

guard let language = nodeLanguage ?? setLanguage else {
return nil
}

return NamedRange(name: language, range: range)
}
}

0 comments on commit 3b1599b

Please sign in to comment.