summaryrefslogtreecommitdiff
path: root/doc/lispref/parsing.texi
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2022-12-26 17:16:59 -0800
committerYuan Fu <casouri@gmail.com>2022-12-26 17:50:14 -0800
commita6d961ae2fd0eb93938f2afd932f4d3cb63a0412 (patch)
treebcdb59869539bdf0d1cee4c81a1e864171350551 /doc/lispref/parsing.texi
parent835a80dcc48c9c9d90709dcadbedb9afd6ded48c (diff)
downloademacs-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.texi14
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.