diff options
author | Yuan Fu <casouri@gmail.com> | 2022-12-26 17:16:59 -0800 |
---|---|---|
committer | Yuan Fu <casouri@gmail.com> | 2022-12-26 17:50:14 -0800 |
commit | a6d961ae2fd0eb93938f2afd932f4d3cb63a0412 (patch) | |
tree | bcdb59869539bdf0d1cee4c81a1e864171350551 /doc/lispref/parsing.texi | |
parent | 835a80dcc48c9c9d90709dcadbedb9afd6ded48c (diff) | |
download | emacs-a6d961ae2fd0eb93938f2afd932f4d3cb63a0412.tar.gz emacs-a6d961ae2fd0eb93938f2afd932f4d3cb63a0412.tar.bz2 emacs-a6d961ae2fd0eb93938f2afd932f4d3cb63a0412.zip |
Add a new tree-sitter query predicate 'pred'
I realized that using an arbitrary function as the predicate in
queries is very helpful for some queries I'm writing for python and
javascript, and presumably most other languages[1].
Granted, we can already filter out unwanted nodes by using a function
instead of a face for the capture name, and (1) determine whether the
captured node is valid and (2) fontify that node if it's valid.
However, such approach is a bit more cumbersome and more importantly
gets in the way of another potential use of the fontification queries:
context extraction.
For example, I could use the query for the 'variable' feature to get
all the variables in a certain region. In this use-case, we want the
filtering happen before returning the captured nodes.
Besides, the change is relatively small and straightforward: most code
are already there, I just need to add some boilerplate.
[1] For a code like aa.bb(cc), we want bb to be in function face,
because obviously its a function. But for aa.bb, we want bb to be in
property face, because it's a property. In the AST, bb is always a
property, the difference between the two cases is the enclosing node:
in the first case, aa.bb is in a "call_expression" node, indicating
that bb is used as a function (a method). So we want a predicate
function that checks whether bb is used as a function or a property,
and determine whether it should be in function or property face.
* doc/lispref/parsing.texi (Pattern Matching): Update manual.
* src/treesit.c (Ftreesit_pattern_expand): Handle :pred.
(treesit_predicate_capture_name_to_node): A new function extracted
from treesit_predicate_capture_name_to_text.
(treesit_predicate_capture_name_to_text): Use the newly extracted
function.
(treesit_predicate_pred): New predicate function.
(treesit_eval_predicates): Add new predicate. Also fix a bug: we want
to AND the results of each predicate.
* test/src/treesit-tests.el (treesit--ert-pred-last-sibling): New
helper function.
(treesit-query-api): Test #pred predicate.
Diffstat (limited to 'doc/lispref/parsing.texi')
-rw-r--r-- | doc/lispref/parsing.texi | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 5d1b11935cf..63741b69c22 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -1266,10 +1266,11 @@ example, with the following pattern: @end example @noindent -tree-sitter only matches arrays where the first element equals to -the last element. To attach a predicate to a pattern, we need to -group them together. A predicate always starts with a @samp{#}. -Currently there are two predicates, @code{#equal} and @code{#match}. +tree-sitter only matches arrays where the first element equals to the +last element. To attach a predicate to a pattern, we need to group +them together. A predicate always starts with a @samp{#}. Currently +there are three predicates, @code{#equal}, @code{#match}, and +@code{#pred}. @deffn Predicate equal arg1 arg2 Matches if @var{arg1} equals to @var{arg2}. Arguments can be either @@ -1282,6 +1283,11 @@ Matches if the text that @var{capture-name}'s node spans in the buffer matches regular expression @var{regexp}. Matching is case-sensitive. @end deffn +@deffn Predicate pred fn &rest nodes +Matches if function @var{fn} returns non-@code{nil} when passed each +node in @var{nodes} as arguments. +@end deffn + Note that a predicate can only refer to capture names that appear in the same pattern. Indeed, it makes little sense to refer to capture names in other patterns. |