]> git.eshelyaron.com Git - emacs.git/commitdiff
Use the treesit thing 'list' with symbol property 'treesit-thing-symbol'
authorJuri Linkov <juri@linkov.net>
Fri, 10 Jan 2025 07:33:49 +0000 (09:33 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sat, 11 Jan 2025 11:18:36 +0000 (12:18 +0100)
* doc/lispref/parsing.texi (User-defined Things): Mention new
functions 'treesit-forward-list', 'treesit-down-list',
'treesit-up-list', 'treesit-show-paren-data' that use the thing
'list' with the symbol property 'treesit-thing-symbol' (bug#73404).

* lisp/treesit.el: Put the property 'treesit-thing-symbol'
on the symbol 'list'.
(treesit--forward-list-with-default, treesit-down-list)
(treesit-up-list, treesit-navigate-thing)
(treesit-show-paren-data--categorize, treesit-major-mode-setup):
Replace 'sexp-list' with 'list'.

* lisp/progmodes/c-ts-mode.el (c-ts-mode--thing-settings):
* lisp/progmodes/js.el (js-ts-mode):
* lisp/progmodes/ruby-ts-mode.el (ruby-ts-mode):
* lisp/progmodes/typescript-ts-mode.el (typescript-ts-base-mode)
(tsx-ts-mode):
* lisp/textmodes/html-ts-mode.el (html-ts-mode):
Replace 'sexp-list' with 'list'.

* src/treesit.c (treesit_traverse_validate_predicate)
(treesit_traverse_match_predicate): Check if the 'pred'
symbol has the property 'Qtreesit_thing_symbol'.
(syms_of_treesit): New symbol 'Qtreesit_thing_symbol'.

(cherry picked from commit 42a5ac3b513ff03c64c9609fc7e79c2b7932b2a4)

doc/lispref/parsing.texi
etc/NEWS
lisp/progmodes/c-ts-mode.el
lisp/progmodes/js.el
lisp/progmodes/ruby-ts-mode.el
lisp/progmodes/typescript-ts-mode.el
lisp/textmodes/html-ts-mode.el
lisp/treesit.el
src/treesit.c

index f6680ea589cc01371dbdf3881d47ebad0437e2aa..e16aea6a38ddc809d1efc0e5e839df3ad13a5e48 100644 (file)
@@ -1628,10 +1628,14 @@ exactly how C and C@t{++} modes define things.
 
 Emacs builtin functions already make use some thing definitions.
 Command @code{treesit-forward-sexp} uses the @code{sexp} definition if
-major mode defines it; @code{treesit-forward-sentence} uses the
-@code{sentence} definition.  Defun movement functions like
-@code{treesit-end-of-defun} uses the @code{defun} definition
-(@code{defun} definition is overridden by
+major mode defines it; @code{treesit-forward-list},
+@code{treesit-down-list}, @code{treesit-up-list},
+@code{treesit-show-paren-data} use the @code{list} definition (its
+symbol @code{list} has the symbol property @code{treesit-thing-symbol}
+to avoid ambiguity with the function that has the same name);
+@code{treesit-forward-sentence} uses the @code{sentence} definition.
+Defun movement functions like @code{treesit-end-of-defun} uses the
+@code{defun} definition (@code{defun} definition is overridden by
 @var{treesit-defun-type-regexp} for backward compatibility).  Major
 modes can also define @code{comment}, @code{string}, @code{text}
 (generally comments and strings).
index 4387bb0010e9053e03ddd214b35c6e99d048e0b5..5787b0b6ad41306991bf10d717e80e1a7658e954 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -871,15 +871,15 @@ override flag by 'treesit-font-lock-setting-query',
 'treesit-font-lock-setting-feature', 'treesit-font-lock-setting-enable',
 and 'treesit-font-lock-setting-override'.
 
-*** New treesit thing 'sexp-list'.
+*** New treesit thing 'list'.
 Unlike the existing thing 'sexp' that defines both lists and atoms,
-'sexp-list' defines only lists to be navigated by 'forward-sexp'.
-The new function 'treesit-forward-sexp-list' uses 'sexp-list'
+'list' defines only lists to be navigated by 'forward-sexp'.
+The new function 'treesit-forward-sexp-list' uses 'list'
 to move across lists.  But to move across atoms inside the list
 it uses 'forward-sexp-default-function'.
 
-*** New tree-sitter based functions for moving by sexp-lists.
-If a major mode defines 'sexp-list' in 'treesit-thing-settings',
+*** New tree-sitter based functions for moving by lists.
+If a major mode defines 'list' in 'treesit-thing-settings',
 tree-sitter setup for these modes sets 'forward-list-function' to
 'treesit-forward-list', 'up-list-function' to 'treesit-up-list', and
 'down-list-function' to 'treesit-down-list'.  This enables the
index ac92032f92aa345fc26745ebd4c0aeadb87768f0..80e635fe76d4c159ad18b04ad03ed29c22b27794 100644 (file)
@@ -1151,7 +1151,7 @@ if `c-ts-mode-emacs-sources-support' is non-nil."
   `(;; It's more useful to include semicolons as sexp so
     ;; that users can move to the end of a statement.
     (sexp (not ,(rx (or "{" "}" "[" "]" "(" ")" ","))))
-    (sexp-list
+    (list
      ,(regexp-opt '("preproc_params"
                     "preproc_parenthesized_expression"
                     "preproc_argument_list"
index 26622ed4bec3cc031f32838064607630a203021d..635f6d8200e1e9a8d206ebca235346fd6432606a 100644 (file)
@@ -3873,7 +3873,7 @@ See `treesit-thing-settings' for more information.")
   "Nodes that designate sexps in JavaScript.
 See `treesit-thing-settings' for more information.")
 
-(defvar js--treesit-sexp-list-nodes
+(defvar js--treesit-list-nodes
   '("export_clause"
     "named_imports"
     "statement_block"
@@ -3936,7 +3936,7 @@ See `treesit-thing-settings' for more information.")
     (setq-local treesit-thing-settings
                 `((javascript
                    (sexp ,(js--regexp-opt-symbol js--treesit-sexp-nodes))
-                   (sexp-list ,(js--regexp-opt-symbol js--treesit-sexp-list-nodes))
+                   (list ,(js--regexp-opt-symbol js--treesit-list-nodes))
                    (sentence ,(js--regexp-opt-symbol js--treesit-sentence-nodes))
                    (text ,(js--regexp-opt-symbol '("comment"
                                                    "string_fragment"))))))
index a776abe881e94dfe64a711d4e9cd1daa516db159..15394f28b279e109c3c60a1abf02350b285bc9bb 100644 (file)
@@ -1132,7 +1132,7 @@ leading double colon is not added."
       (equal (treesit-node-type (treesit-node-child node 0))
              "(")))
 
-(defun ruby-ts--sexp-list-p (node)
+(defun ruby-ts--list-p (node)
   ;; Distinguish between the named `unless' node and the
   ;; node with the same value of type.
   (when (treesit-node-check node 'named)
@@ -1213,7 +1213,7 @@ leading double colon is not added."
                                 )
                                eol)
                               #'ruby-ts--sexp-p))
-                 (sexp-list
+                 (list
                   ,(cons (rx
                           bol
                           (or
@@ -1253,7 +1253,7 @@ leading double colon is not added."
                            "array"
                            "hash")
                           eol)
-                         #'ruby-ts--sexp-list-p))
+                         #'ruby-ts--list-p))
                  (text ,(lambda (node)
                           (or (member (treesit-node-type node)
                                       '("comment" "string_content" "heredoc_content"))
index 5b886b5da7f848367d6fb9b9432af081e78ec599..61ae8babbcefb217131539f84e5d0c4495a95893 100644 (file)
@@ -482,7 +482,7 @@ See `treesit-thing-settings' for more information.")
   "Nodes that designate sexps in TypeScript.
 See `treesit-thing-settings' for more information.")
 
-(defvar typescript-ts-mode--sexp-list-nodes
+(defvar typescript-ts-mode--list-nodes
   '("export_clause"
     "named_imports"
     "statement_block"
@@ -534,7 +534,7 @@ This mode is intended to be inherited by concrete major modes."
   (setq-local treesit-thing-settings
               `((typescript
                  (sexp ,(regexp-opt typescript-ts-mode--sexp-nodes 'symbols))
-                 (sexp-list ,(regexp-opt typescript-ts-mode--sexp-list-nodes
+                 (list ,(regexp-opt typescript-ts-mode--list-nodes
                                          'symbols))
                  (sentence ,(regexp-opt
                              typescript-ts-mode--sentence-nodes 'symbols))
@@ -619,9 +619,9 @@ at least 3 (which is the default value)."
                    (sexp ,(regexp-opt
                            (append typescript-ts-mode--sexp-nodes
                                    '("jsx"))))
-                   (sexp-list ,(concat "^"
+                   (list ,(concat "^"
                                        (regexp-opt
-                                        (append typescript-ts-mode--sexp-list-nodes
+                                        (append typescript-ts-mode--list-nodes
                                                 '(
                                                   "jsx_element"
                                                   "jsx_self_closing_element"
index b29e018cfb6a4e469a220805fdcd855866a6675b..dad49b7ed4ccf86bbf3c5aa4c9decdb75f006649 100644 (file)
@@ -117,7 +117,7 @@ Return nil if there is no name or if NODE is not a defun node."
                                       "text"
                                       "attribute"
                                       "value")))
-                 (sexp-list ,(regexp-opt '("element")) 'symbols)
+                 (list ,(regexp-opt '("element")) 'symbols)
                  (sentence "tag")
                  (text ,(regexp-opt '("comment" "text"))))))
 
index 888efeea239a9eb2861d41c7676575f437b13285..9e967c4a8f85ddc768d54bee88de5a0301828905 100644 (file)
@@ -2412,6 +2412,9 @@ delimits medium sized statements in the source code.  It is,
 however, smaller in scope than sentences.  This is used by
 `treesit-forward-sexp' and friends.")
 
+;; Avoid interpreting the symbol `list' as a function.
+(put 'list 'treesit-thing-symbol t)
+
 (defun treesit--scan-error (pred arg)
   (when-let* ((parent (treesit-thing-at (point) pred t))
               (boundary (treesit-node-child parent (if (> arg 0) -1 0))))
@@ -2435,7 +2438,7 @@ What constitutes as text and source code sexp is determined
 by `text' and `sexp' in `treesit-thing-settings'.
 
 There is an alternative implementation in `treesit-forward-sexp-list'
-that uses `sexp-list' in `treesit-thing-settings' to move only
+that uses `list' in `treesit-thing-settings' to move only
 across lists, whereas uses `forward-sexp-default-function' to move
 across atoms (such as symbols or words) inside the list."
   (interactive "^p")
@@ -2467,7 +2470,7 @@ Fall back to DEFAULT-FUNCTION as long as it doesn't cross
 the boundaries of the list.
 
 ARG is described in the docstring of `forward-list'."
-  (let* ((pred (or treesit-sexp-type-regexp 'sexp-list))
+  (let* ((pred (or treesit-sexp-type-regexp 'list))
          (arg (or arg 1))
          (cnt arg)
          (inc (if (> arg 0) 1 -1)))
@@ -2507,7 +2510,7 @@ ARG is described in the docstring of `forward-list'."
 
 Whereas `treesit-forward-sexp' moves across both lists and atoms
 using `sexp' in `treesit-thing-settings', this function uses
-`sexp-list' in `treesit-thing-settings' to move only across lists.
+`list' in `treesit-thing-settings' to move only across lists.
 But to move across atoms (such as symbols or words) inside the list
 it uses `forward-sexp-default-function' as long as it doesn't go
 outside of the boundaries of the current list.
@@ -2518,7 +2521,7 @@ ARG is described in the docstring of `forward-sexp-function'."
 
 (defun treesit-forward-list (&optional arg)
   "Move forward across a list.
-What constitutes a list is determined by `sexp-list' in
+What constitutes a list is determined by `list' in
 `treesit-thing-settings' that usually defines
 parentheses-like expressions.
 
@@ -2535,7 +2538,7 @@ ARG is described in the docstring of `forward-list-function'."
 (defun treesit-down-list (&optional arg)
   "Move forward down one level of parentheses.
 What constitutes a level of parentheses is determined by
-`sexp-list' in `treesit-thing-settings' that usually defines
+`list' in `treesit-thing-settings' that usually defines
 parentheses-like expressions.
 
 This command is the tree-sitter variant of `down-list'
@@ -2543,7 +2546,7 @@ redefined by the variable `down-list-function'.
 
 ARG is described in the docstring of `down-list'."
   (interactive "^p")
-  (let* ((pred 'sexp-list)
+  (let* ((pred 'list)
          (arg (or arg 1))
          (cnt arg)
          (inc (if (> arg 0) 1 -1)))
@@ -2575,7 +2578,7 @@ ARG is described in the docstring of `down-list'."
 (defun treesit-up-list (&optional arg escape-strings no-syntax-crossing)
   "Move forward out of one level of parentheses.
 What constitutes a level of parentheses is determined by
-`sexp-list' in `treesit-thing-settings' that usually defines
+`list' in `treesit-thing-settings' that usually defines
 parentheses-like expressions.
 
 This command is the tree-sitter variant of `up-list'
@@ -2583,7 +2586,7 @@ redefined by the variable `up-list-function'.
 
 ARG is described in the docstring of `up-list'."
   (interactive "^p")
-  (let* ((pred 'sexp-list)
+  (let* ((pred 'list)
          (arg (or arg 1))
          (cnt arg)
          (inc (if (> arg 0) 1 -1)))
@@ -3068,7 +3071,7 @@ function is called recursively."
               (setq pos (funcall
                          advance
                          (cond ((and (null next) (null prev)
-                                     (not (eq thing 'sexp-list)))
+                                     (not (eq thing 'list)))
                                 parent)
                                ((> arg 0) next)
                                (t prev))))
@@ -3413,9 +3416,9 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
 ;;; Show paren mode
 
 (defun treesit-show-paren-data--categorize (pos &optional end-p)
-  (let* ((pred 'sexp-list)
+  (let* ((pred 'list)
          (parent (when (treesit-thing-defined-p
-                        'sexp-list (treesit-language-at pos))
+                        pred (treesit-language-at pos))
                    (treesit-parent-until
                     (treesit-node-at (if end-p (1- pos) pos)) pred)))
          (first (when parent (treesit-node-child parent 0)))
@@ -3587,7 +3590,7 @@ before calling this function."
     (setq-local forward-sexp-function #'treesit-forward-sexp)
     (setq-local transpose-sexps-function #'treesit-transpose-sexps))
 
-  (when (treesit-thing-defined-p 'sexp-list nil)
+  (when (treesit-thing-defined-p 'list nil)
     (setq-local forward-sexp-function #'treesit-forward-sexp-list)
     (setq-local forward-list-function #'treesit-forward-list)
     (setq-local down-list-function #'treesit-down-list)
index b3214dad8367b448dcc7fe5d3a8a4f6106358743..878c1f0b3406ce22593cd3615775a3cc1de12610 100644 (file)
@@ -3618,7 +3618,8 @@ treesit_traverse_validate_predicate (Lisp_Object pred,
     }
   if (STRINGP (pred))
     return true;
-  else if (FUNCTIONP (pred))
+  else if (FUNCTIONP (pred)
+          && !(SYMBOLP (pred) && !NILP (Fget (pred, Qtreesit_thing_symbol))))
     return true;
   else if (SYMBOLP (pred))
     {
@@ -3722,7 +3723,8 @@ 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) && !NILP (Fget (pred, Qtreesit_thing_symbol))))
     {
       Lisp_Object lisp_node = make_treesit_node (parser, node);
       return !NILP (CALLN (Ffuncall, pred, lisp_node));
@@ -4333,6 +4335,8 @@ syms_of_treesit (void)
   DEFSYM (Qtreesit_invalid_predicate, "treesit-invalid-predicate");
   DEFSYM (Qtreesit_predicate_not_found, "treesit-predicate-not-found");
 
+  DEFSYM (Qtreesit_thing_symbol, "treesit-thing-symbol");
+
   DEFSYM (Qor, "or");
 
 #ifdef WINDOWSNT