@var{pred} can also be recursively defined. It can be @w{@code{(or
@var{pred}@dots{})}}, meaning that satisfying any one of the @var{pred}s
+qualifies the node as the thing. It can be @w{@code{(and
+@var{pred}@dots{})}}, meaning that satisfying all of the @var{pred}s
qualifies the node as the thing. It can be @w{@code{(not @var{pred})}},
meaning that not satisfying @var{pred} qualifies the node.
that's either a @code{sexp} thing or a @code{sentence} thing, as defined
by some other rule in the alist.
+There are two pre-defined predicates: @code{named} and @code{anonymous},
+that qualifies named and anonymous nodes, respectively. They can be
+combined with @code{and} to narrow down the match.
+
Here's an example @code{treesit-thing-settings} for C and C++:
@example
is @code{t}, this function doesn't signal the error when @var{thing} is
undefined and just returns @code{nil}; but it still signals the error if
@var{thing} is a malformed predicate.
-
@end defun
@defun treesit-thing-prev position thing
defining variables such as @code{forward-sexp-function} and
@code{forward-sentence-function}.
@end itemize
-
-@c TODO: Add treesit-thing-settings stuff once we finalize it.
@end defun
For more information on these built-in tree-sitter features,
return true;
else if (SYMBOLP (pred))
{
+ if (BASE_EQ (pred, Qnamed) || BASE_EQ (pred, Qanonymous))
+ return true;
+
Lisp_Object definition = treesit_traverse_get_predicate (pred,
language);
if (NILP (definition))
signal_data,
recursion_level + 1);
}
- else if (BASE_EQ (car, Qor))
+ else if (BASE_EQ (car, Qor) || BASE_EQ (car, Qand))
{
if (!CONSP (cdr) || NILP (cdr))
{
*signal_data = list3 (Qtreesit_invalid_predicate,
- build_string ("`or' must have a list "
- "of patterns as "
+ build_string ("`or' or `and' must have "
+ "a list of patterns as "
"arguments "),
pred);
return false;
Lisp_Object lisp_node = make_treesit_node (parser, node);
return !NILP (CALLN (Ffuncall, pred, lisp_node));
}
+ else if (SYMBOLP (pred) && BASE_EQ (pred, Qnamed))
+ {
+ return ts_node_is_named (node);
+ }
+ else if (SYMBOLP (pred) && BASE_EQ (pred, Qanonymous))
+ {
+ return !ts_node_is_named (node);
+ }
else if (SYMBOLP (pred))
{
Lisp_Object language = XTS_PARSER (parser)->language_symbol;
}
return false;
}
+ else if (BASE_EQ (car, Qand))
+ {
+ FOR_EACH_TAIL (cdr)
+ {
+ if (!treesit_traverse_match_predicate (cursor, XCAR (cdr),
+ parser, named))
+ return false;
+ }
+ return true;
+ }
else if (STRINGP (car) && FUNCTIONP (cdr))
{
/* A bit of code duplication here, but should be fine. */
DEFSYM (Qtreesit_compiled_query_p, "treesit-compiled-query-p");
DEFSYM (Qtreesit_query_p, "treesit-query-p");
DEFSYM (Qnamed, "named");
+ DEFSYM (Qanonymous, "anonymous");
DEFSYM (Qmissing, "missing");
DEFSYM (Qextra, "extra");
DEFSYM (Qoutdated, "outdated");
DEFSYM (Qtreesit_thing_symbol, "treesit-thing-symbol");
DEFSYM (Qor, "or");
+ DEFSYM (Qand, "and");
#ifdef WINDOWSNT
DEFSYM (Qtree_sitter, "tree-sitter");
function, and the node has to match both to qualify as the thing.
PRED can also be recursively defined. It can be (or PRED...), meaning
-satisfying anyone of the inner PREDs qualifies the node; or (not
-PRED), meaning not satisfying the inner PRED qualifies the node.
+satisfying anyone of the inner PREDs qualifies the node; or (and
+PRED...) meaning satisfying all of the inner PREDs qualifies the node;
+or (not PRED), meaning not satisfying the inner PRED qualifies the node.
+
+There are two pre-defined predicates, `named' and `anonymous`. They
+match named nodes and anonymous nodes, respectively.
Finally, PRED can refer to other THINGs defined in this list by using
the symbol of that THING. For example, (or sexp sentence). */);