aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2025-01-12 23:41:47 -0800
committerYuan Fu2025-01-12 23:41:47 -0800
commitf0e63558bd3dfd9e57cacfba8690f9dd29774947 (patch)
tree6dc0c6eeab5a926050eb1ced319909b11fb26b8f
parent4687fff4f0a473fd887bf0800976c356eecd7eb2 (diff)
downloademacs-f0e63558bd3dfd9e57cacfba8690f9dd29774947.tar.gz
emacs-f0e63558bd3dfd9e57cacfba8690f9dd29774947.zip
Add 'and', 'named', and 'anonymous' predicate for tree-sitter
* doc/lispref/parsing.texi (User-defined Things): Mention the new predicate. * src/treesit.c (treesit_traverse_validate_predicate): Recognize named, anonymous, and and predicates. (treesit_traverse_match_predicate): Handle named, anonymous, and and predicates.
-rw-r--r--doc/lispref/parsing.texi9
-rw-r--r--src/treesit.c37
2 files changed, 38 insertions, 8 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index e16aea6a38d..3e44f31c12c 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -1596,6 +1596,8 @@ the thing.
1596 1596
1597@var{pred} can also be recursively defined. It can be @w{@code{(or 1597@var{pred} can also be recursively defined. It can be @w{@code{(or
1598@var{pred}@dots{})}}, meaning that satisfying any one of the @var{pred}s 1598@var{pred}@dots{})}}, meaning that satisfying any one of the @var{pred}s
1599qualifies the node as the thing. It can be @w{@code{(and
1600@var{pred}@dots{})}}, meaning that satisfying all of the @var{pred}s
1599qualifies the node as the thing. It can be @w{@code{(not @var{pred})}}, 1601qualifies the node as the thing. It can be @w{@code{(not @var{pred})}},
1600meaning that not satisfying @var{pred} qualifies the node. 1602meaning that not satisfying @var{pred} qualifies the node.
1601 1603
@@ -1604,6 +1606,10 @@ list. For example, @w{@code{(or sexp sentence)}} defines something
1604that's either a @code{sexp} thing or a @code{sentence} thing, as defined 1606that's either a @code{sexp} thing or a @code{sentence} thing, as defined
1605by some other rule in the alist. 1607by some other rule in the alist.
1606 1608
1609There are two pre-defined predicates: @code{named} and @code{anonymous},
1610that qualifies named and anonymous nodes, respectively. They can be
1611combined with @code{and} to narrow down the match.
1612
1607Here's an example @code{treesit-thing-settings} for C and C++: 1613Here's an example @code{treesit-thing-settings} for C and C++:
1608 1614
1609@example 1615@example
@@ -1662,7 +1668,6 @@ signals @code{treesit-invalid-predicate} error. If @var{ignore-missing}
1662is @code{t}, this function doesn't signal the error when @var{thing} is 1668is @code{t}, this function doesn't signal the error when @var{thing} is
1663undefined and just returns @code{nil}; but it still signals the error if 1669undefined and just returns @code{nil}; but it still signals the error if
1664@var{thing} is a malformed predicate. 1670@var{thing} is a malformed predicate.
1665
1666@end defun 1671@end defun
1667 1672
1668@defun treesit-thing-prev position thing 1673@defun treesit-thing-prev position thing
@@ -2179,8 +2184,6 @@ navigation commands that move, respectively, by sexps and sentences by
2179defining variables such as @code{forward-sexp-function} and 2184defining variables such as @code{forward-sexp-function} and
2180@code{forward-sentence-function}. 2185@code{forward-sentence-function}.
2181@end itemize 2186@end itemize
2182
2183@c TODO: Add treesit-thing-settings stuff once we finalize it.
2184@end defun 2187@end defun
2185 2188
2186For more information on these built-in tree-sitter features, 2189For more information on these built-in tree-sitter features,
diff --git a/src/treesit.c b/src/treesit.c
index 878c1f0b340..918b1a510ea 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -3623,6 +3623,9 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
3623 return true; 3623 return true;
3624 else if (SYMBOLP (pred)) 3624 else if (SYMBOLP (pred))
3625 { 3625 {
3626 if (BASE_EQ (pred, Qnamed) || BASE_EQ (pred, Qanonymous))
3627 return true;
3628
3626 Lisp_Object definition = treesit_traverse_get_predicate (pred, 3629 Lisp_Object definition = treesit_traverse_get_predicate (pred,
3627 language); 3630 language);
3628 if (NILP (definition)) 3631 if (NILP (definition))
@@ -3667,13 +3670,13 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
3667 signal_data, 3670 signal_data,
3668 recursion_level + 1); 3671 recursion_level + 1);
3669 } 3672 }
3670 else if (BASE_EQ (car, Qor)) 3673 else if (BASE_EQ (car, Qor) || BASE_EQ (car, Qand))
3671 { 3674 {
3672 if (!CONSP (cdr) || NILP (cdr)) 3675 if (!CONSP (cdr) || NILP (cdr))
3673 { 3676 {
3674 *signal_data = list3 (Qtreesit_invalid_predicate, 3677 *signal_data = list3 (Qtreesit_invalid_predicate,
3675 build_string ("`or' must have a list " 3678 build_string ("`or' or `and' must have "
3676 "of patterns as " 3679 "a list of patterns as "
3677 "arguments "), 3680 "arguments "),
3678 pred); 3681 pred);
3679 return false; 3682 return false;
@@ -3729,6 +3732,14 @@ treesit_traverse_match_predicate (TSTreeCursor *cursor, Lisp_Object pred,
3729 Lisp_Object lisp_node = make_treesit_node (parser, node); 3732 Lisp_Object lisp_node = make_treesit_node (parser, node);
3730 return !NILP (CALLN (Ffuncall, pred, lisp_node)); 3733 return !NILP (CALLN (Ffuncall, pred, lisp_node));
3731 } 3734 }
3735 else if (SYMBOLP (pred) && BASE_EQ (pred, Qnamed))
3736 {
3737 return ts_node_is_named (node);
3738 }
3739 else if (SYMBOLP (pred) && BASE_EQ (pred, Qanonymous))
3740 {
3741 return !ts_node_is_named (node);
3742 }
3732 else if (SYMBOLP (pred)) 3743 else if (SYMBOLP (pred))
3733 { 3744 {
3734 Lisp_Object language = XTS_PARSER (parser)->language_symbol; 3745 Lisp_Object language = XTS_PARSER (parser)->language_symbol;
@@ -3755,6 +3766,16 @@ treesit_traverse_match_predicate (TSTreeCursor *cursor, Lisp_Object pred,
3755 } 3766 }
3756 return false; 3767 return false;
3757 } 3768 }
3769 else if (BASE_EQ (car, Qand))
3770 {
3771 FOR_EACH_TAIL (cdr)
3772 {
3773 if (!treesit_traverse_match_predicate (cursor, XCAR (cdr),
3774 parser, named))
3775 return false;
3776 }
3777 return true;
3778 }
3758 else if (STRINGP (car) && FUNCTIONP (cdr)) 3779 else if (STRINGP (car) && FUNCTIONP (cdr))
3759 { 3780 {
3760 /* A bit of code duplication here, but should be fine. */ 3781 /* A bit of code duplication here, but should be fine. */
@@ -4297,6 +4318,7 @@ syms_of_treesit (void)
4297 DEFSYM (Qtreesit_compiled_query_p, "treesit-compiled-query-p"); 4318 DEFSYM (Qtreesit_compiled_query_p, "treesit-compiled-query-p");
4298 DEFSYM (Qtreesit_query_p, "treesit-query-p"); 4319 DEFSYM (Qtreesit_query_p, "treesit-query-p");
4299 DEFSYM (Qnamed, "named"); 4320 DEFSYM (Qnamed, "named");
4321 DEFSYM (Qanonymous, "anonymous");
4300 DEFSYM (Qmissing, "missing"); 4322 DEFSYM (Qmissing, "missing");
4301 DEFSYM (Qextra, "extra"); 4323 DEFSYM (Qextra, "extra");
4302 DEFSYM (Qoutdated, "outdated"); 4324 DEFSYM (Qoutdated, "outdated");
@@ -4338,6 +4360,7 @@ syms_of_treesit (void)
4338 DEFSYM (Qtreesit_thing_symbol, "treesit-thing-symbol"); 4360 DEFSYM (Qtreesit_thing_symbol, "treesit-thing-symbol");
4339 4361
4340 DEFSYM (Qor, "or"); 4362 DEFSYM (Qor, "or");
4363 DEFSYM (Qand, "and");
4341 4364
4342#ifdef WINDOWSNT 4365#ifdef WINDOWSNT
4343 DEFSYM (Qtree_sitter, "tree-sitter"); 4366 DEFSYM (Qtree_sitter, "tree-sitter");
@@ -4420,8 +4443,12 @@ cons (REGEXP . FN), which is a combination of a regexp and a predicate
4420function, and the node has to match both to qualify as the thing. 4443function, and the node has to match both to qualify as the thing.
4421 4444
4422PRED can also be recursively defined. It can be (or PRED...), meaning 4445PRED can also be recursively defined. It can be (or PRED...), meaning
4423satisfying anyone of the inner PREDs qualifies the node; or (not 4446satisfying anyone of the inner PREDs qualifies the node; or (and
4424PRED), meaning not satisfying the inner PRED qualifies the node. 4447PRED...) meaning satisfying all of the inner PREDs qualifies the node;
4448or (not PRED), meaning not satisfying the inner PRED qualifies the node.
4449
4450There are two pre-defined predicates, `named' and `anonymous`. They
4451match named nodes and anonymous nodes, respectively.
4425 4452
4426Finally, PRED can refer to other THINGs defined in this list by using 4453Finally, PRED can refer to other THINGs defined in this list by using
4427the symbol of that THING. For example, (or sexp sentence). */); 4454the symbol of that THING. For example, (or sexp sentence). */);