aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGemini Lasswell2018-07-17 11:47:43 -0700
committerGemini Lasswell2018-08-03 08:54:08 -0700
commitca98377280005344fb07c816997b9bc2a737056a (patch)
tree11172830e890866a63a154dad9e68850b8cf5064
parent1459ad2c670e7633f426d7a5a7f05fab23195b32 (diff)
downloademacs-ca98377280005344fb07c816997b9bc2a737056a.tar.gz
emacs-ca98377280005344fb07c816997b9bc2a737056a.zip
Add new commands to Edebug backtraces
Add commands to go to source if available, and to show and hide Edebug's instrumentation. Make Edebug pop to backtraces instead of displaying them, which makes Edebug consistant with the behavior of ERT and the Lisp Debugger. * doc/lispref/edebug.texi (Edebug Misc): Document when and how you can jump to source code from an Edebug backtrace. Document 'edebug-backtrace-show-instrumentation' and 'edebug-backtrace-hide-instrumentation'. * lisp/emacs-lisp/backtrace.el (backtrace-frame): Add comments to describe the fields. (backtrace-goto-source-functions): New abnormal hook. (backtrace-mode-map): Add keybinding and menu item for backtrace-goto-source. (backtrace--flags-width): New constant. (backtrace-update-flags): Use it. (backtrace-goto-source): New command. (backtrace--print-flags): Print the :source-available flag. * lisp/emacs-lisp/edebug.el (edebug-backtrace-frames) (edebug-instrumented-backtrace-frames): New variables. (edebug-backtrace, edebug--backtrace-frames): Remove functions. (edebug-pop-to-backtrace, edebug--backtrace-goto-source) (edebug--add-source-info): New functions. (edebug-mode-map, edebug-mode-menus): Replace 'edebug-backtrace' with 'edebug-pop-to-backtrace'. (edebug--strip-instrumentation): New function. (edebug--unwrap-and-add-info): Remove. (edebug-unwrap-frame, edebug-add-source-info): New functions. (edebug-backtrace-show-instrumentation) (edebug-backtrace-hide-instrumentation): New commands. * test/lisp/emacs-lisp/edebug-tests.el (edebug-tests-check-keymap): Verify keybindings in backtrace-mode-map used by new test. Update with binding for 'edebug-pop-to-backtrace'. (edebug-tests-backtrace-goto-source): New test. * test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el (edebug-test-code-range): Add a new stop point.
-rw-r--r--doc/lispref/edebug.texi12
-rw-r--r--etc/NEWS13
-rw-r--r--lisp/emacs-lisp/backtrace.el52
-rw-r--r--lisp/emacs-lisp/edebug.el118
-rw-r--r--test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el2
-rw-r--r--test/lisp/emacs-lisp/edebug-tests.el18
6 files changed, 165 insertions, 50 deletions
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index 0e0a2e8a643..59c9a68c54b 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -442,8 +442,16 @@ Redisplay the most recently known expression result in the echo area
442Display a backtrace, excluding Edebug's own functions for clarity 442Display a backtrace, excluding Edebug's own functions for clarity
443(@code{edebug-backtrace}). 443(@code{edebug-backtrace}).
444 444
445@xref{Debugging,, Backtraces, elisp}, for the commands which work 445@xref{Debugging,, Backtraces, elisp}, for a description of backtraces
446in a backtrace buffer. 446and the commands which work on them.
447
448If you would like to see Edebug's functions in the backtrace,
449use @kbd{M-x edebug-backtrace-show-instrumentation}. To hide them
450again use @kbd{M-x edebug-backtrace-hide-instrumentation}.
451
452If a backtrace frame starts with @samp{>} that means that Edebug knows
453where the source code for the frame is located. Use @kbd{s} to jump
454to the source code for the current frame.
447 455
448The backtrace buffer is killed automatically when you continue 456The backtrace buffer is killed automatically when you continue
449execution. 457execution.
diff --git a/etc/NEWS b/etc/NEWS
index 486e0d4384a..53b77656278 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -484,11 +484,20 @@ using the new variables 'edebug-behavior-alist',
484globally or for individual definitions. 484globally or for individual definitions.
485 485
486+++ 486+++
487*** Edebug's backtrace buffer now uses 'backtrace-mode'. 487*** Edebug's backtrace buffer now uses 'backtrace-mode'. Backtrace
488Backtrace mode adds fontification, links and commands for changing the 488mode adds fontification, links and commands for changing the
489appearance of backtrace frames. See the node "Backtraces" in the Elisp 489appearance of backtrace frames. See the node "Backtraces" in the Elisp
490manual for documentation of the new mode and its commands. 490manual for documentation of the new mode and its commands.
491 491
492The binding of 'd' in Edebug's keymap is now 'edebug-pop-to-backtrace'
493which replaces 'edebug-backtrace'. Consequently Edebug's backtrace
494windows now behave like those of the Lisp Debugger and of ERT, in that
495when they appear they will be the selected window.
496
497The new 'backtrace-goto-source' command, bound to 's', works in
498Edebug's backtraces on backtrace frames whose source code has
499been instrumented by Edebug.
500
492** Enhanced xterm support 501** Enhanced xterm support
493 502
494*** New variable 'xterm-set-window-title' controls whether Emacs sets 503*** New variable 'xterm-set-window-title' controls whether Emacs sets
diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el
index b6ca2890764..5169c305035 100644
--- a/lisp/emacs-lisp/backtrace.el
+++ b/lisp/emacs-lisp/backtrace.el
@@ -66,7 +66,14 @@ abbreviate the forms it prints."
66(cl-defstruct 66(cl-defstruct
67 (backtrace-frame 67 (backtrace-frame
68 (:constructor backtrace-make-frame)) 68 (:constructor backtrace-make-frame))
69 evald fun args flags locals buffer pos) 69 evald ; Non-nil if argument evaluation is complete.
70 fun ; The function called/to call in this frame.
71 args ; Either evaluated or unevaluated arguments to the function.
72 flags ; A plist, possible properties are :debug-on-exit and :source-available.
73 locals ; An alist containing variable names and values.
74 buffer ; If non-nil, the buffer in use by eval-buffer or eval-region.
75 pos ; The position in the buffer.
76 )
70 77
71(cl-defun backtrace-get-frames 78(cl-defun backtrace-get-frames
72 (&optional base &key (constructor #'backtrace-make-frame)) 79 (&optional base &key (constructor #'backtrace-make-frame))
@@ -181,6 +188,15 @@ This is commonly used to recompute `backtrace-frames'.")
181(defvar-local backtrace-print-function #'cl-prin1 188(defvar-local backtrace-print-function #'cl-prin1
182 "Function used to print values in the current Backtrace buffer.") 189 "Function used to print values in the current Backtrace buffer.")
183 190
191(defvar-local backtrace-goto-source-functions nil
192 "Abnormal hook used to jump to the source code for the current frame.
193Each hook function is called with no argument, and should return
194non-nil if it is able to switch to the buffer containing the
195source code. Execution of the hook will stop if one of the
196functions returns non-nil. When adding a function to this hook,
197you should also set the :source-available flag for the backtrace
198frames where the source code location is known.")
199
184(defvar backtrace-mode-map 200(defvar backtrace-mode-map
185 (let ((map (copy-keymap special-mode-map))) 201 (let ((map (copy-keymap special-mode-map)))
186 (set-keymap-parent map button-buffer-map) 202 (set-keymap-parent map button-buffer-map)
@@ -188,6 +204,7 @@ This is commonly used to recompute `backtrace-frames'.")
188 (define-key map "p" 'backtrace-backward-frame) 204 (define-key map "p" 'backtrace-backward-frame)
189 (define-key map "v" 'backtrace-toggle-locals) 205 (define-key map "v" 'backtrace-toggle-locals)
190 (define-key map "#" 'backtrace-toggle-print-circle) 206 (define-key map "#" 'backtrace-toggle-print-circle)
207 (define-key map "s" 'backtrace-goto-source)
191 (define-key map "\C-m" 'backtrace-help-follow-symbol) 208 (define-key map "\C-m" 'backtrace-help-follow-symbol)
192 (define-key map "+" 'backtrace-pretty-print) 209 (define-key map "+" 'backtrace-pretty-print)
193 (define-key map "-" 'backtrace-collapse) 210 (define-key map "-" 'backtrace-collapse)
@@ -212,6 +229,12 @@ This is commonly used to recompute `backtrace-frames'.")
212 :help "Use line breaks and indentation to make a form more readable"] 229 :help "Use line breaks and indentation to make a form more readable"]
213 ["Collapse to Single Line" backtrace-collapse] 230 ["Collapse to Single Line" backtrace-collapse]
214 "--" 231 "--"
232 ["Go to Source" backtrace-goto-source
233 :active (and (backtrace-get-index)
234 (plist-get (backtrace-frame-flags
235 (nth (backtrace-get-index) backtrace-frames))
236 :source-available))
237 :help "Show the source code for the current frame"]
215 ["Help for Symbol" backtrace-help-follow-symbol 238 ["Help for Symbol" backtrace-help-follow-symbol
216 :help "Show help for symbol at point"] 239 :help "Show help for symbol at point"]
217 ["Describe Backtrace Mode" describe-mode 240 ["Describe Backtrace Mode" describe-mode
@@ -219,6 +242,9 @@ This is commonly used to recompute `backtrace-frames'.")
219 map) 242 map)
220 "Local keymap for `backtrace-mode' buffers.") 243 "Local keymap for `backtrace-mode' buffers.")
221 244
245(defconst backtrace--flags-width 2
246 "Width in characters of the flags for a backtrace frame.")
247
222;;; Navigation and Text Properties 248;;; Navigation and Text Properties
223 249
224;; This mode uses the following text properties: 250;; This mode uses the following text properties:
@@ -580,6 +606,20 @@ content of the sexp."
580 '(backtrace-section backtrace-index backtrace-view 606 '(backtrace-section backtrace-index backtrace-view
581 backtrace-form)))) 607 backtrace-form))))
582 608
609(defun backtrace-goto-source ()
610 "If its location is known, jump to the source code for the frame at point."
611 (interactive)
612 (let* ((index (or (backtrace-get-index) (user-error "Not in a stack frame")))
613 (frame (nth index backtrace-frames))
614 (source-available (plist-get (backtrace-frame-flags frame)
615 :source-available)))
616 (unless (and source-available
617 (catch 'done
618 (dolist (func backtrace-goto-source-functions)
619 (when (funcall func)
620 (throw 'done t)))))
621 (user-error "Source code location not known"))))
622
583(defun backtrace-help-follow-symbol (&optional pos) 623(defun backtrace-help-follow-symbol (&optional pos)
584 "Follow cross-reference at POS, defaulting to point. 624 "Follow cross-reference at POS, defaulting to point.
585For the cross-reference format, see `help-make-xrefs'." 625For the cross-reference format, see `help-make-xrefs'."
@@ -681,8 +721,12 @@ property for use by navigation."
681(defun backtrace--print-flags (frame view) 721(defun backtrace--print-flags (frame view)
682 "Print the flags of a backtrace FRAME if enabled in VIEW." 722 "Print the flags of a backtrace FRAME if enabled in VIEW."
683 (let ((beg (point)) 723 (let ((beg (point))
684 (flag (plist-get (backtrace-frame-flags frame) :debug-on-exit))) 724 (flag (plist-get (backtrace-frame-flags frame) :debug-on-exit))
685 (insert (if (and (plist-get view :show-flags) flag) "* " " ")) 725 (source (plist-get (backtrace-frame-flags frame) :source-available)))
726 (when (plist-get view :show-flags)
727 (when source (insert ">"))
728 (when flag (insert "*")))
729 (insert (make-string (- backtrace--flags-width (- (point) beg)) ?\s))
686 (put-text-property beg (point) 'backtrace-section 'func))) 730 (put-text-property beg (point) 'backtrace-section 'func)))
687 731
688(defun backtrace--print-func-and-args (frame _view) 732(defun backtrace--print-func-and-args (frame _view)
@@ -770,7 +814,7 @@ Fall back to `prin1' if there is an error."
770 (let ((props (backtrace-get-text-properties begin)) 814 (let ((props (backtrace-get-text-properties begin))
771 (inhibit-read-only t) 815 (inhibit-read-only t)
772 (standard-output (current-buffer))) 816 (standard-output (current-buffer)))
773 (delete-char 2) 817 (delete-char backtrace--flags-width)
774 (backtrace--print-flags (nth (backtrace-get-index) backtrace-frames) 818 (backtrace--print-flags (nth (backtrace-get-index) backtrace-frames)
775 view) 819 view)
776 (add-text-properties begin (point) props)))))) 820 (add-text-properties begin (point) props))))))
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 3bf9cb9a488..fc295485fd4 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -3692,7 +3692,7 @@ be installed in `emacs-lisp-mode-map'.")
3692 3692
3693 ;; misc 3693 ;; misc
3694 (define-key map "?" 'edebug-help) 3694 (define-key map "?" 'edebug-help)
3695 (define-key map "d" 'edebug-backtrace) 3695 (define-key map "d" 'edebug-pop-to-backtrace)
3696 3696
3697 (define-key map "-" 'negative-argument) 3697 (define-key map "-" 'negative-argument)
3698 3698
@@ -3985,6 +3985,13 @@ Otherwise call `debug' normally."
3985 3985
3986;;; Backtrace buffer 3986;;; Backtrace buffer
3987 3987
3988(defvar-local edebug-backtrace-frames nil
3989 "Stack frames of the current Edebug Backtrace buffer without instrumentation.
3990This should be a list of `edebug---frame' objects.")
3991(defvar-local edebug-instrumented-backtrace-frames nil
3992 "Stack frames of the current Edebug Backtrace buffer with instrumentation.
3993This should be a list of `edebug---frame' objects.")
3994
3988;; Data structure for backtrace frames with information 3995;; Data structure for backtrace frames with information
3989;; from Edebug instrumentation found in the backtrace. 3996;; from Edebug instrumentation found in the backtrace.
3990(cl-defstruct 3997(cl-defstruct
@@ -3993,7 +4000,7 @@ Otherwise call `debug' normally."
3993 (:include backtrace-frame)) 4000 (:include backtrace-frame))
3994 def-name before-index after-index) 4001 def-name before-index after-index)
3995 4002
3996(defun edebug-backtrace () 4003(defun edebug-pop-to-backtrace ()
3997 "Display the current backtrace in a `backtrace-mode' window." 4004 "Display the current backtrace in a `backtrace-mode' window."
3998 (interactive) 4005 (interactive)
3999 (if (or (not edebug-backtrace-buffer) 4006 (if (or (not edebug-backtrace-buffer)
@@ -4002,31 +4009,33 @@ Otherwise call `debug' normally."
4002 (generate-new-buffer "*Edebug Backtrace*")) 4009 (generate-new-buffer "*Edebug Backtrace*"))
4003 ;; Else, could just display edebug-backtrace-buffer. 4010 ;; Else, could just display edebug-backtrace-buffer.
4004 ) 4011 )
4005 (with-output-to-temp-buffer (buffer-name edebug-backtrace-buffer) 4012 (pop-to-buffer edebug-backtrace-buffer)
4006 (setq edebug-backtrace-buffer standard-output) 4013 (unless (derived-mode-p 'backtrace-mode)
4007 (with-current-buffer edebug-backtrace-buffer 4014 (backtrace-mode)
4008 (unless (derived-mode-p 'backtrace-mode) 4015 (add-hook 'backtrace-goto-source-functions 'edebug--backtrace-goto-source))
4009 (backtrace-mode)) 4016 (setq edebug-instrumented-backtrace-frames
4010 (setq backtrace-frames (edebug--backtrace-frames)) 4017 (backtrace-get-frames 'edebug-debugger
4011 (backtrace-print) 4018 :constructor #'edebug--make-frame)
4012 (goto-char (point-min))))) 4019 edebug-backtrace-frames (edebug--strip-instrumentation
4013 4020 edebug-instrumented-backtrace-frames)
4014(defun edebug--backtrace-frames () 4021 backtrace-frames edebug-backtrace-frames)
4015 "Return backtrace frames with instrumentation removed. 4022 (backtrace-print)
4023 (goto-char (point-min)))
4024
4025(defun edebug--strip-instrumentation (frames)
4026 "Return a new list of backtrace frames with instrumentation removed.
4016Remove frames for Edebug's functions and the lambdas in 4027Remove frames for Edebug's functions and the lambdas in
4017`edebug-enter' wrappers." 4028`edebug-enter' wrappers. Fill in the def-name, before-index
4018 (let* ((frames (backtrace-get-frames 'edebug-debugger 4029and after-index fields in both FRAMES and the returned list
4019 :constructor #'edebug--make-frame)) 4030of deinstrumented frames, for those frames where the source
4020 skip-next-lambda def-name before-index after-index 4031code location is known."
4021 results 4032 (let (skip-next-lambda def-name before-index after-index results
4022 (index (length frames))) 4033 (index (length frames)))
4023 (dolist (frame (reverse frames)) 4034 (dolist (frame (reverse frames))
4024 (let ((fun (edebug--frame-fun frame)) 4035 (let ((new-frame (copy-edebug--frame frame))
4036 (fun (edebug--frame-fun frame))
4025 (args (edebug--frame-args frame))) 4037 (args (edebug--frame-args frame)))
4026 (cl-decf index) 4038 (cl-decf index)
4027 (when (edebug--frame-evald frame)
4028 (setq before-index nil
4029 after-index nil))
4030 (pcase fun 4039 (pcase fun
4031 ('edebug-enter 4040 ('edebug-enter
4032 (setq skip-next-lambda t 4041 (setq skip-next-lambda t
@@ -4037,17 +4046,18 @@ Remove frames for Edebug's functions and the lambdas in
4037 (nth 0 args)) 4046 (nth 0 args))
4038 after-index (nth 1 args))) 4047 after-index (nth 1 args)))
4039 ((pred edebug--symbol-not-prefixed-p) 4048 ((pred edebug--symbol-not-prefixed-p)
4040 (edebug--unwrap-and-add-info frame def-name before-index after-index) 4049 (edebug--unwrap-frame new-frame)
4041 (setf (edebug--frame-def-name frame) (and before-index def-name)) 4050 (edebug--add-source-info new-frame def-name before-index after-index)
4042 (setf (edebug--frame-before-index frame) before-index) 4051 (edebug--add-source-info frame def-name before-index after-index)
4043 (setf (edebug--frame-after-index frame) after-index) 4052 (push new-frame results)
4044 (push frame results)
4045 (setq before-index nil 4053 (setq before-index nil
4046 after-index nil)) 4054 after-index nil))
4047 (`(,(or 'lambda 'closure) . ,_) 4055 (`(,(or 'lambda 'closure) . ,_)
4048 (unless skip-next-lambda 4056 (unless skip-next-lambda
4049 (edebug--unwrap-and-add-info frame def-name before-index after-index) 4057 (edebug--unwrap-frame new-frame)
4050 (push frame results)) 4058 (edebug--add-source-info frame def-name before-index after-index)
4059 (edebug--add-source-info new-frame def-name before-index after-index)
4060 (push new-frame results))
4051 (setq before-index nil 4061 (setq before-index nil
4052 after-index nil 4062 after-index nil
4053 skip-next-lambda nil))))) 4063 skip-next-lambda nil)))))
@@ -4058,14 +4068,9 @@ Remove frames for Edebug's functions and the lambdas in
4058 (and (symbolp sym) 4068 (and (symbolp sym)
4059 (not (string-prefix-p "edebug-" (symbol-name sym))))) 4069 (not (string-prefix-p "edebug-" (symbol-name sym)))))
4060 4070
4061(defun edebug--unwrap-and-add-info (frame def-name before-index after-index) 4071(defun edebug--unwrap-frame (frame)
4062 "Update FRAME with the additional info needed by an edebug--frame. 4072 "Remove Edebug's instrumentation from FRAME.
4063Save DEF-NAME, BEFORE-INDEX and AFTER-INDEX in FRAME. Also 4073Strip it from the function and any unevaluated arguments."
4064remove Edebug's instrumentation from the function and any
4065unevaluated arguments in FRAME."
4066 (setf (edebug--frame-def-name frame) (and before-index def-name))
4067 (setf (edebug--frame-before-index frame) before-index)
4068 (setf (edebug--frame-after-index frame) after-index)
4069 (setf (edebug--frame-fun frame) (edebug-unwrap* (edebug--frame-fun frame))) 4074 (setf (edebug--frame-fun frame) (edebug-unwrap* (edebug--frame-fun frame)))
4070 (unless (edebug--frame-evald frame) 4075 (unless (edebug--frame-evald frame)
4071 (let (results) 4076 (let (results)
@@ -4073,6 +4078,41 @@ unevaluated arguments in FRAME."
4073 (push (edebug-unwrap* arg) results)) 4078 (push (edebug-unwrap* arg) results))
4074 (setf (edebug--frame-args frame) (nreverse results))))) 4079 (setf (edebug--frame-args frame) (nreverse results)))))
4075 4080
4081(defun edebug--add-source-info (frame def-name before-index after-index)
4082 "Update FRAME with the additional info needed by an edebug--frame.
4083Save DEF-NAME, BEFORE-INDEX and AFTER-INDEX in FRAME."
4084 (when (and before-index def-name)
4085 (setf (edebug--frame-flags frame)
4086 (plist-put (copy-sequence (edebug--frame-flags frame))
4087 :source-available t)))
4088 (setf (edebug--frame-def-name frame) (and before-index def-name))
4089 (setf (edebug--frame-before-index frame) before-index)
4090 (setf (edebug--frame-after-index frame) after-index))
4091
4092(defun edebug--backtrace-goto-source ()
4093 (let* ((index (backtrace-get-index))
4094 (frame (nth index backtrace-frames)))
4095 (when (edebug--frame-def-name frame)
4096 (let* ((data (get (edebug--frame-def-name frame) 'edebug))
4097 (marker (nth 0 data))
4098 (offsets (nth 2 data)))
4099 (pop-to-buffer (marker-buffer marker))
4100 (goto-char (+ (marker-position marker)
4101 (aref offsets (edebug--frame-before-index frame))))))))
4102
4103(defun edebug-backtrace-show-instrumentation ()
4104 "Show Edebug's instrumentation in an Edebug Backtrace buffer."
4105 (interactive)
4106 (unless (eq backtrace-frames edebug-instrumented-backtrace-frames)
4107 (setq backtrace-frames edebug-instrumented-backtrace-frames)
4108 (revert-buffer)))
4109
4110(defun edebug-backtrace-hide-instrumentation ()
4111 "Show Edebug's instrumentation in an Edebug Backtrace buffer."
4112 (interactive)
4113 (unless (eq backtrace-frames edebug-backtrace-frames)
4114 (setq backtrace-frames edebug-backtrace-frames)
4115 (revert-buffer)))
4076 4116
4077;;; Trace display 4117;;; Trace display
4078 4118
@@ -4246,7 +4286,7 @@ It is removed when you hit any char."
4246 ["Bounce to Current Point" edebug-bounce-point t] 4286 ["Bounce to Current Point" edebug-bounce-point t]
4247 ["View Outside Windows" edebug-view-outside t] 4287 ["View Outside Windows" edebug-view-outside t]
4248 ["Previous Result" edebug-previous-result t] 4288 ["Previous Result" edebug-previous-result t]
4249 ["Show Backtrace" edebug-backtrace t] 4289 ["Show Backtrace" edebug-pop-to-backtrace t]
4250 ["Display Freq Count" edebug-display-freq-count t]) 4290 ["Display Freq Count" edebug-display-freq-count t])
4251 4291
4252 ("Eval" 4292 ("Eval"
diff --git a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el
index f3fc78d4e12..97dead057a9 100644
--- a/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el
+++ b/test/lisp/emacs-lisp/edebug-resources/edebug-test-code.el
@@ -41,7 +41,7 @@
41(defun edebug-test-code-range (num) 41(defun edebug-test-code-range (num)
42 !start!(let ((index 0) 42 !start!(let ((index 0)
43 (result nil)) 43 (result nil))
44 (while (< index num)!test! 44 (while !lt!(< index num)!test!
45 (push index result)!loop! 45 (push index result)!loop!
46 (cl-incf index))!end-loop! 46 (cl-incf index))!end-loop!
47 (nreverse result))) 47 (nreverse result)))
diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el
index 7d780edf285..7880aaf95bc 100644
--- a/test/lisp/emacs-lisp/edebug-tests.el
+++ b/test/lisp/emacs-lisp/edebug-tests.el
@@ -432,9 +432,11 @@ test and possibly others should be updated."
432 (verify-keybinding "P" 'edebug-view-outside) ;; same as v 432 (verify-keybinding "P" 'edebug-view-outside) ;; same as v
433 (verify-keybinding "W" 'edebug-toggle-save-windows) 433 (verify-keybinding "W" 'edebug-toggle-save-windows)
434 (verify-keybinding "?" 'edebug-help) 434 (verify-keybinding "?" 'edebug-help)
435 (verify-keybinding "d" 'edebug-backtrace) 435 (verify-keybinding "d" 'edebug-pop-to-backtrace)
436 (verify-keybinding "-" 'negative-argument) 436 (verify-keybinding "-" 'negative-argument)
437 (verify-keybinding "=" 'edebug-temp-display-freq-count))) 437 (verify-keybinding "=" 'edebug-temp-display-freq-count)
438 (should (eq (lookup-key backtrace-mode-map "n") 'backtrace-forward-frame))
439 (should (eq (lookup-key backtrace-mode-map "s") 'backtrace-goto-source))))
438 440
439(ert-deftest edebug-tests-stop-point-at-start-of-first-instrumented-function () 441(ert-deftest edebug-tests-stop-point-at-start-of-first-instrumented-function ()
440 "Edebug stops at the beginning of an instrumented function." 442 "Edebug stops at the beginning of an instrumented function."
@@ -924,5 +926,17 @@ test and possibly others should be updated."
924 "g" 926 "g"
925 (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11"))))) 927 (should (equal edebug-tests-@-result "The result of applying + to (1 x) is 11")))))
926 928
929(ert-deftest edebug-tests-backtrace-goto-source ()
930 "Edebug can jump to instrumented source from its *Edebug-Backtrace* buffer."
931 (edebug-tests-with-normal-env
932 (edebug-tests-setup-@ "range" '(2) t)
933 (edebug-tests-run-kbd-macro
934 "@ SPC SPC"
935 (edebug-tests-should-be-at "range" "lt")
936 "dns" ; Pop to backtrace, next frame, goto source.
937 (edebug-tests-should-be-at "range" "start")
938 "g"
939 (should (equal edebug-tests-@-result '(0 1))))))
940
927(provide 'edebug-tests) 941(provide 'edebug-tests)
928;;; edebug-tests.el ends here 942;;; edebug-tests.el ends here