From d1890a3a4a18f79cabf4caf8d194cdc29ea4bf05 Mon Sep 17 00:00:00 2001 From: Vasilij Schneidermann Date: Fri, 30 Sep 2016 16:22:26 +0300 Subject: [PATCH] New user option 'debugger-stack-frame-as-list' * src/eval.c (syms_of_eval) : New variable. * lisp/cus-start.el (standard): Add debugger-stack-frame-as-list. * lisp/emacs-lisp/debug.el (debugger-setup-buffer): Adjust backtrace processing for the value of debugger-stack-frame-as-list. * lisp/emacs-lisp/edebug.el (edebug-backtrace): Adjust backtrace processing for the value of debugger-stack-frame-as-list. * doc/lispref/debugging.texi (Internals of Debugger): Document debugger-stack-frame-as-list. * etc/NEWS: Mention 'debugger-stack-frame-as-list'. --- doc/lispref/debugging.texi | 31 +++++++++++++++++++++++++++++++ etc/NEWS | 5 +++++ lisp/cus-start.el | 1 + lisp/emacs-lisp/debug.el | 4 +++- lisp/emacs-lisp/edebug.el | 4 +++- src/eval.c | 12 ++++++++++-- 6 files changed, 53 insertions(+), 4 deletions(-) diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 2f83b4040fa..710ab92fda5 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -623,6 +623,37 @@ forms are elided. @end smallexample @end deffn +@defvar debugger-stack-frame-as-list +If this variable is non-@code{nil}, every stack frame of the backtrace +is displayed as a list. This aims at improving the backtrace +readability at the cost of special forms no longer being visually +different from regular function calls. + +With @code{debugger-stack-frame-as-list} non-@code{nil}, the above +example would look as follows: + +@smallexample +@group +----------- Buffer: backtrace-output ------------ + (backtrace) + (list ...computing arguments...) +@end group + (progn ...) + (eval (progn (1+ var) (list (quote testing) (backtrace)))) + (setq ...) + (save-excursion ...) + (let ...) + (with-output-to-temp-buffer ...) + (eval (with-output-to-temp-buffer ...)) + (eval-last-sexp-1 nil) +@group + (eval-last-sexp nil) + (call-interactively eval-last-sexp) +----------- Buffer: backtrace-output ------------ +@end group +@end smallexample +@end defvar + @defvar debug-on-next-call @cindex @code{eval}, and debugging @cindex @code{apply}, and debugging diff --git a/etc/NEWS b/etc/NEWS index c3f4cf01b26..dffbac8df65 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -205,6 +205,11 @@ questions, with a handy way to display help texts. +++ ** 'switch-to-buffer-preserve-window-point' now defaults to t. ++++ +** The new variable 'debugger-stack-frame-as-list' allows displaying +all call stack frames in a Lisp backtrace buffer as lists. Both +debug.el and edebug.el have been updated to heed to this variable. + * Editing Changes in Emacs 25.3 diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 2b79bbbfda1..d9ad0a5971e 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -246,6 +246,7 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (debug-ignored-errors debug (repeat (choice symbol regexp))) (debug-on-quit debug boolean) (debug-on-signal debug boolean) + (debugger-stack-frame-as-list debugger boolean) ;; fileio.c (delete-by-moving-to-trash auto-save boolean "23.1") (auto-save-visited-file-name auto-save boolean) diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index 22a3f3935f2..7d273809fcd 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -279,7 +279,9 @@ That buffer should be current already." (goto-char (point-min)) (delete-region (point) (progn - (search-forward "\n debug(") + (search-forward (if debugger-stack-frame-as-list + "\n (debug " + "\n debug(")) (forward-line (if (eq (car args) 'debug) ;; Remove debug--implement-debug-on-entry ;; and the advice's `apply' frame. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 1a00c45447c..6918539e229 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3798,7 +3798,9 @@ Otherwise call `debug' normally." (forward-line 1) (delete-region last-ok-point (point))) - ((looking-at "^ edebug") + ((looking-at (if debugger-stack-frame-as-list + "^ (edebug" + "^ edebug")) (forward-line 1) (delete-region last-ok-point (point)) ))) diff --git a/src/eval.c b/src/eval.c index e08a25a31a0..407561082d1 100644 --- a/src/eval.c +++ b/src/eval.c @@ -3421,13 +3421,17 @@ Output stream used is value of `standard-output'. */) else { tem = backtrace_function (pdl); + if (debugger_stack_frame_as_list) + write_string ("("); Fprin1 (tem, Qnil); /* This can QUIT. */ - write_string ("("); + if (!debugger_stack_frame_as_list) + write_string ("("); { ptrdiff_t i; for (i = 0; i < backtrace_nargs (pdl); i++) { - if (i) write_string (" "); + if (i || debugger_stack_frame_as_list) + write_string(" "); Fprin1 (backtrace_args (pdl)[i], Qnil); } } @@ -3850,6 +3854,10 @@ This is nil when the debugger is called under circumstances where it might not be safe to continue. */); debugger_may_continue = 1; + DEFVAR_BOOL ("debugger-stack-frame-as-list", debugger_stack_frame_as_list, + doc: /* Non-nil means display call stack frames as lists. */); + debugger_stack_frame_as_list = 0; + DEFVAR_LISP ("debugger", Vdebugger, doc: /* Function to call to invoke debugger. If due to frame exit, args are `exit' and the value being returned; -- 2.39.5