1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-26 07:33:47 +00:00

Add 'forward-sexp-default-function' to be used by 'treesit-forward-sexp'

* lisp/emacs-lisp/lisp.el (forward-sexp-default-function):
New function with body from 'forward-sexp' (bug#68993).
(forward-sexp-function): Change the default value from nil to
'forward-sexp-default-function'.
(forward-sexp): Use either 'forward-sexp-function' or
'forward-sexp-default-function'.

* lisp/treesit.el (treesit-forward-sexp): In nodes of type 'text'
fall back to 'forward-sexp-default-function'.  Improve docstring.

* doc/lispref/positions.texi (List Motion): Fix pxref.
This commit is contained in:
Juri Linkov 2024-04-14 19:18:31 +03:00
parent cd113d8c45
commit 568c174135
4 changed files with 30 additions and 12 deletions

View File

@ -892,8 +892,8 @@ parser information to move across syntax constructs. Since what
exactly is considered a sexp varies between languages, a major mode
should set @code{treesit-thing-settings} 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}).
@code{forward-sexp} and @code{backward-sexp}(@pxref{Expressions,
,, emacs, The extensible self-documenting text editor}).
@node Skipping Characters
@subsection Skipping Characters

View File

@ -2103,6 +2103,10 @@ All tree-sitter enabled modes that define 'sentence' in
** Functions and variables to move by program sexps
*** New function 'forward-sexp-default-function'.
The previous implementation of 'forward-sexp' is moved into its
own function, to be bound by 'forward-sexp-function'.
*** New function 'treesit-forward-sexp'.
Tree-sitter conditionally sets 'forward-sexp-function' for major modes
that have defined 'sexp' in 'treesit-thing-settings' to enable

View File

@ -45,7 +45,12 @@ This affects `insert-parentheses' and `insert-pair'."
:type 'boolean
:group 'lisp)
(defvar forward-sexp-function nil
(defun forward-sexp-default-function (&optional arg)
"Default function for `forward-sexp-function'."
(goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
(if (< arg 0) (backward-prefix-chars)))
(defvar forward-sexp-function #'forward-sexp-default-function
;; FIXME:
;; - for some uses, we may want a "sexp-only" version, which only
;; jumps over a well-formed sexp, rather than some dwimish thing
@ -74,10 +79,9 @@ report errors as appropriate for this kind of usage."
"No next sexp"
"No previous sexp"))))
(or arg (setq arg 1))
(if forward-sexp-function
(funcall forward-sexp-function arg)
(goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
(if (< arg 0) (backward-prefix-chars)))))
(funcall (or forward-sexp-function
#'forward-sexp-default-function)
arg)))
(defun backward-sexp (&optional arg interactive)
"Move backward across one balanced expression (sexp).

View File

@ -2138,14 +2138,24 @@ however, smaller in scope than sentences. This is used by
(defun treesit-forward-sexp (&optional arg)
"Tree-sitter implementation for `forward-sexp-function'.
ARG is described in the docstring of `forward-sexp-function'. If
there are no further sexps to move across, signal `scan-error'
like `forward-sexp' does. If point is already at top-level,
return nil without moving point."
ARG is described in the docstring of `forward-sexp-function'.
If point is inside a text environment where tree-sitter is not
supported, go forward a sexp using `forward-sexp-default-function'.
If point is inside code, use tree-sitter functions with the
following behavior. If there are no further sexps to move across,
signal `scan-error' like `forward-sexp' does. If point is already
at top-level, return nil without moving point.
What constitutes as text and source code sexp is determined
by `text' and `sexp' in `treesit-thing-settings'."
(interactive "^p")
(let ((arg (or arg 1))
(pred (or treesit-sexp-type-regexp 'sexp)))
(or (if (> arg 0)
(or (when (treesit-node-match-p (treesit-node-at (point)) 'text t)
(funcall #'forward-sexp-default-function arg)
t)
(if (> arg 0)
(treesit-end-of-thing pred (abs arg) 'restricted)
(treesit-beginning-of-thing pred (abs arg) 'restricted))
;; If we couldn't move, we should signal an error and report