}
/* Validate the PRED passed to treesit_traverse_match_predicate. If
- there's an error, set SIGNAL_DATA to something signal accepts, and
- return false, otherwise return true. This function also check for
+ there's an error, set SIGNAL_DATA to (ERR . DATA), where ERR is an
+ error symbol, and DATA is something signal accepts, and return
+ false, otherwise return true. This function also check for
recusion levels: we place a arbitrary 100 level limit on recursive
predicates. RECURSION_LEVEL is the current recursion level (that
starts at 0), if it goes over 99, return false and set SIGNAL_DATA.
- LANGUAGE is a LANGUAGE symbol. IGNORE_MISSING is as in
- `treesit-node-match-p' below. */
+ LANGUAGE is a LANGUAGE symbol. */
static bool
treesit_traverse_validate_predicate (Lisp_Object pred,
Lisp_Object language,
Lisp_Object *signal_data,
- ptrdiff_t recursion_level,
- bool ignore_missing)
+ ptrdiff_t recursion_level)
{
if (recursion_level > 99)
{
- *signal_data = list1 (build_string ("Predicate recursion level "
+ *signal_data = list2 (Qtreesit_invalid_predicate,
+ build_string ("Predicate recursion level "
"exceeded: it must not exceed "
"100 levels"));
return false;
language);
if (NILP (definition))
{
- if (ignore_missing)
- return false;
- *signal_data = list2 (build_string ("Cannot find the definition "
+ *signal_data = list3 (Qtreesit_predicate_not_found,
+ build_string ("Cannot find the definition "
"of the predicate in "
"`treesit-thing-settings'"),
pred);
return treesit_traverse_validate_predicate (definition,
language,
signal_data,
- recursion_level + 1,
- ignore_missing);
+ recursion_level + 1);
}
else if (CONSP (pred))
{
{
if (!CONSP (cdr))
{
- *signal_data = list2 (build_string ("Invalide `not' "
+ *signal_data = list3 (Qtreesit_invalid_predicate,
+ build_string ("Invalide `not' "
"predicate"),
pred);
return false;
/* At this point CDR must be a cons. */
if (XFIXNUM (Flength (cdr)) != 1)
{
- *signal_data = list2 (build_string ("`not' can only "
+ *signal_data = list3 (Qtreesit_invalid_predicate,
+ build_string ("`not' can only "
"have one argument"),
pred);
return false;
return treesit_traverse_validate_predicate (XCAR (cdr),
language,
signal_data,
- recursion_level + 1,
- ignore_missing);
+ recursion_level + 1);
}
else if (BASE_EQ (car, Qor))
{
if (!CONSP (cdr) || NILP (cdr))
{
- *signal_data = list2 (build_string ("`or' must have a list "
+ *signal_data = list3 (Qtreesit_invalid_predicate,
+ build_string ("`or' must have a list "
"of patterns as "
"arguments "),
pred);
if (!treesit_traverse_validate_predicate (XCAR (cdr),
language,
signal_data,
- recursion_level + 1,
- ignore_missing))
+ recursion_level + 1))
return false;
}
return true;
else if (STRINGP (car) && FUNCTIONP (cdr))
return true;
}
- *signal_data = list2 (build_string ("Invalid predicate, see `treesit-thing-settings' for valid forms of predicate"),
+ *signal_data = list3 (Qtreesit_invalid_predicate,
+ build_string ("Invalid predicate, see `treesit-thing-settings' for valid forms of predicate"),
pred);
return false;
}
the way. PREDICATE can be a regexp string that matches against each
node's type, a predicate function, and more. See
`treesit-thing-settings' for the possible predicates. PREDICATE can
-also be a thing defined in `treesit-thing-settings'.
+also be a thing defined in `treesit-thing-settings'. Using an
+undefined thing doesn't raise an error.
By default, only traverse named nodes, but if ALL is non-nil, traverse
all nodes. If BACKWARD is non-nil, traverse backwards. If DEPTH is
Lisp_Object signal_data = Qnil;
if (!treesit_traverse_validate_predicate (predicate, language,
- &signal_data, 0, false))
- xsignal1 (Qtreesit_invalid_predicate, signal_data);
+ &signal_data, 0))
+ {
+ Lisp_Object err_symbol = XCAR (signal_data);
+ Lisp_Object data = XCDR (signal_data);
+ if (EQ (err_symbol, Qtreesit_predicate_not_found))
+ return Qnil;
+ xsignal1 (err_symbol, data);
+ }
Lisp_Object return_value = Qnil;
TSTreeCursor cursor;
regexp string that matches against each node's type, a predicate
function, and more. See `treesit-thing-settings' for the possible
predicates. PREDICATE can also be a thing defined in
-`treesit-thing-settings'.
+`treesit-thing-settings'. Using an undefined thing doesn't raise an
+error.
By default, only search for named nodes, but if ALL is non-nil, search
for all nodes. If BACKWARD is non-nil, search backwards.
Lisp_Object signal_data = Qnil;
if (!treesit_traverse_validate_predicate (predicate, language,
- &signal_data, 0, false))
- xsignal1 (Qtreesit_invalid_predicate, signal_data);
+ &signal_data, 0))
+ {
+ Lisp_Object err_symbol = XCAR (signal_data);
+ Lisp_Object data = XCDR (signal_data);
+ if (EQ (err_symbol, Qtreesit_predicate_not_found))
+ return Qnil;
+ xsignal1 (err_symbol, data);
+ }
Lisp_Object return_value = Qnil;
TSTreeCursor cursor;
PREDICATE can be a regexp string that matches against each node's
type, a predicate function, and more. See `treesit-thing-settings'
for the possible predicates. PREDICATE can also be a thing defined in
-`treesit-thing-settings'.
+`treesit-thing-settings'. Using an undefined thing doesn't raise an
+error.
For a subtree on the left that consist of both numbers and letters, if
PREDICATE is "is letter", the returned tree is the one on the right.
Lisp_Object signal_data = Qnil;
if (!treesit_traverse_validate_predicate (predicate, language,
- &signal_data, 0, false))
- xsignal1 (Qtreesit_invalid_predicate, signal_data);
+ &signal_data, 0))
+ {
+ Lisp_Object err_symbol = XCAR (signal_data);
+ Lisp_Object data = XCDR (signal_data);
+ if (EQ (err_symbol, Qtreesit_predicate_not_found))
+ return Qnil;
+ xsignal1 (err_symbol, data);
+ }
Lisp_Object parent = Fcons (Qnil, Qnil);
/* In this function we never traverse above NODE, so we don't need
Lisp_Object signal_data = Qnil;
if (!treesit_traverse_validate_predicate (predicate, language,
- &signal_data, 0,
- !NILP (ignore_missing)))
- xsignal1 (Qtreesit_invalid_predicate, signal_data);
+ &signal_data, 0))
+ {
+ Lisp_Object err_symbol = XCAR (signal_data);
+ Lisp_Object data = XCDR (signal_data);
+
+ if (!NILP (ignore_missing)
+ && EQ (err_symbol, Qtreesit_predicate_not_found))
+ return Qnil;
+
+ xsignal1 (err_symbol, data);
+ }
TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (node)->node);
DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted");
DEFSYM (Qtreesit_pattern_expand, "treesit-pattern-expand");
DEFSYM (Qtreesit_invalid_predicate, "treesit-invalid-predicate");
+ DEFSYM (Qtreesit_predicate_not_found, "treesit-predicate-not-found");
DEFSYM (Qor, "or");