aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2019-10-20 13:10:59 +0200
committerLars Ingebrigtsen2019-10-20 13:11:04 +0200
commita4e7c15484a9330fb9e1a1b425fcf1b37bad04e1 (patch)
tree33db809baf378a77d04002d338c291232e12acb7
parent0cbcd2869e46f2ede0d08fd183d6c0ad0ebd8394 (diff)
downloademacs-a4e7c15484a9330fb9e1a1b425fcf1b37bad04e1.tar.gz
emacs-a4e7c15484a9330fb9e1a1b425fcf1b37bad04e1.zip
Preserve breakpoints when Edebug-reinstrumenting functions
* lisp/emacs-lisp/edebug.el (edebug--overlay-breakpoints): New function (bug#23470). * lisp/emacs-lisp/seq.el (seq-position): Autoload.
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/emacs-lisp/edebug.el33
-rw-r--r--lisp/emacs-lisp/seq.el1
3 files changed, 33 insertions, 6 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 21fbdb90af7..b8c2c5a329c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1462,6 +1462,11 @@ the Elisp manual for documentation of the new mode and its commands.
1462 1462
1463** Edebug 1463** Edebug
1464 1464
1465---
1466*** Re-instrumenting a function with Edebug will now try to preserve
1467previously-set breakpoints. If the code has changed substantially,
1468this may not be possible.
1469
1465+++ 1470+++
1466*** New command 'edebug-remove-instrumentation. 1471*** New command 'edebug-remove-instrumentation.
1467This command removes Edebug instrumentation from all functions that 1472This command removes Edebug instrumentation from all functions that
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 893c821f086..68b2126345f 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -1403,15 +1403,33 @@ contains a circular object."
1403 (put edebug-def-name 'edebug 1403 (put edebug-def-name 'edebug
1404 ;; A struct or vector would be better here!! 1404 ;; A struct or vector would be better here!!
1405 (list edebug-form-begin-marker 1405 (list edebug-form-begin-marker
1406 nil ; clear breakpoints 1406 (edebug--restore-breakpoints edebug-old-def-name)
1407 edebug-offset-list 1407 edebug-offset-list
1408 edebug-top-window-data 1408 edebug-top-window-data))
1409 ))
1410 1409
1411 (funcall edebug-new-definition-function edebug-def-name) 1410 (funcall edebug-new-definition-function edebug-def-name)
1412 result 1411 result
1413 ))) 1412 )))
1414 1413
1414(defun edebug--restore-breakpoints (name)
1415 (let* ((data (get name 'edebug))
1416 (offsets (nth 2 data))
1417 (breakpoints (nth 1 data))
1418 (start (nth 0 data))
1419 index)
1420 ;; Breakpoints refer to offsets from the start of the function.
1421 ;; The start position is a marker, so it'll move around in a
1422 ;; similar fashion as the breakpoint markers. If we find a
1423 ;; breakpoint marker that refers to an offset (which is a place
1424 ;; where breakpoints can be made), then we restore it.
1425 (cl-loop for breakpoint in breakpoints
1426 for marker = (nth 3 breakpoint)
1427 when (and (marker-position marker)
1428 (setq index (seq-position
1429 offsets
1430 (- (marker-position marker) start))))
1431 collect (cons index (cdr breakpoint)))))
1432
1415(defun edebug-new-definition (def-name) 1433(defun edebug-new-definition (def-name)
1416 "Set up DEF-NAME to use Edebug's instrumentation functions." 1434 "Set up DEF-NAME to use Edebug's instrumentation functions."
1417 (put def-name 'edebug-behavior 'edebug) 1435 (put def-name 'edebug-behavior 'edebug)
@@ -3166,6 +3184,7 @@ the breakpoint."
3166 (edebug-def-mark (car edebug-data)) 3184 (edebug-def-mark (car edebug-data))
3167 (edebug-breakpoints (car (cdr edebug-data))) 3185 (edebug-breakpoints (car (cdr edebug-data)))
3168 (offset-vector (nth 2 edebug-data)) 3186 (offset-vector (nth 2 edebug-data))
3187 (position (+ edebug-def-mark (aref offset-vector index)))
3169 present) 3188 present)
3170 ;; delete it either way 3189 ;; delete it either way
3171 (setq present (assq index edebug-breakpoints)) 3190 (setq present (assq index edebug-breakpoints))
@@ -3176,8 +3195,10 @@ the breakpoint."
3176 (setq edebug-breakpoints 3195 (setq edebug-breakpoints
3177 (edebug-sort-alist 3196 (edebug-sort-alist
3178 (cons 3197 (cons
3179 (list index condition temporary) 3198 (list index condition temporary
3180 edebug-breakpoints) '<)) 3199 (set-marker (make-marker) position))
3200 edebug-breakpoints)
3201 '<))
3181 (if condition 3202 (if condition
3182 (message "Breakpoint set in %s with condition: %s" 3203 (message "Breakpoint set in %s with condition: %s"
3183 edebug-def-name condition) 3204 edebug-def-name condition)
@@ -3187,7 +3208,7 @@ the breakpoint."
3187 (message "No breakpoint here"))) 3208 (message "No breakpoint here")))
3188 3209
3189 (setcar (cdr edebug-data) edebug-breakpoints) 3210 (setcar (cdr edebug-data) edebug-breakpoints)
3190 (goto-char (+ edebug-def-mark (aref offset-vector index))) 3211 (goto-char position)
3191 (edebug--overlay-breakpoints edebug-def-name))))) 3212 (edebug--overlay-breakpoints edebug-def-name)))))
3192 3213
3193(defun edebug--overlay-breakpoints (function) 3214(defun edebug--overlay-breakpoints (function)
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index f001dceecec..8d4093004a7 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -380,6 +380,7 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
380 (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1) 380 (and (seq-every-p (lambda (item1) (seq-contains-p sequence2 item1 testfn)) sequence1)
381 (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2))) 381 (seq-every-p (lambda (item2) (seq-contains-p sequence1 item2 testfn)) sequence2)))
382 382
383;;;###autoload
383(cl-defgeneric seq-position (sequence elt &optional testfn) 384(cl-defgeneric seq-position (sequence elt &optional testfn)
384 "Return the index of the first element in SEQUENCE that is equal to ELT. 385 "Return the index of the first element in SEQUENCE that is equal to ELT.
385Equality is defined by TESTFN if non-nil or by `equal' if nil." 386Equality is defined by TESTFN if non-nil or by `equal' if nil."