]> git.eshelyaron.com Git - emacs.git/commitdiff
Preserve breakpoints when Edebug-reinstrumenting functions
authorLars Ingebrigtsen <larsi@gnus.org>
Sun, 20 Oct 2019 11:10:59 +0000 (13:10 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Sun, 20 Oct 2019 11:11:04 +0000 (13:11 +0200)
* lisp/emacs-lisp/edebug.el (edebug--overlay-breakpoints): New
function (bug#23470).

* lisp/emacs-lisp/seq.el (seq-position): Autoload.

etc/NEWS
lisp/emacs-lisp/edebug.el
lisp/emacs-lisp/seq.el

index 21fbdb90af7f273c37d71ae75d4aaffefc258917..b8c2c5a329cc38045ecd002dbe350ff0ceead06c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1462,6 +1462,11 @@ the Elisp manual for documentation of the new mode and its commands.
 
 ** Edebug
 
+---
+*** Re-instrumenting a function with Edebug will now try to preserve
+previously-set breakpoints.  If the code has changed substantially,
+this may not be possible.
+
 +++
 *** New command 'edebug-remove-instrumentation.
 This command removes Edebug instrumentation from all functions that
index 893c821f0861ad95f8b7e7d231a781a83ab26ee7..68b2126345f6f55e4f3fd6fb7562400a3a210a35 100644 (file)
@@ -1403,15 +1403,33 @@ contains a circular object."
       (put edebug-def-name 'edebug
           ;; A struct or vector would be better here!!
           (list edebug-form-begin-marker
-                nil                    ; clear breakpoints
+                (edebug--restore-breakpoints edebug-old-def-name)
                 edebug-offset-list
-                edebug-top-window-data
-                ))
+                edebug-top-window-data))
 
       (funcall edebug-new-definition-function edebug-def-name)
       result
       )))
 
+(defun edebug--restore-breakpoints (name)
+  (let* ((data (get name 'edebug))
+         (offsets (nth 2 data))
+         (breakpoints (nth 1 data))
+         (start (nth 0 data))
+         index)
+    ;; Breakpoints refer to offsets from the start of the function.
+    ;; The start position is a marker, so it'll move around in a
+    ;; similar fashion as the breakpoint markers.  If we find a
+    ;; breakpoint marker that refers to an offset (which is a place
+    ;; where breakpoints can be made), then we restore it.
+    (cl-loop for breakpoint in breakpoints
+             for marker = (nth 3 breakpoint)
+             when (and (marker-position marker)
+                       (setq index (seq-position
+                                    offsets
+                                    (- (marker-position marker) start))))
+             collect (cons index (cdr breakpoint)))))
+
 (defun edebug-new-definition (def-name)
   "Set up DEF-NAME to use Edebug's instrumentation functions."
   (put def-name 'edebug-behavior 'edebug)
@@ -3166,6 +3184,7 @@ the breakpoint."
               (edebug-def-mark (car edebug-data))
               (edebug-breakpoints (car (cdr edebug-data)))
               (offset-vector (nth 2 edebug-data))
+               (position (+ edebug-def-mark (aref offset-vector index)))
               present)
          ;; delete it either way
          (setq present (assq index edebug-breakpoints))
@@ -3176,8 +3195,10 @@ the breakpoint."
                (setq edebug-breakpoints
                      (edebug-sort-alist
                       (cons
-                       (list index condition temporary)
-                       edebug-breakpoints) '<))
+                       (list index condition temporary
+                              (set-marker (make-marker) position))
+                       edebug-breakpoints)
+                       '<))
                (if condition
                    (message "Breakpoint set in %s with condition: %s"
                             edebug-def-name condition)
@@ -3187,7 +3208,7 @@ the breakpoint."
              (message "No breakpoint here")))
 
          (setcar (cdr edebug-data) edebug-breakpoints)
-         (goto-char (+ edebug-def-mark (aref offset-vector index)))
+         (goto-char position)
           (edebug--overlay-breakpoints edebug-def-name)))))
 
 (defun edebug--overlay-breakpoints (function)
index f001dceecec5e03b867fd8b515da8c2dbc71414e..8d4093004a7699a026cabb84ef7d76dc83534bd8 100644 (file)
@@ -380,6 +380,7 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
   (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1)
        (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2)))
 
+;;;###autoload
 (cl-defgeneric seq-position (sequence elt &optional testfn)
   "Return the index of the first element in SEQUENCE that is equal to ELT.
 Equality is defined by TESTFN if non-nil or by `equal' if nil."