]> git.eshelyaron.com Git - emacs.git/commit
Add a new tree-sitter query predicate 'pred'
authorYuan Fu <casouri@gmail.com>
Tue, 27 Dec 2022 01:16:59 +0000 (17:16 -0800)
committerYuan Fu <casouri@gmail.com>
Tue, 27 Dec 2022 01:50:14 +0000 (17:50 -0800)
commita6d961ae2fd0eb93938f2afd932f4d3cb63a0412
treebcdb59869539bdf0d1cee4c81a1e864171350551
parent835a80dcc48c9c9d90709dcadbedb9afd6ded48c
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.
doc/lispref/parsing.texi
src/treesit.c
test/src/treesit-tests.el