From e09120d68694272ea5efbe13b16936b4382389d8 Mon Sep 17 00:00:00 2001 From: Gemini Lasswell Date: Tue, 19 Jun 2018 07:27:41 -0700 Subject: Add backtrace-mode and use it in the debugger, ERT and Edebug * doc/lispref/debugging.texi (Using Debugger): Remove explanation of backtrace buffer. Refer to new node. (Backtraces): New node. (Debugger Commands): Refer to new node. Remove 'v'. * doc/lispref/edebug.texi (Edebug Misc): Refer to new node. * doc/misc/ert.texi (Running Tests Interactively): Refer to new node. * lisp/emacs-lisp-backtrace.el: New file. * test/lisp/emacs-lisp/backtrace-tests.el: New file. * lisp/emacs-lisp/debug.el: (debugger-buffer-state): New cl-defstruct. (debugger--restore-buffer-state): New function. (debug): Use a debugger-buffer-state object to save and restore buffer state. Fix bug#15749 by leaving an unused buffer in debugger-mode, empty, instead of in fundamental-mode, and then when reusing a buffer, not calling debugger-mode if the buffer is already in debugger-mode. (debugger-insert-backtrace): Remove. (debugger-setup-buffer): Use backtrace-mode. (debugger--insert-header): New function. (debugger-continue, debugger-return-value): Change check for flags to use backtrace-frames. (debugger-frame-number): Determine backtrace frame number from backtrace-frames. (debugger--locals-visible-p, debugger--insert-locals) (debugger--show-locals, debugger--hide-locals) (debugger-toggle-locals): Remove. (debugger-mode-map): Make a child of backtrace-mode-map. Move navigation commands to backtrace-mode-map. Bind 'q' to debugger-quit instead of top-level. Make Help Follow menu item call backtrace-help-follow-symbol. (debugger-mode): Derive from backtrace-mode. (debug-help-follow): Remove. Move body of this function to 'backtrace-help-follow-symbol' in backtrace.el. (debugger-quit): New function. * lisp/emacs-lisp/edebug.el (edebug-unwrap-results): Remove warning in docstring about circular results. (edebug-unwrap): Use pcase. (edebug-unwrap1): New function to unwrap circular objects. (edebug-unwrap*): Use it. (edebug--frame): New cl-defstruct. (edebug-backtrace): Call the buffer *Edebug Backtrace* and use backtrace-mode. Get the frames from edebug--backtrace-frames. (edebug--backtrace-frames, edebug--unwrap-and-add-info) (edebug--symbol-not-prefixed-p): New functions. * lisp/emacs-lisp/lisp-mode.el (lisp-el-font-lock-keywords-for-backtraces) (lisp-el-font-lock-keywords-for-backtraces-1) (lisp-el-font-lock-keywords-for-backtraces-2): New constants. * lisp/emacs-lisp/ert.el (ert--print-backtrace): Remove. (ert--run-test-debugger): Use backtrace-get-frames. (ert-run-tests-batch): Use backtrace-to-string. (ert-results-pop-to-backtrace-for-test-at-point): Use backtrace-mode. (ert--insert-backtrace-header): New function. * tests/lisp/emacs-lisp/ert-tests.el (ert-test--which-file): Use backtrace-frame slot accessor. --- lisp/emacs-lisp/ert.el | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) (limited to 'lisp/emacs-lisp/ert.el') diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index cad21044f15..7178493ebe5 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -60,6 +60,7 @@ (require 'cl-lib) (require 'button) (require 'debug) +(require 'backtrace) (require 'easymenu) (require 'ewoc) (require 'find-func) @@ -677,13 +678,6 @@ and is displayed in front of the value of MESSAGE-FORM." (cl-defstruct (ert-test-aborted-with-non-local-exit (:include ert-test-result))) -(defun ert--print-backtrace (backtrace do-xrefs) - "Format the backtrace BACKTRACE to the current buffer." - (let ((print-escape-newlines t) - (print-level 8) - (print-length 50)) - (debugger-insert-backtrace backtrace do-xrefs))) - ;; A container for the state of the execution of a single test and ;; environment data needed during its execution. (cl-defstruct ert--test-execution-info @@ -732,7 +726,7 @@ run. ARGS are the arguments to `debugger'." ;; use. ;; ;; Grab the frames above the debugger. - (backtrace (cdr (backtrace-frames debugger))) + (backtrace (cdr (backtrace-get-frames debugger))) (infos (reverse ert--infos))) (setf (ert--test-execution-info-result info) (cl-ecase type @@ -1406,9 +1400,8 @@ Returns the stats object." (ert-test-result-with-condition (message "Test %S backtrace:" (ert-test-name test)) (with-temp-buffer - (ert--print-backtrace - (ert-test-result-with-condition-backtrace result) - nil) + (insert (backtrace-to-string + (ert-test-result-with-condition-backtrace result))) (if (not ert-batch-backtrace-right-margin) (message "%s" (buffer-substring-no-properties (point-min) @@ -2450,20 +2443,21 @@ To be used in the ERT results buffer." (cl-etypecase result (ert-test-passed (error "Test passed, no backtrace available")) (ert-test-result-with-condition - (let ((backtrace (ert-test-result-with-condition-backtrace result)) - (buffer (get-buffer-create "*ERT Backtrace*"))) + (let ((buffer (get-buffer-create "*ERT Backtrace*"))) (pop-to-buffer buffer) - (let ((inhibit-read-only t)) - (buffer-disable-undo) - (erase-buffer) - (ert-simple-view-mode) - (set-buffer-multibyte t) ; mimic debugger-setup-buffer - (setq truncate-lines t) - (ert--print-backtrace backtrace t) - (goto-char (point-min)) - (insert (substitute-command-keys "Backtrace for test `")) - (ert-insert-test-name-button (ert-test-name test)) - (insert (substitute-command-keys "':\n")))))))) + (unless (derived-mode-p 'backtrace-mode) + (backtrace-mode)) + (setq backtrace-insert-header-function + (lambda () (ert--insert-backtrace-header (ert-test-name test))) + backtrace-frames (ert-test-result-with-condition-backtrace result) + backtrace-view '(:do-xrefs t)) + (backtrace-print) + (goto-char (point-min))))))) + +(defun ert--insert-backtrace-header (name) + (insert (substitute-command-keys "Backtrace for test `")) + (ert-insert-test-name-button name) + (insert (substitute-command-keys "':\n"))) (defun ert-results-pop-to-messages-for-test-at-point () "Display the part of the *Messages* buffer generated during the test at point. -- cgit v1.2.3 From 5b50fa5a9d4f7c032a845bc0152c11b70ee1bf53 Mon Sep 17 00:00:00 2001 From: Gemini Lasswell Date: Sun, 24 Jun 2018 07:17:47 -0700 Subject: Always make buttons from function names in backtraces * lisp/emacs-lisp/backtrace.el (backtrace-view) (backtrace--print-func-and-args, backtrace-mode): Always make buttons. Remove all uses of ':do-xrefs'. * lisp/emacs-lisp/debug.el (debugger-setup-buffer): Modify backtrace-view instead of setting it. * lisp/emacs-lisp/edebug.el (edebug-backtrace): * lisp/emacs-lisp/ert.el (ert-results-pop-to-backtrace-for-test-at-point): Remove initialization of backtrace-view. --- lisp/emacs-lisp/backtrace.el | 13 +++++++------ lisp/emacs-lisp/debug.el | 2 +- lisp/emacs-lisp/edebug.el | 3 +-- lisp/emacs-lisp/ert.el | 3 +-- 4 files changed, 10 insertions(+), 11 deletions(-) (limited to 'lisp/emacs-lisp/ert.el') diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el index d16edb6a6cf..bcff14705c7 100644 --- a/lisp/emacs-lisp/backtrace.el +++ b/lisp/emacs-lisp/backtrace.el @@ -146,7 +146,7 @@ This should be a list of `backtrace-frame' objects.") (defvar-local backtrace-view nil "A plist describing how to render backtrace frames. -Possible entries are :show-flags, :do-xrefs and :print-circle.") +Possible entries are :show-flags and :print-circle.") (defvar-local backtrace-insert-header-function nil "Function for inserting a header for the current Backtrace buffer. @@ -591,14 +591,14 @@ property for use by navigation." (insert (if (and (plist-get view :show-flags) flag) "* " " ")) (put-text-property beg (point) 'backtrace-section 'func))) -(defun backtrace--print-func-and-args (frame view) +(defun backtrace--print-func-and-args (frame _view) "Print the function, arguments and buffer position of a backtrace FRAME. Format it according to VIEW." (let* ((beg (point)) (evald (backtrace-frame-evald frame)) (fun (backtrace-frame-fun frame)) (args (backtrace-frame-args frame)) - (fun-file (and (plist-get view :do-xrefs) (symbol-file fun 'defun))) + (fun-file (symbol-file fun 'defun)) (fun-pt (point))) (cond ((and evald (not debugger-stack-frame-as-list)) @@ -707,15 +707,16 @@ creates a backtrace-mode buffer, should usually do the following: - Maybe set `backtrace-insert-header-function' to a function to create header text for the buffer. - Set `backtrace-frames' (see below). - - Set `backtrace-view' if desired (see below). + - Maybe modify `backtrace-view' (see below). - Maybe set `backtrace-print-function'. A command which creates or switches to a Backtrace mode buffer, such as `ert-results-pop-to-backtrace-for-test-at-point', should initialize `backtrace-frames' to a list of `backtrace-frame' objects (`backtrace-get-frames' is provided for that purpose, if -desired), and `backtrace-view' to a plist describing how it wants -the backtrace to appear. Finally, it should call `backtrace-print'. +desired), and may optionally modify `backtrace-view', which is a +plist describing the appearance of the backtrace. Finally, it +should call `backtrace-print'. `backtrace-print' calls `backtrace-insert-header-function' followed by `backtrace-print-frame', once for each stack frame." diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index 707e0cfa186..48ca32ddd83 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -335,7 +335,7 @@ That buffer should be current already and in debugger-mode." :debug-on-exit) nil)) - (setq backtrace-view '(:do-xrefs t :show-flags t) + (setq backtrace-view (plist-put backtrace-view :show-flags t) backtrace-insert-header-function (lambda () (debugger--insert-header args)) backtrace-print-function debugger-print-function) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index b22c8952da0..3bf9cb9a488 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -4007,8 +4007,7 @@ Otherwise call `debug' normally." (with-current-buffer edebug-backtrace-buffer (unless (derived-mode-p 'backtrace-mode) (backtrace-mode)) - (setq backtrace-frames (edebug--backtrace-frames) - backtrace-view '(:do-xrefs t)) + (setq backtrace-frames (edebug--backtrace-frames)) (backtrace-print) (goto-char (point-min))))) diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 7178493ebe5..eb9695d0c12 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -2449,8 +2449,7 @@ To be used in the ERT results buffer." (backtrace-mode)) (setq backtrace-insert-header-function (lambda () (ert--insert-backtrace-header (ert-test-name test))) - backtrace-frames (ert-test-result-with-condition-backtrace result) - backtrace-view '(:do-xrefs t)) + backtrace-frames (ert-test-result-with-condition-backtrace result)) (backtrace-print) (goto-char (point-min))))))) -- cgit v1.2.3