Home Explore Blog CI



neovim

3rd chunk of `runtime/doc/treesitter.txt`
2f9f12808cea463f53484fa1153964f104362b52259309ad0000000100000fa6
            *treesitter-predicate-any-of?*
        Match any of the given strings against the text corresponding to
        a node: >query
            ((identifier) @foo (#any-of? @foo "foo" "bar"))
<
        This is the recommended way to check if the node matches one of many
        keywords, as it has been optimized for this.

    `has-ancestor?`                        *treesitter-predicate-has-ancestor?*
        Match any of the given node types against all ancestors of a node: >query
            ((identifier) @variable.builtin
              (#any-of? @variable.builtin "begin" "end")
              (#has-ancestor? @variable.builtin range_expression))
<
    `has-parent?`                            *treesitter-predicate-has-parent?*
        Match any of the given node types against the direct ancestor of a
        node: >query
            (((field_expression
                 (field_identifier) @method)) @_parent
             (#has-parent? @_parent template_method function_declarator))
<
                                                    *treesitter-predicate-not*
Each predicate has a `not-` prefixed predicate that is just the negation of
the predicate.

                                                    *treesitter-predicate-all*
                                                    *treesitter-predicate-any*
Queries can use quantifiers to capture multiple nodes. When a capture contains
multiple nodes, predicates match only if ALL nodes contained by the capture
match the predicate. Some predicates (`eq?`, `match?`, `lua-match?`,
`contains?`) accept an `any-` prefix to instead match if ANY of the nodes
contained by the capture match the predicate.

As an example, consider the following Lua code: >lua

  -- TODO: This is a
  -- very long
  -- comment (just imagine it)
<
using the following predicated query:
>query
    (((comment)+ @comment)
     (#match? @comment "TODO"))
<
This query will not match because not all of the nodes captured by @comment
match the predicate. Instead, use:
>query
    (((comment)+ @comment)
     (#any-match? @comment "TODO"))
<

Further predicates can be added via |vim.treesitter.query.add_predicate()|.
Use |vim.treesitter.query.list_predicates()| to list all available predicates.


TREESITTER QUERY DIRECTIVES                            *treesitter-directives*

Treesitter directives store metadata for a node or match and perform side
effects. For example, the `set!` directive sets metadata on the match or node: >query

        ((identifier) @foo (#set! type "parameter"))
<
The following directives are built in:

    `set!`                                          *treesitter-directive-set!*
        Sets key/value metadata for a specific match or capture. Value is
        accessible as either `metadata[key]` (match specific) or
        `metadata[capture_id][key]` (capture specific).

        Parameters: ~
            {capture_id} (optional)
            {key}
            {value}

        Examples: >query
            ((identifier) @foo (#set! @foo kind "parameter"))
            ((node1) @left (node2) @right (#set! type "pair"))
            ((codeblock) @markup.raw.block (#set! priority 90))
<
    `offset!`                                      *treesitter-directive-offset!*
        Takes the range of the captured node and applies an offset. This will
        set a new range in the form of a list like { {start_row}, {start_col},
        {end_row}, {end_col} } for the captured node with `capture_id` as
        `metadata[capture_id].range`. Useful for |treesitter-language-injections|.

        Parameters: ~
            {capture_id}
            {start_row}
            {start_col}
            {end_row}
            {end_col}

        Example: >query
            ((identifier) @constant (#offset! @constant 0 1 0 -1))
<
    `gsub!`                                          *treesitter-directive-gsub!*
        Transforms the content of the node using a |lua-pattern|. This will set
        a new `metadata[capture_id].text`.

Title: Treesitter Query Predicates (Continued) and Directives
Summary
This section continues the explanation of Treesitter query predicates, covering `has-ancestor?` and `has-parent?`, and introduces negated predicates using `not-`. It explains the use of quantifiers with predicates, highlighting the difference between `any-` prefixed predicates and regular predicates when matching multiple nodes. The section then transitions to Treesitter query directives, which are used to store metadata or perform side effects. It details the built-in directives `set!` for setting metadata, `offset!` for adjusting node ranges, and `gsub!` for transforming node content using Lua patterns. Examples are provided for each directive to illustrate their usage.