emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r109937: Fix handling of debugger win


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109937: Fix handling of debugger window. (Bug#8789)
Date: Sat, 08 Sep 2012 15:28:11 +0200
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109937
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Sat 2012-09-08 15:28:11 +0200
message:
  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)
modified:
  etc/NEWS
  lisp/ChangeLog
  lisp/emacs-lisp/debug.el
  lisp/window.el
=== modified file 'etc/NEWS'
--- a/etc/NEWS  2012-09-07 10:27:11 +0000
+++ b/etc/NEWS  2012-09-08 13:28:11 +0000
@@ -645,6 +645,8 @@
 
 ** New error type and new function `user-error'.  Doesn't trigger the debugger.
 
+** New option `debugger-bury-or-kill'.
+
 +++
 ** New utility function `buffer-narrowed-p'.
 
@@ -653,20 +655,25 @@
 *** The functions get-lru-window, get-mru-window and get-largest-window
 now accept a third argument to avoid choosing the selected window.
 
-*** New macro with-temp-buffer-window.
-
-*** New option temp-buffer-resize-frames.
-
-*** New function fit-frame-to-buffer and new option
-    fit-frame-to-buffer-bottom-margin.
-
-*** New display action function display-buffer-below-selected.
-
-*** New display action alist `inhibit-switch-frame', if non-nil, tells
-display action functions to avoid changing which frame is selected.
-
-*** New display action alist `pop-up-frame-parameters', if non-nil,
-specifies frame parameters to give any newly-created frame.
+*** New macro `with-temp-buffer-window'.
+
+*** New option `temp-buffer-resize-frames'.
+
+*** New function `fit-frame-to-buffer' and new option
+    `fit-frame-to-buffer-bottom-margin'.
+
+*** New display action functions `display-buffer-below-selected' and
+`display-buffer-in-previous-window'.
+
+*** New display action alist entry `inhibit-switch-frame', if non-nil,
+tells display action functions to avoid changing which frame is
+selected.
+
+*** New display action alist entry `pop-up-frame-parameters', if
+non-nil, specifies frame parameters to give any newly-created frame.
+
+*** New display action alist entry `previous-window', if non-nil,
+specifies window to reuse in `display-buffer-in-previous-window'.
 
 *** The following variables are obsolete, as they can be replaced by
 appropriate entries in the `display-buffer-alist' function introduced

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-09-07 20:14:55 +0000
+++ b/lisp/ChangeLog    2012-09-08 13:28:11 +0000
@@ -1,3 +1,13 @@
+2012-09-08  Martin Rudalics  <address@hidden>
+
+       * 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)
+
 2012-09-07  Stefan Monnier  <address@hidden>
 
        * emacs-lisp/byte-run.el (defun): Tweak message.  Simplify code.

=== modified file 'lisp/emacs-lisp/debug.el'
--- a/lisp/emacs-lisp/debug.el  2012-07-26 01:27:33 +0000
+++ b/lisp/emacs-lisp/debug.el  2012-09-08 13:28:11 +0000
@@ -48,6 +48,39 @@
   :group 'debugger
   :version "21.1")
 
+(defcustom debugger-bury-or-kill 'bury
+  "How to proceed with the debugger buffer when exiting `debug'.
+The value used here affects the behavior of operations on any
+window previously showing the debugger buffer.
+
+`nil' means that if its window is not deleted when exiting the
+  debugger, invoking `switch-to-prev-buffer' will usually show
+  the debugger buffer again.
+
+`append' means that if the window is not deleted, the debugger
+  buffer moves to the end of the window's previous buffers so
+  it's less likely that a future invocation of
+  `switch-to-prev-buffer' will switch to it.  Also, it moves the
+  buffer to the end of the frame's buffer list.
+
+`bury' means that if the window is not deleted, its buffer is
+  removed from the window's list of previous buffers.  Also, it
+  moves the buffer to the end of the frame's buffer list.  This
+  value provides the most reliable remedy to not have
+  `switch-to-prev-buffer' switch to the debugger buffer again
+  without killing the buffer.
+
+`kill' means to kill the debugger buffer.
+
+The value used here is passed to `quit-restore-window'."
+  :type '(choice
+         (const :tag "Keep alive" nil)
+         (const :tag "Append" 'append)
+         (const :tag "Bury" 'bury)
+         (const :tag "Kill" 'kill))
+  :group 'debugger
+  :version "24.2")
+
 (defvar debug-function-list nil
   "List of functions currently set for debug on entry.")
 
@@ -60,6 +93,9 @@
 (defvar debugger-old-buffer nil
   "This is the buffer that was current when the debugger was entered.")
 
+(defvar debugger-previous-window nil
+  "This is the window last showing the debugger buffer.")
+
 (defvar debugger-previous-backtrace nil
   "The contents of the previous backtrace (including text properties).
 This is to optimize `debugger-make-xrefs'.")
@@ -133,7 +169,7 @@
                (with-current-buffer (get-buffer "*Backtrace*")
                  (list major-mode (buffer-string)))))
          (debugger-buffer (get-buffer-create "*Backtrace*"))
-         (debugger-old-buffer (current-buffer))
+         (debugger-window nil)
          (debugger-step-after-exit nil)
           (debugger-will-be-back nil)
          ;; Don't keep reading from an executing kbd macro!
@@ -184,78 +220,63 @@
            (cursor-in-echo-area nil))
        (unwind-protect
            (save-excursion
-             (save-window-excursion
-               (with-no-warnings
-                 (setq unread-command-char -1))
-               (when (eq (car debugger-args) 'debug)
-                 ;; Skip the frames for backtrace-debug, byte-code,
-                 ;; and implement-debug-on-entry.
-                 (backtrace-debug 4 t)
-                 ;; Place an extra debug-on-exit for macro's.
-                 (when (eq 'lambda (car-safe (cadr (backtrace-frame 4))))
-                   (backtrace-debug 5 t)))
-                (pop-to-buffer debugger-buffer)
-               (debugger-mode)
-               (debugger-setup-buffer debugger-args)
-               (when noninteractive
-                 ;; If the backtrace is long, save the beginning
-                 ;; and the end, but discard the middle.
-                 (when (> (count-lines (point-min) (point-max))
-                          debugger-batch-max-lines)
-                   (goto-char (point-min))
-                   (forward-line (/ 2 debugger-batch-max-lines))
-                   (let ((middlestart (point)))
-                     (goto-char (point-max))
-                     (forward-line (- (/ 2 debugger-batch-max-lines)
-                                      debugger-batch-max-lines))
-                     (delete-region middlestart (point)))
-                   (insert "...\n"))
+             (with-no-warnings
+               (setq unread-command-char -1))
+             (when (eq (car debugger-args) 'debug)
+               ;; Skip the frames for backtrace-debug, byte-code,
+               ;; and implement-debug-on-entry.
+               (backtrace-debug 4 t)
+               ;; Place an extra debug-on-exit for macro's.
+               (when (eq 'lambda (car-safe (cadr (backtrace-frame 4))))
+                 (backtrace-debug 5 t)))
+             (pop-to-buffer
+              debugger-buffer
+              `((display-buffer-reuse-window
+                 display-buffer-in-previous-window)
+                 . (,(when debugger-previous-window
+                       `(previous-window . ,debugger-previous-window)))))
+             (setq debugger-window (selected-window))
+             (setq debugger-previous-window debugger-window)
+             (debugger-mode)
+             (debugger-setup-buffer debugger-args)
+             (when noninteractive
+               ;; If the backtrace is long, save the beginning
+               ;; and the end, but discard the middle.
+               (when (> (count-lines (point-min) (point-max))
+                        debugger-batch-max-lines)
                  (goto-char (point-min))
-                 (message "%s" (buffer-string))
-                 (kill-emacs -1))
+                 (forward-line (/ 2 debugger-batch-max-lines))
+                 (let ((middlestart (point)))
+                   (goto-char (point-max))
+                   (forward-line (- (/ 2 debugger-batch-max-lines)
+                                    debugger-batch-max-lines))
+                   (delete-region middlestart (point)))
+                 (insert "...\n"))
+               (goto-char (point-min))
+               (message "%s" (buffer-string))
+               (kill-emacs -1))
+             (message "")
+             (let ((standard-output nil)
+                   (buffer-read-only t))
                (message "")
-               (let ((standard-output nil)
-                     (buffer-read-only t))
-                 (message "")
-                 ;; Make sure we unbind buffer-read-only in the right buffer.
-                 (save-excursion
-                   (recursive-edit)))))
-         ;; Kill or at least neuter the backtrace buffer, so that users
-         ;; don't try to execute debugger commands in an invalid context.
-         (if (get-buffer-window debugger-buffer 0)
-             ;; Still visible despite the save-window-excursion?  Maybe it
-             ;; it's in a pop-up frame.  It would be annoying to delete and
-             ;; recreate it every time the debugger stops, so instead we'll
-             ;; erase it (and maybe hide it) but keep it alive.
-             (with-current-buffer debugger-buffer
-               (with-selected-window (get-buffer-window debugger-buffer 0)
-                  (when (and (window-dedicated-p (selected-window))
-                             (not debugger-will-be-back))
-                    ;; If the window is not dedicated, burying the buffer
-                    ;; will mean that the frame created for it is left
-                    ;; around showing some random buffer, and next time we
-                    ;; pop to the debugger buffer we'll create yet
-                    ;; another frame.
-                    ;; If debugger-will-be-back is non-nil, the frame
-                    ;; would need to be de-iconified anyway immediately
-                    ;; after when we re-enter the debugger, so iconifying it
-                    ;; here would cause flashing.
-                    ;; Drew Adams is not happy with this: he wants to frame
-                    ;; to be left at the top-level, still working on how
-                    ;; best to do that.
-                    (bury-buffer))))
-            (unless debugger-previous-state
-              (kill-buffer debugger-buffer)))
-          ;; Restore the previous state of the debugger-buffer, in case we were
-          ;; in a recursive invocation of the debugger.
-          (when (buffer-live-p debugger-buffer)
-            (with-current-buffer debugger-buffer
-              (let ((inhibit-read-only t))
-                (erase-buffer)
-                (if (null debugger-previous-state)
-                    (fundamental-mode)
-                  (insert (nth 1 debugger-previous-state))
-                  (funcall (nth 0 debugger-previous-state))))))
+               ;; Make sure we unbind buffer-read-only in the right buffer.
+               (save-excursion
+                 (recursive-edit))))
+         (when (and (window-live-p debugger-window)
+                    (eq (window-buffer debugger-window) debugger-buffer))
+           ;; Unshow debugger-buffer.
+           (quit-restore-window debugger-window debugger-bury-or-kill))
+          ;; Restore previous state of debugger-buffer in case we were
+          ;; in a recursive invocation of the debugger, otherwise just
+          ;; erase the buffer and put it into fundamental mode.
+         (when (buffer-live-p debugger-buffer)
+           (with-current-buffer debugger-buffer
+             (let ((inhibit-read-only t))
+               (erase-buffer)
+               (if (null debugger-previous-state)
+                   (fundamental-mode)
+                 (insert (nth 1 debugger-previous-state))
+                 (funcall (nth 0 debugger-previous-state))))))
          (with-timeout-unsuspend debugger-with-timeout-suspend)
          (set-match-data debugger-outer-match-data)))
       ;; Put into effect the modified values of these variables

=== modified file 'lisp/window.el'
--- a/lisp/window.el    2012-09-07 13:53:21 +0000
+++ b/lisp/window.el    2012-09-08 13:28:11 +0000
@@ -5521,6 +5521,62 @@
             (window--display-buffer
              buffer window 'reuse display-buffer-mark-dedicated)))))
 
+(defun display-buffer-in-previous-window (buffer alist)
+  "Display BUFFER in a window previously showing it.
+If ALIST has a non-nil `inhibit-same-window' entry, the selected
+window is not eligible for reuse.
+
+If ALIST contains a `reusable-frames' entry, its value determines
+which frames to search for a reusable window:
+  nil -- the selected frame (actually the last non-minibuffer frame)
+  A frame   -- just that frame
+  `visible' -- all visible frames
+  0   -- all frames on the current terminal
+  t   -- all frames.
+
+If ALIST contains no `reusable-frames' entry, search just the
+selected frame if `display-buffer-reuse-frames' and
+`pop-up-frames' are both nil; search all frames on the current
+terminal if either of those variables is non-nil.
+
+If ALIST has a `previous-window' entry, the window specified by
+that entry will override any other window found by the methods
+above, even if that window never showed BUFFER before."
+  (let* ((alist-entry (assq 'reusable-frames alist))
+        (inhibit-same-window
+         (cdr (assq 'inhibit-same-window alist)))
+        (frames (cond
+                 (alist-entry (cdr alist-entry))
+                 ((if (eq pop-up-frames 'graphic-only)
+                      (display-graphic-p)
+                    pop-up-frames)
+                  0)
+                 (display-buffer-reuse-frames 0)
+                 (t (last-nonminibuffer-frame))))
+        entry best-window second-best-window window)
+    ;; Scan windows whether they have shown the buffer recently.
+    (catch 'best
+      (dolist (window (window-list-1 (frame-first-window) 'nomini frames))
+       (when (and (assq buffer (window-prev-buffers window))
+                  (not (window-dedicated-p window)))
+         (if (eq window (selected-window))
+             (unless inhibit-same-window
+               (setq second-best-window window))
+           (setq best-window window)
+           (throw 'best t)))))
+    ;; When ALIST has a `previous-window' entry, that entry may override
+    ;; anything we found so far.
+    (when (and (setq window (cdr (assq 'previous-window alist)))
+              (window-live-p window)
+              (not (window-dedicated-p window)))
+      (if (eq window (selected-window))
+         (unless inhibit-same-window
+           (setq second-best-window window))
+       (setq best-window window)))
+    ;; Return best or second best window found.
+    (when (setq window (or best-window second-best-window))
+      (window--display-buffer buffer window 'reuse))))
+
 (defun display-buffer-use-some-window (buffer alist)
   "Display BUFFER in an existing window.
 Search for a usable window, set that window to the buffer, and


reply via email to

[Prev in Thread] Current Thread [Next in Thread]