diff options
| author | Martin Rudalics | 2012-09-08 15:28:11 +0200 |
|---|---|---|
| committer | Martin Rudalics | 2012-09-08 15:28:11 +0200 |
| commit | fa2bcf435d9774c0e8542ba36b11ef4722f9675c (patch) | |
| tree | ae13b3c6076ec4c063e4ebaa5b093a2f56dc8a55 | |
| parent | aa7d57c5079024458c5e25cd5f304d1b967bcbe6 (diff) | |
| download | emacs-fa2bcf435d9774c0e8542ba36b11ef4722f9675c.tar.gz emacs-fa2bcf435d9774c0e8542ba36b11ef4722f9675c.zip | |
Fix handling of debugger window. (Bug#8789)
* window.el (display-buffer-in-previous-window): New buffer
display action function.
* emacs-lisp/debug.el (debugger-bury-or-kill): New option.
(debugger-previous-window): New variable.
(debug): Rewrite using display-buffer-in-previous-window,
quit-restore-window and debugger-bury-or-kill. (Bug#8789)
| -rw-r--r-- | etc/NEWS | 25 | ||||
| -rw-r--r-- | lisp/ChangeLog | 10 | ||||
| -rw-r--r-- | lisp/emacs-lisp/debug.el | 163 | ||||
| -rw-r--r-- | lisp/window.el | 56 |
4 files changed, 174 insertions, 80 deletions
| @@ -645,6 +645,8 @@ The interpretation of the DECLS is determined by `defun-declarations-alist'. | |||
| 645 | 645 | ||
| 646 | ** New error type and new function `user-error'. Doesn't trigger the debugger. | 646 | ** New error type and new function `user-error'. Doesn't trigger the debugger. |
| 647 | 647 | ||
| 648 | ** New option `debugger-bury-or-kill'. | ||
| 649 | |||
| 648 | +++ | 650 | +++ |
| 649 | ** New utility function `buffer-narrowed-p'. | 651 | ** New utility function `buffer-narrowed-p'. |
| 650 | 652 | ||
| @@ -653,20 +655,25 @@ The interpretation of the DECLS is determined by `defun-declarations-alist'. | |||
| 653 | *** The functions get-lru-window, get-mru-window and get-largest-window | 655 | *** The functions get-lru-window, get-mru-window and get-largest-window |
| 654 | now accept a third argument to avoid choosing the selected window. | 656 | now accept a third argument to avoid choosing the selected window. |
| 655 | 657 | ||
| 656 | *** New macro with-temp-buffer-window. | 658 | *** New macro `with-temp-buffer-window'. |
| 659 | |||
| 660 | *** New option `temp-buffer-resize-frames'. | ||
| 657 | 661 | ||
| 658 | *** New option temp-buffer-resize-frames. | 662 | *** New function `fit-frame-to-buffer' and new option |
| 663 | `fit-frame-to-buffer-bottom-margin'. | ||
| 659 | 664 | ||
| 660 | *** New function fit-frame-to-buffer and new option | 665 | *** New display action functions `display-buffer-below-selected' and |
| 661 | fit-frame-to-buffer-bottom-margin. | 666 | `display-buffer-in-previous-window'. |
| 662 | 667 | ||
| 663 | *** New display action function display-buffer-below-selected. | 668 | *** New display action alist entry `inhibit-switch-frame', if non-nil, |
| 669 | tells display action functions to avoid changing which frame is | ||
| 670 | selected. | ||
| 664 | 671 | ||
| 665 | *** New display action alist `inhibit-switch-frame', if non-nil, tells | 672 | *** New display action alist entry `pop-up-frame-parameters', if |
| 666 | display action functions to avoid changing which frame is selected. | 673 | non-nil, specifies frame parameters to give any newly-created frame. |
| 667 | 674 | ||
| 668 | *** New display action alist `pop-up-frame-parameters', if non-nil, | 675 | *** New display action alist entry `previous-window', if non-nil, |
| 669 | specifies frame parameters to give any newly-created frame. | 676 | specifies window to reuse in `display-buffer-in-previous-window'. |
| 670 | 677 | ||
| 671 | *** The following variables are obsolete, as they can be replaced by | 678 | *** The following variables are obsolete, as they can be replaced by |
| 672 | appropriate entries in the `display-buffer-alist' function introduced | 679 | appropriate entries in the `display-buffer-alist' function introduced |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 052b85ef757..e10fe9166e7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2012-09-08 Martin Rudalics <rudalics@gmx.at> | ||
| 2 | |||
| 3 | * window.el (display-buffer-in-previous-window): New buffer | ||
| 4 | display action function. | ||
| 5 | |||
| 6 | * emacs-lisp/debug.el (debugger-bury-or-kill): New option. | ||
| 7 | (debugger-previous-window): New variable. | ||
| 8 | (debug): Rewrite using display-buffer-in-previous-window, | ||
| 9 | quit-restore-window and debugger-bury-or-kill. (Bug#8789) | ||
| 10 | |||
| 1 | 2012-09-07 Stefan Monnier <monnier@iro.umontreal.ca> | 11 | 2012-09-07 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 12 | ||
| 3 | * emacs-lisp/byte-run.el (defun): Tweak message. Simplify code. | 13 | * emacs-lisp/byte-run.el (defun): Tweak message. Simplify code. |
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index 7bc93a19d1a..188c0800eb8 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el | |||
| @@ -48,6 +48,39 @@ the middle is discarded, and just the beginning and end are displayed." | |||
| 48 | :group 'debugger | 48 | :group 'debugger |
| 49 | :version "21.1") | 49 | :version "21.1") |
| 50 | 50 | ||
| 51 | (defcustom debugger-bury-or-kill 'bury | ||
| 52 | "How to proceed with the debugger buffer when exiting `debug'. | ||
| 53 | The value used here affects the behavior of operations on any | ||
| 54 | window previously showing the debugger buffer. | ||
| 55 | |||
| 56 | `nil' means that if its window is not deleted when exiting the | ||
| 57 | debugger, invoking `switch-to-prev-buffer' will usually show | ||
| 58 | the debugger buffer again. | ||
| 59 | |||
| 60 | `append' means that if the window is not deleted, the debugger | ||
| 61 | buffer moves to the end of the window's previous buffers so | ||
| 62 | it's less likely that a future invocation of | ||
| 63 | `switch-to-prev-buffer' will switch to it. Also, it moves the | ||
| 64 | buffer to the end of the frame's buffer list. | ||
| 65 | |||
| 66 | `bury' means that if the window is not deleted, its buffer is | ||
| 67 | removed from the window's list of previous buffers. Also, it | ||
| 68 | moves the buffer to the end of the frame's buffer list. This | ||
| 69 | value provides the most reliable remedy to not have | ||
| 70 | `switch-to-prev-buffer' switch to the debugger buffer again | ||
| 71 | without killing the buffer. | ||
| 72 | |||
| 73 | `kill' means to kill the debugger buffer. | ||
| 74 | |||
| 75 | The value used here is passed to `quit-restore-window'." | ||
| 76 | :type '(choice | ||
| 77 | (const :tag "Keep alive" nil) | ||
| 78 | (const :tag "Append" 'append) | ||
| 79 | (const :tag "Bury" 'bury) | ||
| 80 | (const :tag "Kill" 'kill)) | ||
| 81 | :group 'debugger | ||
| 82 | :version "24.2") | ||
| 83 | |||
| 51 | (defvar debug-function-list nil | 84 | (defvar debug-function-list nil |
| 52 | "List of functions currently set for debug on entry.") | 85 | "List of functions currently set for debug on entry.") |
| 53 | 86 | ||
| @@ -60,6 +93,9 @@ the middle is discarded, and just the beginning and end are displayed." | |||
| 60 | (defvar debugger-old-buffer nil | 93 | (defvar debugger-old-buffer nil |
| 61 | "This is the buffer that was current when the debugger was entered.") | 94 | "This is the buffer that was current when the debugger was entered.") |
| 62 | 95 | ||
| 96 | (defvar debugger-previous-window nil | ||
| 97 | "This is the window last showing the debugger buffer.") | ||
| 98 | |||
| 63 | (defvar debugger-previous-backtrace nil | 99 | (defvar debugger-previous-backtrace nil |
| 64 | "The contents of the previous backtrace (including text properties). | 100 | "The contents of the previous backtrace (including text properties). |
| 65 | This is to optimize `debugger-make-xrefs'.") | 101 | This is to optimize `debugger-make-xrefs'.") |
| @@ -133,7 +169,7 @@ first will be printed into the backtrace buffer." | |||
| 133 | (with-current-buffer (get-buffer "*Backtrace*") | 169 | (with-current-buffer (get-buffer "*Backtrace*") |
| 134 | (list major-mode (buffer-string))))) | 170 | (list major-mode (buffer-string))))) |
| 135 | (debugger-buffer (get-buffer-create "*Backtrace*")) | 171 | (debugger-buffer (get-buffer-create "*Backtrace*")) |
| 136 | (debugger-old-buffer (current-buffer)) | 172 | (debugger-window nil) |
| 137 | (debugger-step-after-exit nil) | 173 | (debugger-step-after-exit nil) |
| 138 | (debugger-will-be-back nil) | 174 | (debugger-will-be-back nil) |
| 139 | ;; Don't keep reading from an executing kbd macro! | 175 | ;; Don't keep reading from an executing kbd macro! |
| @@ -184,78 +220,63 @@ first will be printed into the backtrace buffer." | |||
| 184 | (cursor-in-echo-area nil)) | 220 | (cursor-in-echo-area nil)) |
| 185 | (unwind-protect | 221 | (unwind-protect |
| 186 | (save-excursion | 222 | (save-excursion |
| 187 | (save-window-excursion | 223 | (with-no-warnings |
| 188 | (with-no-warnings | 224 | (setq unread-command-char -1)) |
| 189 | (setq unread-command-char -1)) | 225 | (when (eq (car debugger-args) 'debug) |
| 190 | (when (eq (car debugger-args) 'debug) | 226 | ;; Skip the frames for backtrace-debug, byte-code, |
| 191 | ;; Skip the frames for backtrace-debug, byte-code, | 227 | ;; and implement-debug-on-entry. |
| 192 | ;; and implement-debug-on-entry. | 228 | (backtrace-debug 4 t) |
| 193 | (backtrace-debug 4 t) | 229 | ;; Place an extra debug-on-exit for macro's. |
| 194 | ;; Place an extra debug-on-exit for macro's. | 230 | (when (eq 'lambda (car-safe (cadr (backtrace-frame 4)))) |
| 195 | (when (eq 'lambda (car-safe (cadr (backtrace-frame 4)))) | 231 | (backtrace-debug 5 t))) |
| 196 | (backtrace-debug 5 t))) | 232 | (pop-to-buffer |
| 197 | (pop-to-buffer debugger-buffer) | 233 | debugger-buffer |
| 198 | (debugger-mode) | 234 | `((display-buffer-reuse-window |
| 199 | (debugger-setup-buffer debugger-args) | 235 | display-buffer-in-previous-window) |
| 200 | (when noninteractive | 236 | . (,(when debugger-previous-window |
| 201 | ;; If the backtrace is long, save the beginning | 237 | `(previous-window . ,debugger-previous-window))))) |
| 202 | ;; and the end, but discard the middle. | 238 | (setq debugger-window (selected-window)) |
| 203 | (when (> (count-lines (point-min) (point-max)) | 239 | (setq debugger-previous-window debugger-window) |
| 204 | debugger-batch-max-lines) | 240 | (debugger-mode) |
| 205 | (goto-char (point-min)) | 241 | (debugger-setup-buffer debugger-args) |
| 206 | (forward-line (/ 2 debugger-batch-max-lines)) | 242 | (when noninteractive |
| 207 | (let ((middlestart (point))) | 243 | ;; If the backtrace is long, save the beginning |
| 208 | (goto-char (point-max)) | 244 | ;; and the end, but discard the middle. |
| 209 | (forward-line (- (/ 2 debugger-batch-max-lines) | 245 | (when (> (count-lines (point-min) (point-max)) |
| 210 | debugger-batch-max-lines)) | 246 | debugger-batch-max-lines) |
| 211 | (delete-region middlestart (point))) | ||
| 212 | (insert "...\n")) | ||
| 213 | (goto-char (point-min)) | 247 | (goto-char (point-min)) |
| 214 | (message "%s" (buffer-string)) | 248 | (forward-line (/ 2 debugger-batch-max-lines)) |
| 215 | (kill-emacs -1)) | 249 | (let ((middlestart (point))) |
| 250 | (goto-char (point-max)) | ||
| 251 | (forward-line (- (/ 2 debugger-batch-max-lines) | ||
| 252 | debugger-batch-max-lines)) | ||
| 253 | (delete-region middlestart (point))) | ||
| 254 | (insert "...\n")) | ||
| 255 | (goto-char (point-min)) | ||
| 256 | (message "%s" (buffer-string)) | ||
| 257 | (kill-emacs -1)) | ||
| 258 | (message "") | ||
| 259 | (let ((standard-output nil) | ||
| 260 | (buffer-read-only t)) | ||
| 216 | (message "") | 261 | (message "") |
| 217 | (let ((standard-output nil) | 262 | ;; Make sure we unbind buffer-read-only in the right buffer. |
| 218 | (buffer-read-only t)) | 263 | (save-excursion |
| 219 | (message "") | 264 | (recursive-edit)))) |
| 220 | ;; Make sure we unbind buffer-read-only in the right buffer. | 265 | (when (and (window-live-p debugger-window) |
| 221 | (save-excursion | 266 | (eq (window-buffer debugger-window) debugger-buffer)) |
| 222 | (recursive-edit))))) | 267 | ;; Unshow debugger-buffer. |
| 223 | ;; Kill or at least neuter the backtrace buffer, so that users | 268 | (quit-restore-window debugger-window debugger-bury-or-kill)) |
| 224 | ;; don't try to execute debugger commands in an invalid context. | 269 | ;; Restore previous state of debugger-buffer in case we were |
| 225 | (if (get-buffer-window debugger-buffer 0) | 270 | ;; in a recursive invocation of the debugger, otherwise just |
| 226 | ;; Still visible despite the save-window-excursion? Maybe it | 271 | ;; erase the buffer and put it into fundamental mode. |
| 227 | ;; it's in a pop-up frame. It would be annoying to delete and | 272 | (when (buffer-live-p debugger-buffer) |
| 228 | ;; recreate it every time the debugger stops, so instead we'll | 273 | (with-current-buffer debugger-buffer |
| 229 | ;; erase it (and maybe hide it) but keep it alive. | 274 | (let ((inhibit-read-only t)) |
| 230 | (with-current-buffer debugger-buffer | 275 | (erase-buffer) |
| 231 | (with-selected-window (get-buffer-window debugger-buffer 0) | 276 | (if (null debugger-previous-state) |
| 232 | (when (and (window-dedicated-p (selected-window)) | 277 | (fundamental-mode) |
| 233 | (not debugger-will-be-back)) | 278 | (insert (nth 1 debugger-previous-state)) |
| 234 | ;; If the window is not dedicated, burying the buffer | 279 | (funcall (nth 0 debugger-previous-state)))))) |
| 235 | ;; will mean that the frame created for it is left | ||
| 236 | ;; around showing some random buffer, and next time we | ||
| 237 | ;; pop to the debugger buffer we'll create yet | ||
| 238 | ;; another frame. | ||
| 239 | ;; If debugger-will-be-back is non-nil, the frame | ||
| 240 | ;; would need to be de-iconified anyway immediately | ||
| 241 | ;; after when we re-enter the debugger, so iconifying it | ||
| 242 | ;; here would cause flashing. | ||
| 243 | ;; Drew Adams is not happy with this: he wants to frame | ||
| 244 | ;; to be left at the top-level, still working on how | ||
| 245 | ;; best to do that. | ||
| 246 | (bury-buffer)))) | ||
| 247 | (unless debugger-previous-state | ||
| 248 | (kill-buffer debugger-buffer))) | ||
| 249 | ;; Restore the previous state of the debugger-buffer, in case we were | ||
| 250 | ;; in a recursive invocation of the debugger. | ||
| 251 | (when (buffer-live-p debugger-buffer) | ||
| 252 | (with-current-buffer debugger-buffer | ||
| 253 | (let ((inhibit-read-only t)) | ||
| 254 | (erase-buffer) | ||
| 255 | (if (null debugger-previous-state) | ||
| 256 | (fundamental-mode) | ||
| 257 | (insert (nth 1 debugger-previous-state)) | ||
| 258 | (funcall (nth 0 debugger-previous-state)))))) | ||
| 259 | (with-timeout-unsuspend debugger-with-timeout-suspend) | 280 | (with-timeout-unsuspend debugger-with-timeout-suspend) |
| 260 | (set-match-data debugger-outer-match-data))) | 281 | (set-match-data debugger-outer-match-data))) |
| 261 | ;; Put into effect the modified values of these variables | 282 | ;; Put into effect the modified values of these variables |
diff --git a/lisp/window.el b/lisp/window.el index 0e03268029c..b071a8e9c50 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -5521,6 +5521,62 @@ the selected one." | |||
| 5521 | (window--display-buffer | 5521 | (window--display-buffer |
| 5522 | buffer window 'reuse display-buffer-mark-dedicated))))) | 5522 | buffer window 'reuse display-buffer-mark-dedicated))))) |
| 5523 | 5523 | ||
| 5524 | (defun display-buffer-in-previous-window (buffer alist) | ||
| 5525 | "Display BUFFER in a window previously showing it. | ||
| 5526 | If ALIST has a non-nil `inhibit-same-window' entry, the selected | ||
| 5527 | window is not eligible for reuse. | ||
| 5528 | |||
| 5529 | If ALIST contains a `reusable-frames' entry, its value determines | ||
| 5530 | which frames to search for a reusable window: | ||
| 5531 | nil -- the selected frame (actually the last non-minibuffer frame) | ||
| 5532 | A frame -- just that frame | ||
| 5533 | `visible' -- all visible frames | ||
| 5534 | 0 -- all frames on the current terminal | ||
| 5535 | t -- all frames. | ||
| 5536 | |||
| 5537 | If ALIST contains no `reusable-frames' entry, search just the | ||
| 5538 | selected frame if `display-buffer-reuse-frames' and | ||
| 5539 | `pop-up-frames' are both nil; search all frames on the current | ||
| 5540 | terminal if either of those variables is non-nil. | ||
| 5541 | |||
| 5542 | If ALIST has a `previous-window' entry, the window specified by | ||
| 5543 | that entry will override any other window found by the methods | ||
| 5544 | above, even if that window never showed BUFFER before." | ||
| 5545 | (let* ((alist-entry (assq 'reusable-frames alist)) | ||
| 5546 | (inhibit-same-window | ||
| 5547 | (cdr (assq 'inhibit-same-window alist))) | ||
| 5548 | (frames (cond | ||
| 5549 | (alist-entry (cdr alist-entry)) | ||
| 5550 | ((if (eq pop-up-frames 'graphic-only) | ||
| 5551 | (display-graphic-p) | ||
| 5552 | pop-up-frames) | ||
| 5553 | 0) | ||
| 5554 | (display-buffer-reuse-frames 0) | ||
| 5555 | (t (last-nonminibuffer-frame)))) | ||
| 5556 | entry best-window second-best-window window) | ||
| 5557 | ;; Scan windows whether they have shown the buffer recently. | ||
| 5558 | (catch 'best | ||
| 5559 | (dolist (window (window-list-1 (frame-first-window) 'nomini frames)) | ||
| 5560 | (when (and (assq buffer (window-prev-buffers window)) | ||
| 5561 | (not (window-dedicated-p window))) | ||
| 5562 | (if (eq window (selected-window)) | ||
| 5563 | (unless inhibit-same-window | ||
| 5564 | (setq second-best-window window)) | ||
| 5565 | (setq best-window window) | ||
| 5566 | (throw 'best t))))) | ||
| 5567 | ;; When ALIST has a `previous-window' entry, that entry may override | ||
| 5568 | ;; anything we found so far. | ||
| 5569 | (when (and (setq window (cdr (assq 'previous-window alist))) | ||
| 5570 | (window-live-p window) | ||
| 5571 | (not (window-dedicated-p window))) | ||
| 5572 | (if (eq window (selected-window)) | ||
| 5573 | (unless inhibit-same-window | ||
| 5574 | (setq second-best-window window)) | ||
| 5575 | (setq best-window window))) | ||
| 5576 | ;; Return best or second best window found. | ||
| 5577 | (when (setq window (or best-window second-best-window)) | ||
| 5578 | (window--display-buffer buffer window 'reuse)))) | ||
| 5579 | |||
| 5524 | (defun display-buffer-use-some-window (buffer alist) | 5580 | (defun display-buffer-use-some-window (buffer alist) |
| 5525 | "Display BUFFER in an existing window. | 5581 | "Display BUFFER in an existing window. |
| 5526 | Search for a usable window, set that window to the buffer, and | 5582 | Search for a usable window, set that window to the buffer, and |