From c6d52846598eeaf200c553ff0ac9f16db612b64e Mon Sep 17 00:00:00 2001 From: Noam Postavsky Date: Fri, 21 Jun 2019 08:14:20 -0400 Subject: [PATCH] Suppress recursive debugger for 'e' command (Bug#36145) * lisp/emacs-lisp/debug.el (debugger-eval-expression): * lisp/emacs-lisp/edebug.el (edebug-eval-expression) (edebug-eval-last-sexp, edebug-eval-print-last-sexp): Suppress debugger with inhibit-debugger, unless given a prefix argument. * doc/lispref/edebug.texi (Edebug Eval): * doc/lispref/debugging.texi (Debugger Commands, Backtraces): Document new behavior. (Using Debugger): Remove incorrect paragraph about debug-on-error. * etc/NEWS: Announce new behavior. --- doc/lispref/debugging.texi | 15 ++++----------- doc/lispref/edebug.texi | 10 +++++++--- etc/NEWS | 11 +++++++++++ lisp/emacs-lisp/debug.el | 12 ++++++++---- lisp/emacs-lisp/edebug.el | 33 +++++++++++++++++++++------------ 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 9e43343310..7538e70ab5 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -383,16 +383,6 @@ Using Debugger rather than bury it. Consult the variable's documentation for more possibilities.) - When the debugger has been entered, the @code{debug-on-error} -variable is temporarily set according to -@code{eval-expression-debug-on-error}. If the latter variable is -non-@code{nil}, @code{debug-on-error} will temporarily be set to -@code{t}. This means that any further errors that occur while doing a -debugging session will (by default) trigger another backtrace. If -this is not what you want, you can either set -@code{eval-expression-debug-on-error} to @code{nil}, or set -@code{debug-on-error} to @code{nil} in @code{debugger-mode-hook}. - The debugger itself must be run byte-compiled, since it makes assumptions about the state of the Lisp interpreter. These assumptions are false if the debugger is running interpreted. @@ -527,7 +517,10 @@ Debugger Commands temporarily restores their values from outside the debugger, so you can examine and change them. This makes the debugger more transparent. By contrast, @kbd{M-:} does nothing special in the debugger; it shows you -the variable values within the debugger. +the variable values within the debugger. By default, this command +suppresses the debugger during evaluation, so that an error in the +evaluated expression won't add a new error on top of the existing one. +Use the prefix argument to override this. @item R Like @kbd{e}, but also save the result of evaluation in the diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 2c0ee3969b..823a5009e8 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -681,8 +681,11 @@ Edebug Eval @table @kbd @item e @var{exp} @key{RET} Evaluate expression @var{exp} in the context outside of Edebug -(@code{edebug-eval-expression}). That is, Edebug tries to minimize its -interference with the evaluation. +(@code{edebug-eval-expression}). That is, Edebug tries to minimize +its interference with the evaluation. By default, this command +suppresses the debugger during evaluation, so that an error in the +evaluated expression won't add a new error on top of the existing one. +Use a prefix argument to override this. @item M-: @var{exp} @key{RET} Evaluate expression @var{exp} in the context of Edebug itself @@ -690,7 +693,8 @@ Edebug Eval @item C-x C-e Evaluate the expression before point, in the context outside of Edebug -(@code{edebug-eval-last-sexp}). +(@code{edebug-eval-last-sexp}). Similar to @key{e}, this command +suppresses the debugger unless a prefix argument is used. @end table @cindex lexical binding (Edebug) diff --git a/etc/NEWS b/etc/NEWS index 4a168d5678..43dc6ea969 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1074,6 +1074,11 @@ Backtrace mode adds fontification and commands for changing the appearance of backtrace frames. See the node "(elisp) Backtraces" in the Elisp manual for documentation of the new mode and its commands. ++++ +*** Recursive debugging is suppressed by default for 'e'. +That is bound to the command 'debug-eval-expression'. Use a prefix +argument to override this. + ** Edebug +++ @@ -1098,6 +1103,12 @@ The new 'backtrace-goto-source' command, bound to 's', works in Edebug's backtraces on backtrace frames whose source code has been instrumented by Edebug. ++++ +*** Backtrace debugging is suppressed by default for 'e' and 'C-x C-e'. +Those are bound to the commands 'edebug-eval-expression' and +'edebug-eval-last-sexp', respectively. Use a prefix argument to +override this. + ** Enhanced xterm support *** New variable 'xterm-set-window-title' controls whether Emacs sets diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index 8989aa0719..20aceccb68 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -516,17 +516,21 @@ (defun debugger--backtrace-base () 'debug--implement-debug-on-entry) (t 'debug))) -(defun debugger-eval-expression (exp &optional nframe) +(defun debugger-eval-expression (exp &optional nframe allow-recursive-debug) "Eval an expression, in an environment like that outside the debugger. -The environment used is the one when entering the activation frame at point." +The environment used is the one when entering the activation frame at point. +With a prefix argument, errors signaled while evaluating may +trigger the debugger again." (interactive - (list (read--expression "Eval in stack frame: "))) + (list (read--expression "Eval in stack frame: ") + nil current-prefix-arg)) (let ((nframe (or nframe (condition-case nil (1+ (debugger-frame-number 'skip-base)) (error 0)))) ;; If on first line. (base (debugger--backtrace-base))) (debugger-env-macro - (let ((val (backtrace-eval exp nframe base))) + (let ((val (let ((inhibit-debugger (not allow-recursive-debug))) + (backtrace-eval exp nframe base)))) (prog1 (debugger--print val t) (let ((str (eval-expression-print-format val))) diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index ab5553b4e8..1f9d994fed 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3580,28 +3580,37 @@ (defalias 'edebug-prin1-to-string #'cl-prin1-to-string) (defalias 'edebug-format #'format-message) (defalias 'edebug-message #'message) -(defun edebug-eval-expression (expr) +(defun edebug-eval-expression (expr &optional allow-debugger) "Evaluate an expression in the outside environment. If interactive, prompt for the expression. -Print result in minibuffer." - (interactive (list (read--expression "Eval: "))) +Print result in minibuffer. +With a prefix argument, errors signaled while evaluating may +trigger the debugger." + (interactive (list (read--expression "Eval: ") + current-prefix-arg)) (princ (edebug-outside-excursion - (setq values (cons (edebug-eval expr) values)) + (push (let ((inhibit-debugger (not allow-debugger))) + (edebug-eval expr)) + values) (concat (edebug-safe-prin1-to-string (car values)) (eval-expression-print-format (car values)))))) -(defun edebug-eval-last-sexp () +(defun edebug-eval-last-sexp (&optional allow-debugger) "Evaluate sexp before point in the outside environment. -Print value in minibuffer." - (interactive) - (edebug-eval-expression (edebug-last-sexp))) +Print value in minibuffer. +With a prefix argument, errors signaled while evaluating may +trigger the debugger." + (interactive "P") + (edebug-eval-expression (edebug-last-sexp allow-debugger))) -(defun edebug-eval-print-last-sexp () +(defun edebug-eval-print-last-sexp (&optional allow-debugger) "Evaluate sexp before point in outside environment; insert value. -This prints the value into current buffer." - (interactive) - (let* ((form (edebug-last-sexp)) +This prints the value into current buffer. +With a prefix argument, errors signaled while evaluating may +trigger the debugger." + (interactive "P") + (let* ((form (edebug-last-sexp allow-debugger)) (result-string (edebug-outside-excursion (edebug-safe-prin1-to-string (edebug-safe-eval form)))) -- 2.11.0