Use the treesit thing 'list' with symbol property 'treesit-thing-symbol'
* 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'.
This commit is contained in:
parent
351b6ac16d
commit
42a5ac3b51
9 changed files with 45 additions and 34 deletions
|
@ -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).
|
||||
|
|
10
etc/NEWS
10
etc/NEWS
|
@ -1024,15 +1024,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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -3876,7 +3876,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"
|
||||
|
@ -3941,7 +3941,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"))))))
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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"
|
||||
|
@ -536,7 +536,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))
|
||||
|
@ -621,9 +621,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"
|
||||
|
|
|
@ -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"))))))
|
||||
|
||||
|
|
|
@ -2420,6 +2420,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))))
|
||||
|
@ -2443,7 +2446,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")
|
||||
|
@ -2475,7 +2478,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)))
|
||||
|
@ -2515,7 +2518,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.
|
||||
|
@ -2526,7 +2529,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.
|
||||
|
||||
|
@ -2543,7 +2546,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'
|
||||
|
@ -2551,7 +2554,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)))
|
||||
|
@ -2583,7 +2586,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'
|
||||
|
@ -2591,7 +2594,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)))
|
||||
|
@ -3076,7 +3079,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))))
|
||||
|
@ -3420,9 +3423,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)))
|
||||
|
@ -3594,7 +3597,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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue