Subject: [PATCH] Add edebug-bounce-to-previous-value
From: Jens Schmidt <[email-masked]>
To: [email-masked]
Date: Thu, 21 Aug 2025 21:40:54 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Edebug has `edebug-bounce-point', which is invaluable to quickly peek
into the current buffer and its position during an Edebug session.

But now suppose you edebug a form

  (< foo-position (foo-end-of-current-blurb))

involving buffer positions and you would like to know where
`foo-position' and the result of the call to `foo-end-of-current-blurb'
are located in the current buffer while stepping through that form.
AFAIK, this involves manual switching to the current buffer, calling
`goto-char', etc., which is inconvenient and breaks the debugging flow.

The attached patch extends the concept of `edbug-bounce-point' by adding
a function `edebug-bounce-to-previous-value'.  That function uses the
previous value (as recorded by `edebug-compute-previous-result') to
bounce point to that value.  (If the previous value is not an integer
or marker, the function errors out.)  In that way it is much easier to
understand where buffer positions are actually located and what the code
does with them.

One could imagine alternative implementations, for example, by extending
`edebug-bounce-point' to bounce to the previous value when called with
C-u as prefix arg.

If you agree that this feature would be useful and if we can agree on a
concrete implementation, I can provide a full-blown patch including NEWS
entry and all.

Thanks for maintaining Emacs!

In GNU Emacs 31.0.50 (build 3, x86_64-pc-linux-gnu, GTK+ Version
 3.24.38, cairo version 1.16.0) of 2025-08-21 built on sappc2
Repository revision: ade6608e2587452c8ea565ce3057879379ebd0b5
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12201009
System Description: Debian GNU/Linux 12 (bookworm)

Configured using:
 'configure --with-native-compilation --with-mailutils'

From 53babf74b0c236928e8dd6f0d28bb636c5cbaac5 Mon Sep 17 00:00:00 2001
From: Jens Schmidt <[email-masked]>
Date: Thu, 21 Aug 2025 20:58:42 +0200
Subject: [PATCH] Add edebug-bounce-to-previous-value

From: Jens Schmidt <[email-masked]>

* lisp/emacs-lisp/edebug.el (edebug-previous-value): Add variable.
(edebug-compute-previous-result): Update it here.
(edebug-bounce-to-previous-value): Add function.
---
 lisp/emacs-lisp/edebug.el | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 284e3acd959..af6b54535b3 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -2617,7 +2617,8 @@ edebug-outside-d-c-i-n-s-w
 
 (defvar edebug-eval-list nil) ;; List of expressions to evaluate.
 
-(defvar edebug-previous-result nil) ;; Last result returned.
+(defvar edebug-previous-value nil) ;; Last value returned.
+(defvar edebug-previous-result nil) ;; Likewise, but converted to a string.
 
 (defun edebug--display (value offset-index arg-mode)
   ;; edebug--display-1 is too big, we should split it.  This function
@@ -3114,6 +3115,34 @@ edebug-bounce-point
       (edebug-pop-to-buffer edebug-buffer (car edebug-window-data)))))

+(defun edebug-bounce-to-previous-value (arg)
+  "Bounce point to previous value in the outside current buffer.
+If prefix argument ARG is supplied, sit for that many seconds
+before returning.  The default is one second."
+  (interactive "p")
+  (if (not edebug-active)
+      (error "Edebug is not active"))
+  (if (not (integer-or-marker-p edebug-previous-value))
+      (error "Previous value not a number or marker"))
+  (save-excursion
+    ;; If the buffer's currently displayed, avoid set-window-configuration.
+    (save-window-excursion
+      (let ((point-info ""))
+        (edebug-pop-to-buffer edebug-outside-buffer)
+        (cond
+         ((< edebug-previous-value (point-min))
+          (setq point-info (format " (< Point min: %s)" (point-min))))
+         ((> edebug-previous-value (point-max))
+          (setq point-info (format " (> Point max: %s)" (point-max))))
+         ((invisible-p edebug-previous-value)
+          (setq point-info (format " (invisible)"))))
+        (goto-char edebug-previous-value)
+        (message "Current buffer: %s Point: %s%s"
+	         (current-buffer) edebug-previous-value point-info)
+        (sit-for arg)
+        (edebug-pop-to-buffer edebug-buffer (car edebug-window-data))))))
+
+
 ;; Joe Wells, here is a start at your idea of adding a buffer to the internal
 ;; display list.  Still need to use this list in edebug--display.
 
@@ -3743,7 +3772,8 @@ edebug-compute-previous-result
   (if edebug-unwrap-results
       (setq previous-value
 	    (edebug-unwrap* previous-value)))
-  (setq edebug-previous-result
+  (setq edebug-previous-value previous-value
+        edebug-previous-result
 	(concat "Result: "
 		(edebug-safe-prin1-to-string previous-value)
 		(eval-expression-print-format previous-value))))
-- 
2.39.5