Don't signal scan-error when moving by sexp interactively

* lisp/emacs-lisp/lisp.el (forward-sexp, backward-sexp, forward-list)
(backward-list, down-list, up-list, mark-sexp, kill-sexp)
(backward-kill-sexp): Remove unsightly scan-error when running
interactively and no further movement by sexp can be made (bug#43489).
This commit is contained in:
Mattias Engdegård 2020-09-18 12:49:33 +02:00
parent b252e09ae4
commit df0f32f048

View file

@ -55,7 +55,7 @@ This affects `insert-parentheses' and `insert-pair'."
"If non-nil, `forward-sexp' delegates to this function. "If non-nil, `forward-sexp' delegates to this function.
Should take the same arguments and behave similarly to `forward-sexp'.") Should take the same arguments and behave similarly to `forward-sexp'.")
(defun forward-sexp (&optional arg) (defun forward-sexp (&optional arg user-error)
"Move forward across one balanced expression (sexp). "Move forward across one balanced expression (sexp).
With ARG, do it that many times. Negative arg -N means move With ARG, do it that many times. Negative arg -N means move
backward across N balanced expressions. This command assumes backward across N balanced expressions. This command assumes
@ -64,23 +64,32 @@ point is not in a string or comment. Calls
If unable to move over a sexp, signal `scan-error' with three If unable to move over a sexp, signal `scan-error' with three
arguments: a message, the start of the obstacle (usually a arguments: a message, the start of the obstacle (usually a
parenthesis or list marker of some kind), and end of the parenthesis or list marker of some kind), and end of the
obstacle." obstacle. If USER-ERROR is non-nil, as it is interactively,
(interactive "^p") report errors as appropriate for an interactive command."
(or arg (setq arg 1)) (interactive "^p\nd")
(if forward-sexp-function (if user-error
(funcall forward-sexp-function arg) (condition-case _
(goto-char (or (scan-sexps (point) arg) (buffer-end arg))) (forward-sexp arg nil)
(if (< arg 0) (backward-prefix-chars)))) (scan-error (user-error (if (> arg 0)
"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)))))
(defun backward-sexp (&optional arg) (defun backward-sexp (&optional arg user-error)
"Move backward across one balanced expression (sexp). "Move backward across one balanced expression (sexp).
With ARG, do it that many times. Negative arg -N means With ARG, do it that many times. Negative arg -N means
move forward across N balanced expressions. move forward across N balanced expressions.
This command assumes point is not in a string or comment. This command assumes point is not in a string or comment.
Uses `forward-sexp' to do the work." Uses `forward-sexp' to do the work.
(interactive "^p") If USER-ERROR is non-nil, as it is interactively,
report errors as appropriate for an interactive command."
(interactive "^p\nd")
(or arg (setq arg 1)) (or arg (setq arg 1))
(forward-sexp (- arg))) (forward-sexp (- arg) user-error))
(defun mark-sexp (&optional arg allow-extend) (defun mark-sexp (&optional arg allow-extend)
"Set mark ARG sexps from point. "Set mark ARG sexps from point.
@ -99,50 +108,78 @@ This command assumes point is not in a string or comment."
(set-mark (set-mark
(save-excursion (save-excursion
(goto-char (mark)) (goto-char (mark))
(forward-sexp arg) (condition-case error
(forward-sexp arg)
(scan-error
(user-error (if (equal (cadr error)
"Containing expression ends prematurely")
"No more sexp to select"
(cadr error)))))
(point)))) (point))))
(t (t
(push-mark (push-mark
(save-excursion (save-excursion
(forward-sexp (prefix-numeric-value arg)) (condition-case error
(forward-sexp (prefix-numeric-value arg))
(scan-error
(user-error (if (equal (cadr error)
"Containing expression ends prematurely")
"No sexp to select"
(cadr error)))))
(point)) (point))
nil t)))) nil t))))
(defun forward-list (&optional arg) (defun forward-list (&optional arg user-error)
"Move forward across one balanced group of parentheses. "Move forward across one balanced group of parentheses.
This command will also work on other parentheses-like expressions This command will also work on other parentheses-like expressions
defined by the current language mode. defined by the current language mode.
With ARG, do it that many times. With ARG, do it that many times.
Negative arg -N means move backward across N groups of parentheses. Negative arg -N means move backward across N groups of parentheses.
This command assumes point is not in a string or comment." This command assumes point is not in a string or comment.
(interactive "^p") If USER-ERROR is non-nil, as it is interactively,
(or arg (setq arg 1)) report errors as appropriate for an interactive command."
(goto-char (or (scan-lists (point) arg 0) (buffer-end arg)))) (interactive "^p\nd")
(if user-error
(condition-case _
(forward-list arg nil)
(scan-error (user-error (if (> arg 0)
"No next group"
"No previous group"))))
(or arg (setq arg 1))
(goto-char (or (scan-lists (point) arg 0) (buffer-end arg)))))
(defun backward-list (&optional arg) (defun backward-list (&optional arg user-error)
"Move backward across one balanced group of parentheses. "Move backward across one balanced group of parentheses.
This command will also work on other parentheses-like expressions This command will also work on other parentheses-like expressions
defined by the current language mode. defined by the current language mode.
With ARG, do it that many times. With ARG, do it that many times.
Negative arg -N means move forward across N groups of parentheses. Negative arg -N means move forward across N groups of parentheses.
This command assumes point is not in a string or comment." This command assumes point is not in a string or comment.
(interactive "^p") If USER-ERROR is non-nil, as it is interactively,
report errors as appropriate for an interactive command."
(interactive "^p\nd")
(or arg (setq arg 1)) (or arg (setq arg 1))
(forward-list (- arg))) (forward-list (- arg) user-error))
(defun down-list (&optional arg) (defun down-list (&optional arg user-error)
"Move forward down one level of parentheses. "Move forward down one level of parentheses.
This command will also work on other parentheses-like expressions This command will also work on other parentheses-like expressions
defined by the current language mode. defined by the current language mode.
With ARG, do this that many times. With ARG, do this that many times.
A negative argument means move backward but still go down a level. A negative argument means move backward but still go down a level.
This command assumes point is not in a string or comment." This command assumes point is not in a string or comment.
(interactive "^p") If USER-ERROR is non-nil, as it is interactively,
(or arg (setq arg 1)) report errors as appropriate for an interactive command."
(let ((inc (if (> arg 0) 1 -1))) (interactive "^p\nd")
(while (/= arg 0) (if user-error
(goto-char (or (scan-lists (point) inc -1) (buffer-end arg))) (condition-case _
(setq arg (- arg inc))))) (down-list arg nil)
(scan-error (user-error "At bottom level")))
(or arg (setq arg 1))
(let ((inc (if (> arg 0) 1 -1)))
(while (/= arg 0)
(goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
(setq arg (- arg inc))))))
(defun backward-up-list (&optional arg escape-strings no-syntax-crossing) (defun backward-up-list (&optional arg escape-strings no-syntax-crossing)
"Move backward out of one level of parentheses. "Move backward out of one level of parentheses.
@ -229,26 +266,39 @@ point is unspecified."
(or (< inc 0) (or (< inc 0)
(forward-comment 1)) (forward-comment 1))
(setf arg (+ arg inc))) (setf arg (+ arg inc)))
(signal (car err) (cdr err)))))) (if no-syntax-crossing
;; Assume called interactively; don't signal an error.
(user-error "At top level")
(signal (car err) (cdr err)))))))
(setq arg (- arg inc))))) (setq arg (- arg inc)))))
(defun kill-sexp (&optional arg) (defun kill-sexp (&optional arg user-error)
"Kill the sexp (balanced expression) following point. "Kill the sexp (balanced expression) following point.
With ARG, kill that many sexps after point. With ARG, kill that many sexps after point.
Negative arg -N means kill N sexps before point. Negative arg -N means kill N sexps before point.
This command assumes point is not in a string or comment." This command assumes point is not in a string or comment.
(interactive "p") If USER-ERROR is non-nil, as it is interactively,
(let ((opoint (point))) report errors as appropriate for an interactive command."
(forward-sexp (or arg 1)) (interactive "p\nd")
(kill-region opoint (point)))) (if user-error
(condition-case _
(kill-sexp arg nil)
(scan-error (user-error (if (> arg 0)
"No next sexp"
"No previous sexp"))))
(let ((opoint (point)))
(forward-sexp (or arg 1))
(kill-region opoint (point)))))
(defun backward-kill-sexp (&optional arg) (defun backward-kill-sexp (&optional arg user-error)
"Kill the sexp (balanced expression) preceding point. "Kill the sexp (balanced expression) preceding point.
With ARG, kill that many sexps before point. With ARG, kill that many sexps before point.
Negative arg -N means kill N sexps after point. Negative arg -N means kill N sexps after point.
This command assumes point is not in a string or comment." This command assumes point is not in a string or comment.
(interactive "p") If USER-ERROR is non-nil, as it is interactively,
(kill-sexp (- (or arg 1)))) report errors as appropriate for an interactive command."
(interactive "p\nd")
(kill-sexp (- (or arg 1)) user-error))
;; After Zmacs: ;; After Zmacs:
(defun kill-backward-up-list (&optional arg) (defun kill-backward-up-list (&optional arg)