emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r109843: Rewrite switch-to-prev-/next


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r109843: Rewrite switch-to-prev-/next-buffer and quit-window; add display-buffer-below-selected.
Date: Sat, 01 Sep 2012 18:47:09 +0200
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 109843
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Sat 2012-09-01 18:47:09 +0200
message:
  Rewrite switch-to-prev-/next-buffer and quit-window; add 
display-buffer-below-selected.
  
  * window.el (switch-to-prev-buffer): Handle additional values of
  BURY-OR-KILL argument.  Don't switch in minibuffer window.
  (switch-to-next-buffer): Don't switch in minibuffer window.
  (quit-restore-window): New function based on quit-window.
  Handle additional values of former KILL argument.
  (quit-window): Call quit-restore-window with appropriate
  interpretation of KILL argument.
  (display-buffer-below-selected): New buffer display action
  function.
modified:
  lisp/ChangeLog
  lisp/window.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-09-01 04:28:24 +0000
+++ b/lisp/ChangeLog    2012-09-01 16:47:09 +0000
@@ -1,3 +1,15 @@
+2012-09-01  Martin Rudalics  <address@hidden>
+
+       * window.el (switch-to-prev-buffer): Handle additional values of
+       BURY-OR-KILL argument.  Don't switch in minibuffer window.
+       (switch-to-next-buffer): Don't switch in minibuffer window.
+       (quit-restore-window): New function based on quit-window.
+       Handle additional values of former KILL argument.
+       (quit-window): Call quit-restore-window with appropriate
+       interpretation of KILL argument.
+       (display-buffer-below-selected): New buffer display action
+       function.
+
 2012-09-01  Stefan Monnier  <address@hidden>
 
        * minibuffer.el (completion-at-point-functions): Complete docstring

=== modified file 'lisp/window.el'
--- a/lisp/window.el    2012-08-31 16:51:49 +0000
+++ b/lisp/window.el    2012-09-01 16:47:09 +0000
@@ -2972,7 +2972,12 @@
 
 Optional argument BURY-OR-KILL non-nil means the buffer currently
 shown in WINDOW is about to be buried or killed and consequently
-shall not be switched to in future invocations of this command."
+shall not be switched to in future invocations of this command.
+
+As a special case, if BURY-OR-KILL equals `append', this means to
+move the buffer to the end of WINDOW's previous buffers list so a
+future invocation of `switch-to-prev-buffer' less likely switches
+to it."
   (interactive)
   (let* ((window (window-normalize-window window t))
         (frame (window-frame window))
@@ -2980,26 +2985,34 @@
         ;; Save this since it's destroyed by `set-window-buffer'.
         (next-buffers (window-next-buffers window))
          (pred (frame-parameter frame 'buffer-predicate))
-        entry buffer new-buffer killed-buffers visible)
+        entry new-buffer killed-buffers visible)
+    (when (window-minibuffer-p window)
+      ;; Don't switch in minibuffer window.
+      (unless (setq window (minibuffer-selected-window))
+       (error "Window %s is a minibuffer window" window)))
+
     (when (window-dedicated-p window)
+      ;; Don't switch in dedicated window.
       (error "Window %s is dedicated to buffer %s" window old-buffer))
 
     (catch 'found
       ;; Scan WINDOW's previous buffers first, skipping entries of next
       ;; buffers.
       (dolist (entry (window-prev-buffers window))
-       (when (and (setq buffer (car entry))
-                  (or (buffer-live-p buffer)
+       (when (and (setq new-buffer (car entry))
+                  (or (buffer-live-p new-buffer)
                       (not (setq killed-buffers
-                                 (cons buffer killed-buffers))))
-                   (or (null pred) (funcall pred buffer))
-                  (not (eq buffer old-buffer))
-                   (or bury-or-kill (not (memq buffer next-buffers))))
+                                 (cons new-buffer killed-buffers))))
+                  (not (eq new-buffer old-buffer))
+                   (or (null pred) (funcall pred new-buffer))
+                  ;; When BURY-OR-KILL is nil, avoid switching to a
+                  ;; buffer in WINDOW's next buffers list.
+                  (or bury-or-kill (not (memq new-buffer next-buffers))))
          (if (and (not switch-to-visible-buffer)
-                  (get-buffer-window buffer frame))
-             ;; Try to avoid showing a buffer visible in some other window.
-             (setq visible buffer)
-           (setq new-buffer buffer)
+                  (get-buffer-window new-buffer frame))
+             ;; Try to avoid showing a buffer visible in some other
+             ;; window.
+             (setq visible new-buffer)
            (set-window-buffer-start-and-point
             window new-buffer (nth 1 entry) (nth 2 entry))
            (throw 'found t))))
@@ -3014,8 +3027,8 @@
                        (nreverse (buffer-list frame))))
        (when (and (buffer-live-p buffer)
                   (not (eq buffer old-buffer))
+                   (or (null pred) (funcall pred buffer))
                   (not (eq (aref (buffer-name buffer) 0) ?\s))
-                   (or (null pred) (funcall pred buffer))
                   (or bury-or-kill (not (memq buffer next-buffers))))
          (if (get-buffer-window buffer frame)
              ;; Try to avoid showing a buffer visible in some other window.
@@ -3047,12 +3060,20 @@
        (set-window-buffer-start-and-point window new-buffer)))
 
     (if bury-or-kill
-       ;; Remove `old-buffer' from WINDOW's previous and (restored list
-       ;; of) next buffers.
-       (progn
+       (let ((entry (and (eq bury-or-kill 'append)
+                         (assq old-buffer (window-prev-buffers window)))))
+         ;; Remove `old-buffer' from WINDOW's previous and (restored list
+         ;; of) next buffers.
          (set-window-prev-buffers
           window (assq-delete-all old-buffer (window-prev-buffers window)))
-         (set-window-next-buffers window (delq old-buffer next-buffers)))
+         (set-window-next-buffers window (delq old-buffer next-buffers))
+         (when entry
+           ;; Append old-buffer's entry to list of WINDOW's previous
+           ;; buffers so it's less likely to get switched to soon but
+           ;; `display-buffer-in-previous-window' can nevertheless find
+           ;; it.
+           (set-window-prev-buffers
+            window (append (window-prev-buffers window) (list entry)))))
       ;; Move `old-buffer' to head of WINDOW's restored list of next
       ;; buffers.
       (set-window-next-buffers
@@ -3080,8 +3101,14 @@
         (old-buffer (window-buffer window))
         (next-buffers (window-next-buffers window))
          (pred (frame-parameter frame 'buffer-predicate))
-        buffer new-buffer entry killed-buffers visible)
+        new-buffer entry killed-buffers visible)
+    (when (window-minibuffer-p window)
+      ;; Don't switch in minibuffer window.
+      (unless (setq window (minibuffer-selected-window))
+       (error "Window %s is a minibuffer window" window)))
+
     (when (window-dedicated-p window)
+      ;; Don't switch in dedicated window.
       (error "Window %s is dedicated to buffer %s" window old-buffer))
 
     (catch 'found
@@ -3100,9 +3127,10 @@
       ;; Scan the buffer list of WINDOW's frame next, skipping previous
       ;; buffers entries.
       (dolist (buffer (buffer-list frame))
-       (when (and (buffer-live-p buffer) (not (eq buffer old-buffer))
+       (when (and (buffer-live-p buffer)
+                  (not (eq buffer old-buffer))
+                   (or (null pred) (funcall pred buffer))
                   (not (eq (aref (buffer-name buffer) 0) ?\s))
-                   (or (null pred) (funcall pred buffer))
                   (not (assq buffer (window-prev-buffers window))))
          (if (get-buffer-window buffer frame)
              ;; Try to avoid showing a buffer visible in some other window.
@@ -3113,18 +3141,17 @@
       ;; Scan WINDOW's reverted previous buffers last (must not use
       ;; nreverse here!)
       (dolist (entry (reverse (window-prev-buffers window)))
-       (when (and (setq buffer (car entry))
-                  (or (buffer-live-p buffer)
+       (when (and (setq new-buffer (car entry))
+                  (or (buffer-live-p new-buffer)
                       (not (setq killed-buffers
-                                 (cons buffer killed-buffers))))
-                   (or (null pred) (funcall pred buffer))
-                  (not (eq buffer old-buffer)))
+                                 (cons new-buffer killed-buffers))))
+                  (not (eq new-buffer old-buffer))
+                   (or (null pred) (funcall pred new-buffer)))
          (if (and (not switch-to-visible-buffer)
-                  (get-buffer-window buffer frame))
+                  (get-buffer-window new-buffer frame))
              ;; Try to avoid showing a buffer visible in some other window.
              (unless visible
-               (setq visible buffer))
-           (setq new-buffer buffer)
+               (setq visible new-buffer))
            (set-window-buffer-start-and-point
             window new-buffer (nth 1 entry) (nth 2 entry))
            (throw 'found t))))
@@ -3351,18 +3378,35 @@
        ;; Unrecord BUFFER in WINDOW.
        (unrecord-window-buffer window buffer)))))
 
-(defun quit-window (&optional kill window)
-  "Quit WINDOW and bury its buffer.
+(defun quit-restore-window (&optional window bury-or-kill)
+  "Quit WINDOW and deal with its buffer.
 WINDOW must be a live window and defaults to the selected one.
-With prefix argument KILL non-nil, kill the buffer instead of
-burying it.
 
 According to information stored in WINDOW's `quit-restore' window
 parameter either (1) delete WINDOW and its frame, (2) delete
 WINDOW, (3) restore the buffer previously displayed in WINDOW,
 or (4) make WINDOW display some other buffer than the present
-one.  If non-nil, reset `quit-restore' parameter to nil."
-  (interactive "P")
+one.  If non-nil, reset `quit-restore' parameter to nil.
+
+Optional second argument BURY-OR-KILL tells how to proceed with
+the buffer of WINDOW.  The following values are handled:
+
+`nil' means to not handle the buffer in a particular way.  This
+  means that if WINDOW is not deleted by this function, invoking
+  `switch-to-prev-buffer' will usually show the buffer again.
+
+`append' means that if WINDOW is not deleted, move its buffer to
+  the end of WINDOW's previous buffers so it's less likely that a
+  future invocation of `switch-to-prev-buffer' will switch to it.
+  Also, move the buffer to the end of the frame's buffer list.
+
+`bury' means that if WINDOW is not deleted, remove its buffer
+  from WINDOW'S list of previous buffers.  Also, move 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 this buffer again without killing the buffer.
+
+`kill' means to kill WINDOW's buffer."
   (setq window (window-normalize-window window t))
   (let* ((buffer (window-buffer window))
         (quit-restore (window-parameter window 'quit-restore))
@@ -3374,13 +3418,13 @@
                          (not (eq (setq prev-buffer (cadr prev-buffers))
                                   buffer))))
                 prev-buffer)))
-        quad resize)
+        quad entry)
     (cond
      ((and (not prev-buffer)
           (memq (nth 1 quit-restore) '(window frame))
           (eq (nth 3 quit-restore) buffer)
           ;; Delete WINDOW if possible.
-          (window--delete window nil kill))
+          (window--delete window nil (eq bury-or-kill 'kill)))
       ;; If the previously selected window is still alive, select it.
       (when (window-live-p (nth 2 quit-restore))
        (select-window (nth 2 quit-restore))))
@@ -3388,21 +3432,32 @@
           (buffer-live-p (car quad))
           (eq (nth 3 quit-restore) buffer))
       ;; Show another buffer stored in quit-restore parameter.
-      (setq resize (and (integerp (nth 3 quad))
-                        (/= (nth 3 quad) (window-total-size window))))
-      (set-window-dedicated-p window nil)
-      (when resize
+      (when (and (integerp (nth 3 quad))
+                (/= (nth 3 quad) (window-total-size window)))
        ;; Try to resize WINDOW to its old height but don't signal an
        ;; error.
        (condition-case nil
            (window-resize window (- (nth 3 quad) (window-total-size window)))
          (error nil)))
+      (set-window-dedicated-p window nil)
       ;; Restore WINDOW's previous buffer, start and point position.
       (set-window-buffer-start-and-point
        window (nth 0 quad) (nth 1 quad) (nth 2 quad))
-      ;; Unrecord WINDOW's buffer here (Bug#9937) to make sure it's not
-      ;; re-recorded by `set-window-buffer'.
-      (unrecord-window-buffer window buffer)
+      ;; Deal with the buffer we just removed from WINDOW.
+      (setq entry (and (eq bury-or-kill 'append)
+                      (assq buffer (window-prev-buffers window))))
+      (when bury-or-kill
+       ;; Remove buffer from WINDOW's previous and next buffers.
+       (set-window-prev-buffers
+        window (assq-delete-all buffer (window-prev-buffers window)))
+       (set-window-next-buffers
+        window (delq buffer (window-next-buffers window))))
+      (when entry
+       ;; Append old buffer's entry to list of WINDOW's previous
+       ;; buffers so it's less likely to get switched to soon but
+       ;; `display-buffer-in-previous-window' can nevertheless find it.
+       (set-window-prev-buffers
+        window (append (window-prev-buffers window) (list entry))))
       ;; Reset the quit-restore parameter.
       (set-window-parameter window 'quit-restore nil)
       ;; Select old window.
@@ -3414,12 +3469,29 @@
       (set-window-parameter window 'quit-restore nil)
       ;; Make sure that WINDOW is no more dedicated.
       (set-window-dedicated-p window nil)
-      (switch-to-prev-buffer window 'bury-or-kill)))
-
-    ;; Kill WINDOW's old-buffer if requested
-    (if kill
-       (kill-buffer buffer)
-      (bury-buffer-internal buffer))))
+      (switch-to-prev-buffer window bury-or-kill)))
+
+    ;; Deal with the buffer.
+    (cond
+     ((not (buffer-live-p buffer)))
+     ((eq bury-or-kill 'kill)
+      (kill-buffer buffer))
+     (bury-or-kill
+      (bury-buffer-internal buffer)))))
+
+(defun quit-window (&optional kill window)
+  "Quit WINDOW and bury its buffer.
+WINDOW must be a live window and defaults to the selected one.
+With prefix argument KILL non-nil, kill the buffer instead of
+burying it.
+
+According to information stored in WINDOW's `quit-restore' window
+parameter either (1) delete WINDOW and its frame, (2) delete
+WINDOW, (3) restore the buffer previously displayed in WINDOW,
+or (4) make WINDOW display some other buffer than the present
+one.  If non-nil, reset `quit-restore' parameter to nil."
+  (interactive "P")
+  (quit-restore-window window (if kill 'kill 'bury)))
 
 (defun quit-windows-on (&optional buffer-or-name kill frame)
   "Quit all windows showing BUFFER-OR-NAME.
@@ -5330,6 +5402,20 @@
       (and pop-up-windows
           (display-buffer-pop-up-window buffer alist))))
 
+(defun display-buffer-below-selected (buffer _alist)
+  "Try displaying BUFFER in a window below the selected window.
+This either splits the selected window or reuses the window below
+the selected one."
+  (let (window)
+    (or (and (not (frame-parameter nil 'unsplittable))
+            (setq window (window--try-to-split-window (selected-window)))
+            (window--display-buffer
+             buffer window 'window display-buffer-mark-dedicated))
+       (and (setq window (window-in-direction 'below))
+            (not (window-dedicated-p window))
+            (window--display-buffer
+             buffer window 'reuse display-buffer-mark-dedicated)))))
+
 (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]