Add treesit-forward-sexp (bug#60894)

* lisp/progmodes/java-ts-mode.el (java-ts-mode): Use
treesit-sexp-type-regexp.
* lisp/treesit.el (treesit-sexp-type-regexp): New defvar.
(treesit-forward-sexp): New command.
(treesit-major-mode-setup): Conditionally set forward-sexp-function.
* lisp/progmodes/ruby-ts-mode.el: Add some types to ruby-ts-mode.
* doc/lispref/positions.texi (List Motion): Mention the change in the
manual.
* etc/NEWS: Mention the change.
This commit is contained in:
Theodor Thornhill 2023-01-17 21:18:29 +01:00
parent 03a8d132b0
commit 207901457c
5 changed files with 72 additions and 0 deletions

View file

@ -875,6 +875,23 @@ by using @code{forward-sentence} and
@code{backward-sentence}(@pxref{Moving by Sentences,,, emacs, The
extensible self-documenting text editor}).
@defvar treesit-sexp-type-regexp
The value of this variable is a regexp matching the node type of sexp
nodes. (For ``node'' and ``node type'', @pxref{Parsing Program
Source}.)
@end defvar
@findex treesit-forward-sexp
@findex forward-sexp@r{, and tree-sitter}
@findex backward-sexp@r{, and tree-sitter}
If Emacs is compiled with tree-sitter, it can use the tree-sitter
parser information to move across syntax constructs. Since what
exactly is considered a sexp varies between languages, a major mode
should set @code{treesit-sexp-type-regexp} to determine that. Then
the mode can get navigation-by-sexp functionality for free, by using
@code{forward-sexp} and @code{backward-sexp}(@pxref{Moving by
Sentences,,, emacs, The extensible self-documenting text editor}).
@node Skipping Characters
@subsection Skipping Characters
@cindex skipping characters

View file

@ -84,6 +84,15 @@ define "sentences" in Tree-sitter enabled modes.
All tree-sitter modes that define 'treesit-sentence-type-regexp' now
set 'forward-sentence-function' to call 'treesit-forward-sentence'.
*** New defvar-local 'treesit-sexp-type-regexp'.
Similarly to 'treesit-defun-type-regexp', this variable is used to
define "sexps" in Tree-sitter enabled modes.
*** New function 'treesit-forward-sexp'.
treesit.el conditionally sets 'forward-sexp-function` for major modes
that have defined 'treesit-sexp-type-regexp' to enable sexp-related
motion commands.
* Changes in Specialized Modes and Packages in Emacs 30.1
---

View file

@ -328,6 +328,21 @@ Return nil if there is no name or if NODE is not a defun node."
"package_declaration"
"import_declaration")))
(setq-local treesit-sexp-type-regexp
(regexp-opt '("annotation"
"parenthesized_expression"
"argument_list"
"identifier"
"modifiers"
"block"
"body"
"literal"
"access"
"reference"
"_type"
"true"
"false")))
;; Font-lock.
(setq-local treesit-font-lock-settings java-ts-mode--font-lock-settings)
(setq-local treesit-font-lock-feature-list

View file

@ -1008,6 +1008,20 @@ leading double colon is not added."
;; Navigation.
(setq-local treesit-defun-type-regexp ruby-ts--method-regex)
(setq-local treesit-sexp-type-regexp
(regexp-opt '("class"
"module"
"method"
"argument_list"
"array"
"hash"
"parenthesized_statements"
"if"
"case"
"block"
"do_block"
"begin")))
;; AFAIK, Ruby can not nest methods
(setq-local treesit-defun-prefer-top-level nil)

View file

@ -1636,6 +1636,21 @@ BACKWARD and ALL are the same as in `treesit-search-forward'."
(goto-char current-pos)))
node))
(defvar-local treesit-sexp-type-regexp nil
"A regexp that matches the node type of sexp nodes.
A sexp node is a node that is bigger than punctuation, and
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.")
(defun treesit-forward-sexp (&optional arg)
(interactive "^p")
(or arg (setq arg 1))
(funcall
(if (> arg 0) #'treesit-end-of-thing #'treesit-beginning-of-thing)
treesit-sexp-type-regexp (abs arg)))
(defun treesit-transpose-sexps (&optional arg)
"Tree-sitter `transpose-sexps' function.
Arg is the same as in `transpose-sexps'.
@ -2301,6 +2316,8 @@ before calling this function."
(setq-local add-log-current-defun-function
#'treesit-add-log-current-defun))
(when treesit-sexp-type-regexp
(setq-local forward-sexp-function #'treesit-forward-sexp))
(setq-local transpose-sexps-function #'treesit-transpose-sexps)
(when treesit-sentence-type-regexp
(setq-local forward-sentence-function #'treesit-forward-sentence))