aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2012-09-01 18:47:09 +0200
committerMartin Rudalics2012-09-01 18:47:09 +0200
commit78dd6ab19818ddbd6995e58b6eccd3e19899aba1 (patch)
tree9bb7a705ee65d9c0b32ca90e5b8ec3bd0edbc437
parent7e510e2844732d53563abd45ec60df7de2129246 (diff)
downloademacs-78dd6ab19818ddbd6995e58b6eccd3e19899aba1.tar.gz
emacs-78dd6ab19818ddbd6995e58b6eccd3e19899aba1.zip
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.
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/window.el182
2 files changed, 146 insertions, 48 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c5b866e9d54..f43a3177af2 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,15 @@
12012-09-01 Martin Rudalics <rudalics@gmx.at>
2
3 * window.el (switch-to-prev-buffer): Handle additional values of
4 BURY-OR-KILL argument. Don't switch in minibuffer window.
5 (switch-to-next-buffer): Don't switch in minibuffer window.
6 (quit-restore-window): New function based on quit-window.
7 Handle additional values of former KILL argument.
8 (quit-window): Call quit-restore-window with appropriate
9 interpretation of KILL argument.
10 (display-buffer-below-selected): New buffer display action
11 function.
12
12012-09-01 Stefan Monnier <monnier@iro.umontreal.ca> 132012-09-01 Stefan Monnier <monnier@iro.umontreal.ca>
2 14
3 * minibuffer.el (completion-at-point-functions): Complete docstring 15 * minibuffer.el (completion-at-point-functions): Complete docstring
diff --git a/lisp/window.el b/lisp/window.el
index c72093334d8..2fce874e987 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2972,7 +2972,12 @@ found.
2972 2972
2973Optional argument BURY-OR-KILL non-nil means the buffer currently 2973Optional argument BURY-OR-KILL non-nil means the buffer currently
2974shown in WINDOW is about to be buried or killed and consequently 2974shown in WINDOW is about to be buried or killed and consequently
2975shall not be switched to in future invocations of this command." 2975shall not be switched to in future invocations of this command.
2976
2977As a special case, if BURY-OR-KILL equals `append', this means to
2978move the buffer to the end of WINDOW's previous buffers list so a
2979future invocation of `switch-to-prev-buffer' less likely switches
2980to it."
2976 (interactive) 2981 (interactive)
2977 (let* ((window (window-normalize-window window t)) 2982 (let* ((window (window-normalize-window window t))
2978 (frame (window-frame window)) 2983 (frame (window-frame window))
@@ -2980,26 +2985,34 @@ shall not be switched to in future invocations of this command."
2980 ;; Save this since it's destroyed by `set-window-buffer'. 2985 ;; Save this since it's destroyed by `set-window-buffer'.
2981 (next-buffers (window-next-buffers window)) 2986 (next-buffers (window-next-buffers window))
2982 (pred (frame-parameter frame 'buffer-predicate)) 2987 (pred (frame-parameter frame 'buffer-predicate))
2983 entry buffer new-buffer killed-buffers visible) 2988 entry new-buffer killed-buffers visible)
2989 (when (window-minibuffer-p window)
2990 ;; Don't switch in minibuffer window.
2991 (unless (setq window (minibuffer-selected-window))
2992 (error "Window %s is a minibuffer window" window)))
2993
2984 (when (window-dedicated-p window) 2994 (when (window-dedicated-p window)
2995 ;; Don't switch in dedicated window.
2985 (error "Window %s is dedicated to buffer %s" window old-buffer)) 2996 (error "Window %s is dedicated to buffer %s" window old-buffer))
2986 2997
2987 (catch 'found 2998 (catch 'found
2988 ;; Scan WINDOW's previous buffers first, skipping entries of next 2999 ;; Scan WINDOW's previous buffers first, skipping entries of next
2989 ;; buffers. 3000 ;; buffers.
2990 (dolist (entry (window-prev-buffers window)) 3001 (dolist (entry (window-prev-buffers window))
2991 (when (and (setq buffer (car entry)) 3002 (when (and (setq new-buffer (car entry))
2992 (or (buffer-live-p buffer) 3003 (or (buffer-live-p new-buffer)
2993 (not (setq killed-buffers 3004 (not (setq killed-buffers
2994 (cons buffer killed-buffers)))) 3005 (cons new-buffer killed-buffers))))
2995 (or (null pred) (funcall pred buffer)) 3006 (not (eq new-buffer old-buffer))
2996 (not (eq buffer old-buffer)) 3007 (or (null pred) (funcall pred new-buffer))
2997 (or bury-or-kill (not (memq buffer next-buffers)))) 3008 ;; When BURY-OR-KILL is nil, avoid switching to a
3009 ;; buffer in WINDOW's next buffers list.
3010 (or bury-or-kill (not (memq new-buffer next-buffers))))
2998 (if (and (not switch-to-visible-buffer) 3011 (if (and (not switch-to-visible-buffer)
2999 (get-buffer-window buffer frame)) 3012 (get-buffer-window new-buffer frame))
3000 ;; Try to avoid showing a buffer visible in some other window. 3013 ;; Try to avoid showing a buffer visible in some other
3001 (setq visible buffer) 3014 ;; window.
3002 (setq new-buffer buffer) 3015 (setq visible new-buffer)
3003 (set-window-buffer-start-and-point 3016 (set-window-buffer-start-and-point
3004 window new-buffer (nth 1 entry) (nth 2 entry)) 3017 window new-buffer (nth 1 entry) (nth 2 entry))
3005 (throw 'found t)))) 3018 (throw 'found t))))
@@ -3014,8 +3027,8 @@ shall not be switched to in future invocations of this command."
3014 (nreverse (buffer-list frame)))) 3027 (nreverse (buffer-list frame))))
3015 (when (and (buffer-live-p buffer) 3028 (when (and (buffer-live-p buffer)
3016 (not (eq buffer old-buffer)) 3029 (not (eq buffer old-buffer))
3017 (not (eq (aref (buffer-name buffer) 0) ?\s))
3018 (or (null pred) (funcall pred buffer)) 3030 (or (null pred) (funcall pred buffer))
3031 (not (eq (aref (buffer-name buffer) 0) ?\s))
3019 (or bury-or-kill (not (memq buffer next-buffers)))) 3032 (or bury-or-kill (not (memq buffer next-buffers))))
3020 (if (get-buffer-window buffer frame) 3033 (if (get-buffer-window buffer frame)
3021 ;; Try to avoid showing a buffer visible in some other window. 3034 ;; Try to avoid showing a buffer visible in some other window.
@@ -3047,12 +3060,20 @@ shall not be switched to in future invocations of this command."
3047 (set-window-buffer-start-and-point window new-buffer))) 3060 (set-window-buffer-start-and-point window new-buffer)))
3048 3061
3049 (if bury-or-kill 3062 (if bury-or-kill
3050 ;; Remove `old-buffer' from WINDOW's previous and (restored list 3063 (let ((entry (and (eq bury-or-kill 'append)
3051 ;; of) next buffers. 3064 (assq old-buffer (window-prev-buffers window)))))
3052 (progn 3065 ;; Remove `old-buffer' from WINDOW's previous and (restored list
3066 ;; of) next buffers.
3053 (set-window-prev-buffers 3067 (set-window-prev-buffers
3054 window (assq-delete-all old-buffer (window-prev-buffers window))) 3068 window (assq-delete-all old-buffer (window-prev-buffers window)))
3055 (set-window-next-buffers window (delq old-buffer next-buffers))) 3069 (set-window-next-buffers window (delq old-buffer next-buffers))
3070 (when entry
3071 ;; Append old-buffer's entry to list of WINDOW's previous
3072 ;; buffers so it's less likely to get switched to soon but
3073 ;; `display-buffer-in-previous-window' can nevertheless find
3074 ;; it.
3075 (set-window-prev-buffers
3076 window (append (window-prev-buffers window) (list entry)))))
3056 ;; Move `old-buffer' to head of WINDOW's restored list of next 3077 ;; Move `old-buffer' to head of WINDOW's restored list of next
3057 ;; buffers. 3078 ;; buffers.
3058 (set-window-next-buffers 3079 (set-window-next-buffers
@@ -3080,8 +3101,14 @@ found."
3080 (old-buffer (window-buffer window)) 3101 (old-buffer (window-buffer window))
3081 (next-buffers (window-next-buffers window)) 3102 (next-buffers (window-next-buffers window))
3082 (pred (frame-parameter frame 'buffer-predicate)) 3103 (pred (frame-parameter frame 'buffer-predicate))
3083 buffer new-buffer entry killed-buffers visible) 3104 new-buffer entry killed-buffers visible)
3105 (when (window-minibuffer-p window)
3106 ;; Don't switch in minibuffer window.
3107 (unless (setq window (minibuffer-selected-window))
3108 (error "Window %s is a minibuffer window" window)))
3109
3084 (when (window-dedicated-p window) 3110 (when (window-dedicated-p window)
3111 ;; Don't switch in dedicated window.
3085 (error "Window %s is dedicated to buffer %s" window old-buffer)) 3112 (error "Window %s is dedicated to buffer %s" window old-buffer))
3086 3113
3087 (catch 'found 3114 (catch 'found
@@ -3100,9 +3127,10 @@ found."
3100 ;; Scan the buffer list of WINDOW's frame next, skipping previous 3127 ;; Scan the buffer list of WINDOW's frame next, skipping previous
3101 ;; buffers entries. 3128 ;; buffers entries.
3102 (dolist (buffer (buffer-list frame)) 3129 (dolist (buffer (buffer-list frame))
3103 (when (and (buffer-live-p buffer) (not (eq buffer old-buffer)) 3130 (when (and (buffer-live-p buffer)
3104 (not (eq (aref (buffer-name buffer) 0) ?\s)) 3131 (not (eq buffer old-buffer))
3105 (or (null pred) (funcall pred buffer)) 3132 (or (null pred) (funcall pred buffer))
3133 (not (eq (aref (buffer-name buffer) 0) ?\s))
3106 (not (assq buffer (window-prev-buffers window)))) 3134 (not (assq buffer (window-prev-buffers window))))
3107 (if (get-buffer-window buffer frame) 3135 (if (get-buffer-window buffer frame)
3108 ;; Try to avoid showing a buffer visible in some other window. 3136 ;; Try to avoid showing a buffer visible in some other window.
@@ -3113,18 +3141,17 @@ found."
3113 ;; Scan WINDOW's reverted previous buffers last (must not use 3141 ;; Scan WINDOW's reverted previous buffers last (must not use
3114 ;; nreverse here!) 3142 ;; nreverse here!)
3115 (dolist (entry (reverse (window-prev-buffers window))) 3143 (dolist (entry (reverse (window-prev-buffers window)))
3116 (when (and (setq buffer (car entry)) 3144 (when (and (setq new-buffer (car entry))
3117 (or (buffer-live-p buffer) 3145 (or (buffer-live-p new-buffer)
3118 (not (setq killed-buffers 3146 (not (setq killed-buffers
3119 (cons buffer killed-buffers)))) 3147 (cons new-buffer killed-buffers))))
3120 (or (null pred) (funcall pred buffer)) 3148 (not (eq new-buffer old-buffer))
3121 (not (eq buffer old-buffer))) 3149 (or (null pred) (funcall pred new-buffer)))
3122 (if (and (not switch-to-visible-buffer) 3150 (if (and (not switch-to-visible-buffer)
3123 (get-buffer-window buffer frame)) 3151 (get-buffer-window new-buffer frame))
3124 ;; Try to avoid showing a buffer visible in some other window. 3152 ;; Try to avoid showing a buffer visible in some other window.
3125 (unless visible 3153 (unless visible
3126 (setq visible buffer)) 3154 (setq visible new-buffer))
3127 (setq new-buffer buffer)
3128 (set-window-buffer-start-and-point 3155 (set-window-buffer-start-and-point
3129 window new-buffer (nth 1 entry) (nth 2 entry)) 3156 window new-buffer (nth 1 entry) (nth 2 entry))
3130 (throw 'found t)))) 3157 (throw 'found t))))
@@ -3351,18 +3378,35 @@ all window-local buffer lists."
3351 ;; Unrecord BUFFER in WINDOW. 3378 ;; Unrecord BUFFER in WINDOW.
3352 (unrecord-window-buffer window buffer))))) 3379 (unrecord-window-buffer window buffer)))))
3353 3380
3354(defun quit-window (&optional kill window) 3381(defun quit-restore-window (&optional window bury-or-kill)
3355 "Quit WINDOW and bury its buffer. 3382 "Quit WINDOW and deal with its buffer.
3356WINDOW must be a live window and defaults to the selected one. 3383WINDOW must be a live window and defaults to the selected one.
3357With prefix argument KILL non-nil, kill the buffer instead of
3358burying it.
3359 3384
3360According to information stored in WINDOW's `quit-restore' window 3385According to information stored in WINDOW's `quit-restore' window
3361parameter either (1) delete WINDOW and its frame, (2) delete 3386parameter either (1) delete WINDOW and its frame, (2) delete
3362WINDOW, (3) restore the buffer previously displayed in WINDOW, 3387WINDOW, (3) restore the buffer previously displayed in WINDOW,
3363or (4) make WINDOW display some other buffer than the present 3388or (4) make WINDOW display some other buffer than the present
3364one. If non-nil, reset `quit-restore' parameter to nil." 3389one. If non-nil, reset `quit-restore' parameter to nil.
3365 (interactive "P") 3390
3391Optional second argument BURY-OR-KILL tells how to proceed with
3392the buffer of WINDOW. The following values are handled:
3393
3394`nil' means to not handle the buffer in a particular way. This
3395 means that if WINDOW is not deleted by this function, invoking
3396 `switch-to-prev-buffer' will usually show the buffer again.
3397
3398`append' means that if WINDOW is not deleted, move its buffer to
3399 the end of WINDOW's previous buffers so it's less likely that a
3400 future invocation of `switch-to-prev-buffer' will switch to it.
3401 Also, move the buffer to the end of the frame's buffer list.
3402
3403`bury' means that if WINDOW is not deleted, remove its buffer
3404 from WINDOW'S list of previous buffers. Also, move the buffer
3405 to the end of the frame's buffer list. This value provides the
3406 most reliable remedy to not have `switch-to-prev-buffer' switch
3407 to this buffer again without killing the buffer.
3408
3409`kill' means to kill WINDOW's buffer."
3366 (setq window (window-normalize-window window t)) 3410 (setq window (window-normalize-window window t))
3367 (let* ((buffer (window-buffer window)) 3411 (let* ((buffer (window-buffer window))
3368 (quit-restore (window-parameter window 'quit-restore)) 3412 (quit-restore (window-parameter window 'quit-restore))
@@ -3374,13 +3418,13 @@ one. If non-nil, reset `quit-restore' parameter to nil."
3374 (not (eq (setq prev-buffer (cadr prev-buffers)) 3418 (not (eq (setq prev-buffer (cadr prev-buffers))
3375 buffer)))) 3419 buffer))))
3376 prev-buffer))) 3420 prev-buffer)))
3377 quad resize) 3421 quad entry)
3378 (cond 3422 (cond
3379 ((and (not prev-buffer) 3423 ((and (not prev-buffer)
3380 (memq (nth 1 quit-restore) '(window frame)) 3424 (memq (nth 1 quit-restore) '(window frame))
3381 (eq (nth 3 quit-restore) buffer) 3425 (eq (nth 3 quit-restore) buffer)
3382 ;; Delete WINDOW if possible. 3426 ;; Delete WINDOW if possible.
3383 (window--delete window nil kill)) 3427 (window--delete window nil (eq bury-or-kill 'kill)))
3384 ;; If the previously selected window is still alive, select it. 3428 ;; If the previously selected window is still alive, select it.
3385 (when (window-live-p (nth 2 quit-restore)) 3429 (when (window-live-p (nth 2 quit-restore))
3386 (select-window (nth 2 quit-restore)))) 3430 (select-window (nth 2 quit-restore))))
@@ -3388,21 +3432,32 @@ one. If non-nil, reset `quit-restore' parameter to nil."
3388 (buffer-live-p (car quad)) 3432 (buffer-live-p (car quad))
3389 (eq (nth 3 quit-restore) buffer)) 3433 (eq (nth 3 quit-restore) buffer))
3390 ;; Show another buffer stored in quit-restore parameter. 3434 ;; Show another buffer stored in quit-restore parameter.
3391 (setq resize (and (integerp (nth 3 quad)) 3435 (when (and (integerp (nth 3 quad))
3392 (/= (nth 3 quad) (window-total-size window)))) 3436 (/= (nth 3 quad) (window-total-size window)))
3393 (set-window-dedicated-p window nil)
3394 (when resize
3395 ;; Try to resize WINDOW to its old height but don't signal an 3437 ;; Try to resize WINDOW to its old height but don't signal an
3396 ;; error. 3438 ;; error.
3397 (condition-case nil 3439 (condition-case nil
3398 (window-resize window (- (nth 3 quad) (window-total-size window))) 3440 (window-resize window (- (nth 3 quad) (window-total-size window)))
3399 (error nil))) 3441 (error nil)))
3442 (set-window-dedicated-p window nil)
3400 ;; Restore WINDOW's previous buffer, start and point position. 3443 ;; Restore WINDOW's previous buffer, start and point position.
3401 (set-window-buffer-start-and-point 3444 (set-window-buffer-start-and-point
3402 window (nth 0 quad) (nth 1 quad) (nth 2 quad)) 3445 window (nth 0 quad) (nth 1 quad) (nth 2 quad))
3403 ;; Unrecord WINDOW's buffer here (Bug#9937) to make sure it's not 3446 ;; Deal with the buffer we just removed from WINDOW.
3404 ;; re-recorded by `set-window-buffer'. 3447 (setq entry (and (eq bury-or-kill 'append)
3405 (unrecord-window-buffer window buffer) 3448 (assq buffer (window-prev-buffers window))))
3449 (when bury-or-kill
3450 ;; Remove buffer from WINDOW's previous and next buffers.
3451 (set-window-prev-buffers
3452 window (assq-delete-all buffer (window-prev-buffers window)))
3453 (set-window-next-buffers
3454 window (delq buffer (window-next-buffers window))))
3455 (when entry
3456 ;; Append old buffer's entry to list of WINDOW's previous
3457 ;; buffers so it's less likely to get switched to soon but
3458 ;; `display-buffer-in-previous-window' can nevertheless find it.
3459 (set-window-prev-buffers
3460 window (append (window-prev-buffers window) (list entry))))
3406 ;; Reset the quit-restore parameter. 3461 ;; Reset the quit-restore parameter.
3407 (set-window-parameter window 'quit-restore nil) 3462 (set-window-parameter window 'quit-restore nil)
3408 ;; Select old window. 3463 ;; Select old window.
@@ -3414,12 +3469,29 @@ one. If non-nil, reset `quit-restore' parameter to nil."
3414 (set-window-parameter window 'quit-restore nil) 3469 (set-window-parameter window 'quit-restore nil)
3415 ;; Make sure that WINDOW is no more dedicated. 3470 ;; Make sure that WINDOW is no more dedicated.
3416 (set-window-dedicated-p window nil) 3471 (set-window-dedicated-p window nil)
3417 (switch-to-prev-buffer window 'bury-or-kill))) 3472 (switch-to-prev-buffer window bury-or-kill)))
3473
3474 ;; Deal with the buffer.
3475 (cond
3476 ((not (buffer-live-p buffer)))
3477 ((eq bury-or-kill 'kill)
3478 (kill-buffer buffer))
3479 (bury-or-kill
3480 (bury-buffer-internal buffer)))))
3418 3481
3419 ;; Kill WINDOW's old-buffer if requested 3482(defun quit-window (&optional kill window)
3420 (if kill 3483 "Quit WINDOW and bury its buffer.
3421 (kill-buffer buffer) 3484WINDOW must be a live window and defaults to the selected one.
3422 (bury-buffer-internal buffer)))) 3485With prefix argument KILL non-nil, kill the buffer instead of
3486burying it.
3487
3488According to information stored in WINDOW's `quit-restore' window
3489parameter either (1) delete WINDOW and its frame, (2) delete
3490WINDOW, (3) restore the buffer previously displayed in WINDOW,
3491or (4) make WINDOW display some other buffer than the present
3492one. If non-nil, reset `quit-restore' parameter to nil."
3493 (interactive "P")
3494 (quit-restore-window window (if kill 'kill 'bury)))
3423 3495
3424(defun quit-windows-on (&optional buffer-or-name kill frame) 3496(defun quit-windows-on (&optional buffer-or-name kill frame)
3425 "Quit all windows showing BUFFER-OR-NAME. 3497 "Quit all windows showing BUFFER-OR-NAME.
@@ -5330,6 +5402,20 @@ again with `display-buffer-pop-up-window'."
5330 (and pop-up-windows 5402 (and pop-up-windows
5331 (display-buffer-pop-up-window buffer alist)))) 5403 (display-buffer-pop-up-window buffer alist))))
5332 5404
5405(defun display-buffer-below-selected (buffer _alist)
5406 "Try displaying BUFFER in a window below the selected window.
5407This either splits the selected window or reuses the window below
5408the selected one."
5409 (let (window)
5410 (or (and (not (frame-parameter nil 'unsplittable))
5411 (setq window (window--try-to-split-window (selected-window)))
5412 (window--display-buffer
5413 buffer window 'window display-buffer-mark-dedicated))
5414 (and (setq window (window-in-direction 'below))
5415 (not (window-dedicated-p window))
5416 (window--display-buffer
5417 buffer window 'reuse display-buffer-mark-dedicated)))))
5418
5333(defun display-buffer-use-some-window (buffer alist) 5419(defun display-buffer-use-some-window (buffer alist)
5334 "Display BUFFER in an existing window. 5420 "Display BUFFER in an existing window.
5335Search for a usable window, set that window to the buffer, and 5421Search for a usable window, set that window to the buffer, and