Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tree-sitter/tree-sitter/llms.txt
Use this file to discover all available pages before exploring further.
The Query API allows you to search syntax trees using pattern matching. Queries are written in a special S-expression syntax and can capture specific nodes that match certain patterns.
Query
A Query is a set of patterns that match nodes in a syntax tree.
new
pub fn new(language: &Language, source: &str) -> Result<Self, QueryError>
Create a new query from a string containing one or more S-expression patterns. The query is associated with a particular language, and can only be run on syntax nodes parsed with that language.
The language to associate with the query
The query source code in S-expression syntax
let query = Query::new(
&language,
r#"
(function_item
name: (identifier) @function.name
parameters: (parameters) @function.params)
"#
)?;
pattern_count
pub fn pattern_count(&self) -> usize
Get the number of patterns in the query.
start_byte_for_pattern
pub fn start_byte_for_pattern(&self, pattern_index: usize) -> usize
Get the byte offset where the given pattern starts in the query’s source.
end_byte_for_pattern
pub fn end_byte_for_pattern(&self, pattern_index: usize) -> usize
Get the byte offset where the given pattern ends in the query’s source.
is_pattern_rooted
pub fn is_pattern_rooted(&self, index: usize) -> bool
Check if a given pattern within a query has a single root node.
is_pattern_non_local
pub fn is_pattern_non_local(&self, index: usize) -> bool
Check if a given pattern is non-local (can match nodes at any depth).
Capture Management
capture_names
pub const fn capture_names(&self) -> &[&str]
Get the names of the captures used in the query.
for name in query.capture_names() {
println!("Capture: @{}", name);
}
capture_index_for_name
pub fn capture_index_for_name(&self, name: &str) -> Option<u32>
Get the index for a given capture name.
The name of the capture (without the @ prefix)
capture_quantifiers
pub const fn capture_quantifiers(&self, index: usize) -> &[CaptureQuantifier]
Get the quantifiers of the captures for a given pattern.
Predicates
property_predicates
pub const fn property_predicates(&self, index: usize) -> &[(QueryProperty, bool)]
Get the properties that are checked for the given pattern index. This includes predicates with the operators is? and is-not?.
property_settings
pub const fn property_settings(&self, index: usize) -> &[QueryProperty]
Get the properties that are set for the given pattern index. This includes predicates with the operator set!.
general_predicates
pub const fn general_predicates(&self, index: usize) -> &[QueryPredicate]
Get the other user-defined predicates associated with the given index. This includes predicates with operators other than match?, eq?, not-eq?, is?, is-not?, and set!.
Pattern Control
disable_capture
pub fn disable_capture(&mut self, name: &str)
Disable a certain capture within a query. This prevents the capture from being returned in matches, and also avoids any resource usage associated with recording the capture.
The name of the capture to disable
disable_pattern
pub fn disable_pattern(&mut self, index: usize)
Disable a certain pattern within a query. This prevents the pattern from matching, and also avoids any resource usage associated with the pattern.
The index of the pattern to disable
QueryCursor
A QueryCursor is a stateful object for executing a Query on a syntax tree.
new
Create a new cursor for executing a query. The cursor stores the state that is needed to iteratively search for matches.
let mut cursor = QueryCursor::new();
Execution
matches
pub fn matches<'query, 'cursor: 'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
&'cursor mut self,
query: &'query Query,
node: Node<'tree>,
text_provider: T,
) -> QueryMatches<'query, 'tree, T, I>
Iterate over all of the matches in the order that they were found. Requires the StreamingIterator trait to be in scope.
The node to search within
A provider for accessing the source text
use tree_sitter::StreamingIterator;
let mut cursor = QueryCursor::new();
let mut matches = cursor.matches(&query, root_node, source.as_bytes());
while let Some(match_) = matches.next() {
for capture in match_.captures {
println!("Capture @{}: {}",
query.capture_names()[capture.index as usize],
capture.node.utf8_text(source.as_bytes()).unwrap());
}
}
captures
pub fn captures<'query, 'cursor: 'query, 'tree, T: TextProvider<I>, I: AsRef<[u8]>>(
&'cursor mut self,
query: &'query Query,
node: Node<'tree>,
text_provider: T,
) -> QueryCaptures<'query, 'tree, T, I>
Iterate over all of the individual captures in the order that they appear. This is useful if you don’t care about which pattern matched, and just want a single, ordered sequence of captures.
use tree_sitter::StreamingIterator;
let mut cursor = QueryCursor::new();
let mut captures = cursor.captures(&query, root_node, source.as_bytes());
while let Some((match_, index)) = captures.next() {
let capture = &match_.captures[index];
println!("Capture: {}", capture.node.kind());
}
Range Configuration
set_byte_range
pub fn set_byte_range(&mut self, range: ops::Range<usize>) -> &mut Self
Set the range in which the query will be executed, in terms of byte offsets.
The byte range to search within
cursor.set_byte_range(0..100);
set_point_range
pub fn set_point_range(&mut self, range: ops::Range<Point>) -> &mut Self
Set the range in which the query will be executed, in terms of rows and columns.
The point range to search within
set_containing_byte_range
pub fn set_containing_byte_range(&mut self, range: ops::Range<usize>) -> &mut Self
Set the byte range within which all matches must be fully contained. This will restrict the query cursor to only return matches where all nodes are fully contained within the given range.
set_containing_point_range
pub fn set_containing_point_range(&mut self, range: ops::Range<Point>) -> &mut Self
Set the point range within which all matches must be fully contained.
set_max_start_depth
pub fn set_max_start_depth(&mut self, max_start_depth: Option<u32>) -> &mut Self
Set the maximum start depth for a query cursor. This prevents cursors from exploring children nodes at a certain depth. Set to None to remove the maximum start depth.
The maximum depth, or None to disable
Match Limits
match_limit
pub fn match_limit(&self) -> u32
Return the maximum number of in-progress matches for this cursor.
set_match_limit
pub fn set_match_limit(&mut self, limit: u32)
Set the maximum number of in-progress matches for this cursor. The limit must be greater than 0 and less than or equal to 65536.
The maximum number of in-progress matches
did_exceed_match_limit
pub fn did_exceed_match_limit(&self) -> bool
Check if, on its last execution, this cursor exceeded its maximum number of in-progress matches.
QueryMatch
A match of a query to a particular set of nodes.
pub struct QueryMatch<'cursor, 'tree> {
pub pattern_index: usize,
pub captures: &'cursor [QueryCapture<'tree>],
// ...
}
The index of the pattern that matched
The list of captures in this match
pub const fn id(&self) -> u32
Get the unique id for this match.
remove
Remove this match from the query cursor’s results.
nodes_for_capture_index
pub fn nodes_for_capture_index(
&self,
capture_ix: u32,
) -> impl Iterator<Item = Node<'tree>> + '_
Get all nodes for a given capture index within this match.
QueryCapture
A particular node that has been captured with a particular name within a query.
pub struct QueryCapture<'tree> {
pub node: Node<'tree>,
pub index: u32,
}
The index of the capture (use Query::capture_names() to get the name)
Supporting Types
CaptureQuantifier
Quantifiers for captures.
pub enum CaptureQuantifier {
Zero,
ZeroOrOne,
ZeroOrMore,
One,
OneOrMore,
}
QueryProperty
A key-value pair associated with a particular pattern in a query.
pub struct QueryProperty {
pub key: Box<str>,
pub value: Option<Box<str>>,
pub capture_id: Option<usize>,
}
QueryPredicate
A user-defined predicate associated with a pattern.
pub struct QueryPredicate {
pub operator: Box<str>,
pub args: Box<[QueryPredicateArg]>,
}
QueryPredicateArg
An argument to a query predicate.
pub enum QueryPredicateArg {
Capture(u32),
String(Box<str>),
}
Examples
Basic Query
use tree_sitter::{Query, QueryCursor, StreamingIterator};
let query = Query::new(
&language,
r#"
(function_item
name: (identifier) @function.name)
"#
)?;
let mut cursor = QueryCursor::new();
let matches = cursor.matches(&query, root_node, source.as_bytes());
for match_ in matches {
for capture in match_.captures {
let name = query.capture_names()[capture.index as usize];
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
println!("@{}: {}", name, text);
}
}
Query with Predicates
let query = Query::new(
&language,
r#"
(function_item
name: (identifier) @name
(#eq? @name "main"))
"#
)?;
let mut cursor = QueryCursor::new();
let mut matches = cursor.matches(&query, root_node, source.as_bytes());
while let Some(match_) = matches.next() {
println!("Found main function!");
}
Filtering by Range
let mut cursor = QueryCursor::new();
cursor.set_byte_range(100..500);
let matches = cursor.matches(&query, root_node, source.as_bytes());
// Only matches within bytes 100-500 will be returned
Using Captures Iterator
use tree_sitter::StreamingIterator;
let query = Query::new(
&language,
"(identifier) @id"
)?;
let mut cursor = QueryCursor::new();
let mut captures = cursor.captures(&query, root_node, source.as_bytes());
while let Some((match_, index)) = captures.next() {
let capture = &match_.captures[index];
let text = capture.node.utf8_text(source.as_bytes()).unwrap();
println!("Identifier: {}", text);
}