aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2012-09-08 15:28:11 +0200
committerMartin Rudalics2012-09-08 15:28:11 +0200
commitfa2bcf435d9774c0e8542ba36b11ef4722f9675c (patch)
treeae13b3c6076ec4c063e4ebaa5b093a2f56dc8a55
parentaa7d57c5079024458c5e25cd5f304d1b967bcbe6 (diff)
downloademacs-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/NEWS25
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/emacs-lisp/debug.el163
-rw-r--r--lisp/window.el56
4 files changed, 174 insertions, 80 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 55b8388ca27..7a9c9a21c97 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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
654now accept a third argument to avoid choosing the selected window. 656now 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,
669tells display action functions to avoid changing which frame is
670selected.
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
666display action functions to avoid changing which frame is selected. 673non-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,
669specifies frame parameters to give any newly-created frame. 676specifies 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
672appropriate entries in the `display-buffer-alist' function introduced 679appropriate 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 @@
12012-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
12012-09-07 Stefan Monnier <monnier@iro.umontreal.ca> 112012-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'.
53The value used here affects the behavior of operations on any
54window 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
75The 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).
65This is to optimize `debugger-make-xrefs'.") 101This 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.
5526If ALIST has a non-nil `inhibit-same-window' entry, the selected
5527window is not eligible for reuse.
5528
5529If ALIST contains a `reusable-frames' entry, its value determines
5530which 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
5537If ALIST contains no `reusable-frames' entry, search just the
5538selected frame if `display-buffer-reuse-frames' and
5539`pop-up-frames' are both nil; search all frames on the current
5540terminal if either of those variables is non-nil.
5541
5542If ALIST has a `previous-window' entry, the window specified by
5543that entry will override any other window found by the methods
5544above, 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.
5526Search for a usable window, set that window to the buffer, and 5582Search for a usable window, set that window to the buffer, and