Subject: Re: bug#79288: [PATCH] Add edebug-bounce-to-previous-value

From: Jens Schmidt <[email-masked]>
Date: Fri, 22 Aug 2025 21:24:30 +0200

On 2025-08-22  08:39, Eli Zaretskii wrote:

> Thanks, but I think this command should have a key binding.

My personal favorite would be "P", but that is taken already.  From
there I'd use either "j" (for jump), "M-p" (because it has a "p"), or
"."  (because it is a point).  If you have any better ideas, please let
me know, I'm completely open here.  I attached the list of used and free
current edebug bindings, sorted by keys.

On 2025-08-22  09:51, Stefan Monnier wrote:

> For my own use, I get the impression that I'd find it more useful to ask
> the user to type in the form whose value we want to "bounce to".

When we extend the notion of "previous value" to "what has been
single-stepped through OR what has been evaluated with `e' or `C-x C-e'"
we can have that as well.  So you press "C-x C-e", get some buffer
position back, and then press "j" (or whatever) to bounce to that
value.

Only the user interface is potentially slightly more confusing, then.
I attached a revised patch implementing that.

Please let me know your choice of key and patch (v1 from
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=79288#5 or v2 from this
message), and I will continue on that route.

Thanks!

------------------------- edebug key bindings -------------------------
   A                                          "a"  #'abort-recursive-edit
  "B"  #'edebug-next-breakpoint               "b"  #'edebug-set-breakpoint
  "C"  #'edebug-Continue-fast-mode            "c"  #'edebug-continue-mode
  "D"  #'edebug-toggle-disable-breakpoint     "d"  #'edebug-pop-to-backtrace
  "E"  #'edebug-visit-eval-list               "e"  #'edebug-eval-expression
   F                                          "f"  #'edebug-forward-sexp
  "G"  #'edebug-Go-nonstop-mode               "g"  #'edebug-go-mode
   H                                          "h"  #'edebug-goto-here
  "I"  #'edebug-instrument-callee             "i"  #'edebug-step-in
   J                                           j
   K                                           k
   L                                           l
   M                                           m
   N                                          "n"  #'edebug-next-mode
   O                                          "o"  #'edebug-step-out
  "P"  #'edebug-view-outside                  "p"  #'edebug-bounce-point
  "Q"  #'edebug-top-level-nonstop             "q"  #'top-level
   R                                          "r"  #'edebug-previous-result
  "S"  #'edebug-stop                           s
  "T"  #'edebug-Trace-fast-mode               "t"  #'edebug-trace-mode
  "U"  #'edebug-unset-breakpoints             "u"  #'edebug-unset-breakpoint
   V                                          "v"  #'edebug-view-outside
  "W"  #'edebug-toggle-save-windows           "w"  #'edebug-where
  "X"  #'edebug-set-global-break-condition    "x"  #'edebug-set-conditional-breakpoint
   Y                                           y
   Z                                           z

  "SPC"     #'edebug-step-mode
  "-"       #'negative-argument
  "="       #'edebug-temp-display-freq-count
  "?"       #'edebug-help

  "C-c C-c" #'edebug-go-mode
  "C-c C-d" #'edebug-unset-breakpoint
  "C-c C-l" #'edebug-where)
  "C-c C-n" #'edebug-next-mode
  "C-c C-s" #'edebug-step-mode
  "C-c C-t" (lambda () (interactive) (edebug-set-breakpoint t))
  "C-x C-e" #'edebug-eval-last-sexp
  "C-x SPC" #'edebug-set-breakpoint
------------------------- edebug key bindings -------------------------

From f7ebb63fdab725279394a380721e5804475670ee Mon Sep 17 00:00:00 2001
From: Jens Schmidt <[email-masked]>
Date: Thu, 21 Aug 2025 20:58:42 +0200
Subject: [PATCH v2] 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 | 42 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)

diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 284e3acd959..1835fe6dfb9 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -2617,7 +2617,11 @@ 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.
+;; Last value seen while single-stepping or evaluating in the outside
+;; environment.
+(defvar edebug-previous-value nil)
+;; Last value seen while single-stepping, and converted to a string.
+(defvar edebug-previous-result nil)
 
 (defun edebug--display (value offset-index arg-mode)
   ;; edebug--display-1 is too big, we should split it.  This function
@@ -3114,6 +3118,37 @@ 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.
+The previous value is the last value you have encountered while
+single-stepping or evaluated in the outside environment, for example, by
+calling function `edebug-eval-expression, whatever comes later.
+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 +3778,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))))
@@ -3785,6 +3821,8 @@ edebug-eval-expression
             (values--store-value value)
             (concat (edebug-safe-prin1-to-string value)
                     (eval-expression-print-format value)))))
+    (unless errored
+      (setq edebug-previous-value value))
     (cond
      (errored
       (message "Error: %s" errored))
-- 
2.39.5