@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
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.
+
\f
* Changes in Specialized Modes and Packages in Emacs 30.1
---
"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
;; 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)
(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'.
(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))