How to reproduce:
- write some faulty elisp code
- press
C-x C-e
foreval-last-sexp
- the debugger will appear (
*backtrace*
window) and take the focus of the cursor.
I'd like the focus to remain with the original window so. How can I do that?
So the sequencing is a bit tricky as mentioned in the comment below, but reselecting the previous window seems like the easiest way:
(defun my-debug-hook ()
;; Selecting the window in `debug-mode-hook' is too early, it will
;; confuse the debugger's code, causing it to replace the current
;; buffer contents with the backtrace, and reset `buffer-undo-list'!
;; We want to do it when the debugger enters a `recursive-edit'.
;; The (recursive) command loop will call `post-command-hook' once
;; at startup, which is exactly the right time for us.
(add-hook 'post-command-hook #'select-previous-window-once))
(defun select-previous-window-once ()
(select-window (previous-window))
(remove-hook 'post-command-hook #'select-previous-window-once))
(add-hook 'debugger-mode-hook #'my-debug-hook)
.init
, it does not change the *backtrace*
window still takes focus when evaulating lisp code with errors
Commented
Sep 21, 2019 at 17:02
In your comment you say this:
I have a
close-and-kill-next-pane
function defined in my.init
. I use that to kill windows that I just needed temporarily, help docs, etc.After I identify the issue, I want to close the debugger and work on my code. By habit, I hit the keybinding for
close-and-kill-next-pane
and instead of the debugger going away, what I was working on goes away. Does that make sense? Please tell me if that workflow doesn't make sense.
My answer is to tell you that that workflow doesn't make much sense, to me, at least. I'd say that it is better to get out of that habit, or at least to temper it enough to take a quick look at the *Backtrace*
(debugger) window, to see what's going on.
The debugger window is selected by default so you can address the error. What you really want to do, if you're uninterested in what it tells you or you've already taken a look at it, is to dismiss the debugger by hitting q
. That exits the recursive edit that was entered. (Just deleting the window does not exit the recursive edit.)
If, for some reason, the debugger window is no longer selected, you can still exit the recursive edit (without bothering to select that window and use q
). You can use C-]
, which is abort-recursive-edit
, or C-M-c
, which is exit-recursive-edit
, from anywhere.
close-and-kill-next-pane
command does kill the buffer (otherwise it would be called close-next-pane
).
At the end of your configuration, put (setq inhibit-debugger t)
, this will inhibit debugger completely.
Be aware that inhibit-debugger will ignore any value on typical vars such as debug-on-error
, etc.; or the function debug-on-entry
. So, when you want to debug, undo the inhibit-debugger
var!
My motivation was to avoid having a non responsive Emacs terminal, which, after doing abort recursive stuff, ended up "introducing characters", which depends on how they interact with current mode could be harm stuff. And the worst part of it, is when you are doing things very fast and you did not realize what happened.
close-and-kill-next-pane
function defined in my.init
. I use that to kill windows that I just needed temporarily, help docs, etc. After I identify the issue, I want to close the debugger and work on my code. By habbit,i hit the keybinding forclose-and-kill-next-pane
and instead of the debugger going away, what i was working on goes away. Does that make sense? Please tell me if that workflow doesn't make sense. I'm new to writing elisp code.recursive-edit
. It is possible to remain inrecursive-edit
and do other things; however, it is usually a good idea to deal with the bug while you have the debugger window open. The debugger window can be closed with the letterq
when focus is in that debugging buffer, and that exitsrecursive-edit
. There are other ways to exitrecursive-edit
, but theq
key is generally the most convenient (in my opinion).