Subject: Re: bug#73404: 30.0.50; [forward/kill/etc]-sexp commands do not behave as expected in tree-sitter modes

From: Juri Linkov <[email-masked]>
Date: Sun, 05 Jan 2025 09:37:49 +0200

> The minimal change that doesn't require updating
> all existing definitions of treesit-thing-settings,
> is just to add an exception for 'list':
> [...]
> @@ -3618,7 +3618,7 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
> -  else if (FUNCTIONP (pred))
> +  else if (FUNCTIONP (pred) && !BASE_EQ (pred, Qlist))

I admit that hard-coding one symbol is not the right thing to do.
So here is a better patch that checks for the symbol property:

diff --git a/lisp/treesit.el b/lisp/treesit.el
index e643eb48654..169607b150e 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -2516,6 +2516,8 @@ treesit-forward-sexp-list
             (treesit--scan-error pred arg)))
       (setq cnt (- cnt inc)))))
 
+(put 'list 'treesit-predicate t)
+
 (defun treesit-forward-list (&optional arg)
   "Move forward across a list.
 What constitutes a list is determined by `sexp-list' in
diff --git a/src/treesit.c b/src/treesit.c
index b3214dad836..4d2cd45e1b2 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -3618,7 +3618,7 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
     }
   if (STRINGP (pred))
     return true;
-  else if (FUNCTIONP (pred))
+  else if (FUNCTIONP (pred) && !(SYMBOLP (pred) && Fget (pred, Qtreesit_predicate)))
     return true;
   else if (SYMBOLP (pred))
     {
@@ -3722,7 +3722,7 @@ treesit_traverse_match_predicate (TSTreeCursor *cursor, Lisp_Object pred,
       const char *type = ts_node_type (node);
       return fast_c_string_match (pred, type, strlen (type)) >= 0;
     }
-  else if (FUNCTIONP (pred))
+  else if (FUNCTIONP (pred) && !(SYMBOLP (pred) && Fget (pred, Qtreesit_predicate)))
     {
       Lisp_Object lisp_node = make_treesit_node (parser, node);
       return !NILP (CALLN (Ffuncall, pred, lisp_node));
@@ -4333,6 +4333,8 @@ syms_of_treesit (void)
   DEFSYM (Qtreesit_invalid_predicate, "treesit-invalid-predicate");
   DEFSYM (Qtreesit_predicate_not_found, "treesit-predicate-not-found");
 
+  DEFSYM (Qtreesit_predicate, "treesit-predicate");
+
   DEFSYM (Qor, "or");
 
 #ifdef WINDOWSNT