1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-05 22:20:24 -08:00

Change tree-sitter query predicate names (bug#79687)

Latest tree-sitter library throws a syntax error if the
predicate names in a query don't end with question mark.  So we
made the following change:

:equal changed to :eq?
:match changed to :match?
:pred changed to :pred?

Old names are transparently converted to new names when
expanding patterns.

:match predicate can now take the regexp and the node in any
order: it'll figure out which is which automatically. This way
it works with current Emacs convention (regexp first), as well
as tree-sitter's match convention (regexp second).

* doc/lispref/parsing.texi (Pattern Matching): Update manuel to
use new predicate names.
* src/treesit.c:
(Ftreesit_pattern_expand):
(Ftreesit_query_expand):
(treesit_predicate_match):
(treesit_eval_predicates):
(syms_of_treesit): Use new predicate names.
* test/src/treesit-tests.el (treesit-query-api): Update test.
This commit is contained in:
Yuan Fu 2025-11-02 16:16:50 -08:00
parent 68290e1a03
commit b01435306a
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
4 changed files with 83 additions and 59 deletions

View file

@ -1473,7 +1473,7 @@ example, with the following pattern:
@group
(
(array :anchor (_) @@first (_) @@last :anchor)
(:equal @@first @@last)
(:eq? @@first @@last)
)
@end group
@end example
@ -1482,24 +1482,32 @@ example, with the following pattern:
tree-sitter only matches arrays where the first element is equal to
the last element. To attach a predicate to a pattern, we need to
group them together. Currently there are three predicates:
@code{:equal}, @code{:match}, and @code{:pred}.
@code{:eq?}, @code{:match?}, and @code{:pred?}.
@deffn Predicate :equal arg1 arg2
@deffn Predicate :eq? arg1 arg2
Matches if @var{arg1} is equal to @var{arg2}. Arguments can be either
strings or capture names. Capture names represent the text that the
captured node spans in the buffer.
captured node spans in the buffer. Note that this is more like
@code{equal} in Elisp, but @code{eq?} is the convention used by
tree-sitter. Previously we supported the @code{:equal} predicate but
it's now considered deprecated.
@end deffn
@deffn Predicate :match regexp capture-name
@deffn Predicate :match? capture-name regexp
Matches if the text that @var{capture-name}'s node spans in the buffer
matches regular expression @var{regexp}, given as a string literal.
Matching is case-sensitive.
Matching is case-sensitive. The ordering of the arguments doesn't
matter. Previously we supported the @code{:match} predicate but it's
now considered deprecated.
@end deffn
@deffn Predicate :pred fn &rest nodes
@deffn Predicate :pred? fn &rest nodes
Matches if function @var{fn} returns non-@code{nil} when passed each
node in @var{nodes} as arguments. The function runs with the current
buffer set to the buffer of node being queried.
buffer set to the buffer of node being queried. Be very careful when
using this predicate, since it can be expensive when used in a tight
loop. Previously we supported the @code{:pred} predicate but it's now
considered deprecated.
@end deffn
Note that a predicate can only refer to capture names that appear in
@ -1554,9 +1562,9 @@ Anchor @code{:anchor} is written as @samp{.}.
@item
@samp{:+} is written as @samp{+}.
@item
@code{:equal}, @code{:match} and @code{:pred} are written as
@code{#equal}, @code{#match} and @code{#pred}, respectively.
In general, predicates change their @samp{:} to @samp{#}.
@code{:eq?}, @code{:match?} and @code{:pred?} are written as
@code{#eq?}, @code{#match?} and @code{#pred?}, respectively. In
general, predicates change the @samp{:} to @samp{#}.
@end itemize
For example,
@ -1565,7 +1573,7 @@ For example,
@group
'((
(compound_expression :anchor (_) @@first (_) :* @@rest)
(:match "love" @@first)
(:match? "love" @@first)
))
@end group
@end example
@ -1577,7 +1585,7 @@ is written in string form as
@group
"(
(compound_expression . (_) @@first (_)* @@rest)
(#match \"love\" @@first)
(#match? \"love\" @@first)
)"
@end group
@end example