all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattiase@acm.org>
To: 43489@debbugs.gnu.org
Subject: bug#43489: [PATCH] Don't signal scan-error when moving by sexp interactively
Date: Fri, 18 Sep 2020 13:31:16 +0200	[thread overview]
Message-ID: <64C7CB3A-36F2-4988-9FF9-B99115C9ED13@acm.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 671 bytes --]

When moving by sexp (C-M-f, C-M-u and so on) and point is already at a boundary preventing further movement, Emacs currently signals an internal error such as

 Scan error: "Containing expression ends prematurely", 5010, 5010

or

 Scan error: "Unbalanced parentheses", 5010, 1

which is unhelpful and rather looks as if something went wrong in the internal machinery.

The attached patch does away with this error when the commands are invoked interactively; programmatic use of the functions will get the scan-error just like before. There didn't seem to be much point in replacing the errors with new messages so the current version of the patch doesn't.


[-- Attachment #2: 0001-Don-t-signal-scan-error-when-moving-by-sexp-interact.patch --]
[-- Type: application/octet-stream, Size: 6173 bytes --]

From 25a03c7ec547984b2e500d4e5be7855290ae95ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Fri, 18 Sep 2020 12:49:33 +0200
Subject: [PATCH] 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): Remove unsightly scan-error
when running interactively and no further movement by sexp can be made.
---
 lisp/emacs-lisp/lisp.el | 84 +++++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 32 deletions(-)

diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el
index 8c18557c79..2b0ed76633 100644
--- a/lisp/emacs-lisp/lisp.el
+++ b/lisp/emacs-lisp/lisp.el
@@ -55,7 +55,7 @@ forward-sexp-function
   "If non-nil, `forward-sexp' delegates to this function.
 Should take the same arguments and behave similarly to `forward-sexp'.")
 
-(defun forward-sexp (&optional arg)
+(defun forward-sexp (&optional arg noerror)
   "Move forward across one balanced expression (sexp).
 With ARG, do it that many times.  Negative arg -N means move
 backward across N balanced expressions.  This command assumes
@@ -64,23 +64,29 @@ forward-sexp
 If unable to move over a sexp, signal `scan-error' with three
 arguments: a message, the start of the obstacle (usually a
 parenthesis or list marker of some kind), and end of the
-obstacle."
-  (interactive "^p")
-  (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)
+obstacle.  If NOERROR is non-nil, as it is interactively,
+do not signal an error."
+  (interactive "^p\nd")
+  (if noerror
+      (condition-case _
+          (forward-sexp arg nil)
+        (scan-error (ding)))
+    (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 noerror)
   "Move backward across one balanced expression (sexp).
 With ARG, do it that many times.  Negative arg -N means
 move forward across N balanced expressions.
 This command assumes point is not in a string or comment.
-Uses `forward-sexp' to do the work."
-  (interactive "^p")
+Uses `forward-sexp' to do the work.
+If NOERROR is non-nil, as it is interactively, do not signal an error."
+  (interactive "^p\nd")
   (or arg (setq arg 1))
-  (forward-sexp (- arg)))
+  (forward-sexp (- arg) noerror))
 
 (defun mark-sexp (&optional arg allow-extend)
   "Set mark ARG sexps from point.
@@ -108,41 +114,52 @@ mark-sexp
 	    (point))
 	  nil t))))
 
-(defun forward-list (&optional arg)
+(defun forward-list (&optional arg noerror)
   "Move forward across one balanced group of parentheses.
 This command will also work on other parentheses-like expressions
 defined by the current language mode.
 With ARG, do it that many times.
 Negative arg -N means move backward across N groups of parentheses.
-This command assumes point is not in a string or comment."
-  (interactive "^p")
-  (or arg (setq arg 1))
-  (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
-
-(defun backward-list (&optional arg)
+This command assumes point is not in a string or comment.
+If NOERROR is non-nil, as it is interactively, do not signal an error."
+  (interactive "^p\nd")
+  (if noerror
+      (condition-case _
+          (forward-list arg nil)
+        (scan-error (ding)))
+    (or arg (setq arg 1))
+    (goto-char (or (scan-lists (point) arg 0) (buffer-end arg)))))
+
+(defun backward-list (&optional arg noerror)
   "Move backward across one balanced group of parentheses.
 This command will also work on other parentheses-like expressions
 defined by the current language mode.
 With ARG, do it that many times.
 Negative arg -N means move forward across N groups of parentheses.
-This command assumes point is not in a string or comment."
-  (interactive "^p")
+This command assumes point is not in a string or comment.
+If NOERROR is non-nil, as it is interactively, do not signal an error."
+  (interactive "^p\nd")
   (or arg (setq arg 1))
-  (forward-list (- arg)))
+  (forward-list (- arg) noerror))
 
-(defun down-list (&optional arg)
+(defun down-list (&optional arg noerror)
   "Move forward down one level of parentheses.
 This command will also work on other parentheses-like expressions
 defined by the current language mode.
 With ARG, do this that many times.
 A negative argument means move backward but still go down a level.
-This command assumes point is not in a string or comment."
-  (interactive "^p")
-  (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)))))
+This command assumes point is not in a string or comment.
+If NOERROR is non-nil, as it is interactively, do not signal an error."
+  (interactive "^p\nd")
+  (if noerror
+      (condition-case _
+          (down-list arg nil)
+        (scan-error (ding)))
+    (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)
   "Move backward out of one level of parentheses.
@@ -229,7 +246,10 @@ up-list
                  (or (< inc 0)
                      (forward-comment 1))
                  (setf arg (+ arg inc)))
-            (signal (car err) (cdr err))))))
+            (if no-syntax-crossing
+                ;; Assume called interactively; don't signal an error.
+                (ding)
+              (signal (car err) (cdr err)))))))
       (setq arg (- arg inc)))))
 
 (defun kill-sexp (&optional arg)
-- 
2.21.1 (Apple Git-122.3)


[-- Attachment #3: Type: text/plain, Size: 2 bytes --]




             reply	other threads:[~2020-09-18 11:31 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-18 11:31 Mattias Engdegård [this message]
2020-09-18 13:13 ` bug#43489: [PATCH] Don't signal scan-error when moving by sexp interactively Lars Ingebrigtsen
2020-09-18 13:18   ` Dmitry Gutov
2020-09-18 13:42     ` Lars Ingebrigtsen
2020-09-18 13:48       ` Dmitry Gutov
2020-09-18 15:13   ` Mattias Engdegård
2020-09-18 15:23     ` Lars Ingebrigtsen
2020-09-18 16:01       ` Mattias Engdegård
2020-09-19 14:13         ` Lars Ingebrigtsen
2020-09-20 17:33           ` Mattias Engdegård
2020-09-20 19:54             ` Lars Ingebrigtsen
2020-09-21 10:55               ` Mattias Engdegård
2020-09-21 14:47                 ` Lars Ingebrigtsen
2020-09-21 17:12                   ` Mattias Engdegård
2020-09-22 14:32                     ` Lars Ingebrigtsen
2020-09-23  9:17                       ` Mattias Engdegård
2020-09-23 13:40                         ` Lars Ingebrigtsen
2020-09-23 14:33                           ` Mattias Engdegård
2020-09-23 14:45                             ` João Távora
2020-09-23 16:24                               ` Mattias Engdegård
2020-09-23 16:37                                 ` João Távora
2020-09-24 15:50                                   ` Mattias Engdegård
2020-09-24 15:58                                     ` João Távora
2020-09-24 17:32                                       ` Stefan Monnier
2020-09-24 19:23                                         ` João Távora
2020-09-28 17:05                                           ` Stefan Monnier
2020-09-20 21:39             ` Dmitry Gutov
2020-09-21 11:21               ` Mattias Engdegård
2020-09-21 12:36                 ` Dmitry Gutov
2020-09-21 17:12                   ` Mattias Engdegård
2020-09-21 17:49                     ` Dmitry Gutov
2020-09-21  8:49   ` João Távora
2020-09-21 14:43     ` Lars Ingebrigtsen
2020-09-21 17:12     ` Mattias Engdegård
2020-09-21 17:25       ` João Távora

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=64C7CB3A-36F2-4988-9FF9-B99115C9ED13@acm.org \
    --to=mattiase@acm.org \
    --cc=43489@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.