aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2019-11-26 10:13:12 +0100
committerMartin Rudalics2019-11-26 10:13:12 +0100
commit261b060f12234baa6912ef40a9ce1a054f583ad0 (patch)
tree05ff49333a2b84af0763bc491404352a20c89c7d
parentb006095bc9eb1f963372cf862aa040e9a9d30331 (diff)
downloademacs-261b060f12234baa6912ef40a9ce1a054f583ad0.tar.gz
emacs-261b060f12234baa6912ef40a9ce1a054f583ad0.zip
2019-11-26 Martin Rudalics <rudalics@gmx.at>
* lisp/window.el (switch-to-visible-buffer): Declare obsolete. (switch-to-prev-buffer-skip): New option. (switch-to-prev-buffer, switch-to-next-buffer): Obey 'switch-to-prev-buffer-skip'. * doc/lispref/windows.texi (Window History): Remove description of 'switch-to-visible-buffer'. Describe new option 'switch-to-prev-buffer-skip' * etc/NEWS: Mention switch from 'switch-to-visible-buffer' to 'switch-to-prev-buffer-skip'.
-rw-r--r--doc/lispref/windows.texi78
-rw-r--r--etc/NEWS10
-rw-r--r--lisp/window.el166
3 files changed, 201 insertions, 53 deletions
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index f05a6db1761..fdba259bf71 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -3920,8 +3920,13 @@ or killed, or has been already shown by a recent invocation of
3920If repeated invocations of this command have already shown all buffers 3920If repeated invocations of this command have already shown all buffers
3921previously shown in @var{window}, further invocations will show buffers 3921previously shown in @var{window}, further invocations will show buffers
3922from the buffer list of the frame @var{window} appears on (@pxref{Buffer 3922from the buffer list of the frame @var{window} appears on (@pxref{Buffer
3923List}), trying to skip buffers that are already shown in another window 3923List}).
3924on that frame. 3924
3925The option @code{switch-to-prev-buffer-skip} described below can be
3926used to inhibit switching to certain buffers, for example, to those
3927already shown in another window. Also, if @var{window}'s frame has a
3928@code{buffer-predicate} parameter (@pxref{Buffer Parameters}), that
3929predicate may inhibit switching to certain buffers.
3925@end deffn 3930@end deffn
3926 3931
3927@deffn Command switch-to-next-buffer &optional window 3932@deffn Command switch-to-next-buffer &optional window
@@ -3933,20 +3938,65 @@ defaults to the selected one.
3933If there is no recent invocation of @code{switch-to-prev-buffer} that 3938If there is no recent invocation of @code{switch-to-prev-buffer} that
3934can be undone, this function tries to show a buffer from the buffer list 3939can be undone, this function tries to show a buffer from the buffer list
3935of the frame @var{window} appears on (@pxref{Buffer List}). 3940of the frame @var{window} appears on (@pxref{Buffer List}).
3941
3942The option @code{switch-to-prev-buffer-skip} and the
3943@code{buffer-predicate} (@pxref{Buffer Parameters}) of @var{window}'s
3944frame affect this command as they do for @code{switch-to-prev-buffer}.
3936@end deffn 3945@end deffn
3937 3946
3938By default @code{switch-to-prev-buffer} and @code{switch-to-next-buffer} 3947By default @code{switch-to-prev-buffer} and
3939can switch to a buffer that is already shown in another window on the 3948@code{switch-to-next-buffer} can switch to a buffer that is already
3940same frame. The following option can be used to override this behavior. 3949shown in another window. The following option can be used to override
3941 3950this behavior.
3942@defopt switch-to-visible-buffer 3951
3943If this variable is non-@code{nil}, @code{switch-to-prev-buffer} and 3952@defopt switch-to-prev-buffer-skip
3944@code{switch-to-next-buffer} may switch to a buffer that is already 3953If this variable is @code{nil}, @code{switch-to-prev-buffer} may
3945visible on the same frame, provided the buffer was shown in the 3954switch to any buffer, including those already shown in other windows.
3946relevant window before. If it is @code{nil}, 3955
3947@code{switch-to-prev-buffer} and @code{switch-to-next-buffer} always 3956If this variable is non-@code{nil}, @code{switch-to-prev-buffer} will
3948try to avoid switching to a buffer that is already visible in another 3957refrain from switching to certain buffers. The following values can
3949window on the same frame. The default is @code{t}. 3958be used:
3959
3960@itemize @bullet
3961@item
3962@code{this} means do not switch to a buffer shown on the frame that
3963hosts the window @code{switch-to-prev-buffer} is acting upon.
3964
3965@item
3966@code{visible} means do not switch to a buffer shown on any visible
3967frame.
3968
3969@item
39700 (the number zero) means do not switch to a buffer shown on any
3971visible or iconified frame.
3972
3973@item
3974@code{t} means do not switch to a buffer shown on any live frame.
3975
3976@item
3977A function that takes three arguments---the @var{window} argument of
3978@code{switch-to-prev-buffer}, a buffer @code{switch-to-prev-buffer}
3979intends to switch to and the @var{bury-or-kill} argument of
3980@code{switch-to-prev-buffer}. If that function returns
3981non-@code{nil}, @code{switch-to-prev-buffer} will refrain from
3982switching to the buffer specified by the second argument.
3983@end itemize
3984
3985The command @code{switch-to-next-buffer} obeys this option in a
3986similar way. If this option specifies a function,
3987@code{switch-to-next-buffer} will call that function with the third
3988argument always @code{nil}.
3989
3990Note that since @code{switch-to-prev-buffer} is called by
3991@code{bury-buffer}, @code{replace-buffer-in-windows} and
3992@code{quit-restore-window} as well, customizing this option may also
3993affect the behavior of Emacs when a window is quit or a buffer gets
3994buried or killed.
3995
3996Note also that under certain circumstances
3997@code{switch-to-prev-buffer} and @code{switch-to-next-buffer} may
3998ignore this option, for example, when there is only one buffer left
3999these functions can switch to.
3950@end defopt 4000@end defopt
3951 4001
3952 4002
diff --git a/etc/NEWS b/etc/NEWS
index a97cf20ea7c..2a14eb2ecfc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -414,6 +414,16 @@ When non-nil, 'switch-to-buffer' uses 'pop-to-buffer-same-window' that
414respects display actions specified by 'display-buffer-alist' and 414respects display actions specified by 'display-buffer-alist' and
415'display-buffer-overriding-action'. 415'display-buffer-overriding-action'.
416 416
417+++
418** The option 'switch-to-visible-buffer' is now obsolete.
419Customize 'switch-to-prev-buffer-skip' instead.
420
421+++
422** New option 'switch-to-prev-buffer-skip'.
423This option allows to specify the set of buffers that may be shown by
424'switch-to-prev-buffer' and 'switch-to-next-buffer' more stringently
425than the now obsolete 'switch-to-visible-buffer'.
426
417** New 'flex' completion style 427** New 'flex' completion style
418An implementation of popular "flex/fuzzy/scatter" completion which 428An implementation of popular "flex/fuzzy/scatter" completion which
419matches strings where the pattern appears as a subsequence. Put 429matches strings where the pattern appears as a subsequence. Put
diff --git a/lisp/window.el b/lisp/window.el
index 74780479393..49fad75d3cd 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4409,6 +4409,68 @@ that is already visible in another window on the same frame."
4409 :version "24.1" 4409 :version "24.1"
4410 :group 'windows) 4410 :group 'windows)
4411 4411
4412(make-obsolete-variable 'switch-to-visible-buffer
4413 'switch-to-prev-buffer-skip "27.1")
4414
4415(defcustom switch-to-prev-buffer-skip nil
4416 "Buffers `switch-to-prev-buffer' should skip.
4417If this variable is nil, `switch-to-prev-buffer' may switch to
4418any buffer, including those already shown in other windows.
4419
4420If this variable is non-nil, `switch-to-prev-buffer' will refrain
4421from switching to certain buffers according to the value of this
4422variable:
4423
4424- `this' means do not switch to a buffer shown on the frame that
4425 hosts the window `switch-to-prev-buffer' is acting upon.
4426
4427- `visible' means do not switch to a buffer shown on any visible
4428 frame.
4429
4430- 0 (the number zero) means do not switch to a buffer shown on
4431 any visible or iconified frame.
4432
4433- t means do not switch to a buffer shown on any live frame.
4434
4435If this option specifies a function, that function is called with
4436three arguments - the WINDOW argument of `switch-to-prev-buffer',
4437a buffer `switch-to-prev-buffer' intends to switch to and the
4438BURY-OR-KILL argument of `switch-to-prev-buffer'. If that
4439function returns non-nil, `switch-to-prev-buffer' will not switch
4440to that buffer.
4441
4442Since `switch-to-prev-buffer' is called by `bury-buffer',
4443`replace-buffer-in-windows' and `quit-restore-window' among
4444others, customizing this option may also affect the behavior of
4445Emacs when a window is quit or a buffer gets buried or killed.
4446
4447The value of this option is consulted by `switch-to-next-buffer'
4448as well. In that case, if this option specifies a function, it
4449will be called with the third argument nil.
4450
4451Under certain circumstances `switch-to-prev-buffer' may ignore
4452this option, for example, when there is only one buffer left."
4453 :type
4454 '(choice (const :tag "Never" nil)
4455 (const :tag "This frame" this)
4456 (const :tag "Visible frames" visible)
4457 (const :tag "Visible and iconified frames" 0)
4458 (const :tag "Any frame" t)
4459 (function :tag "Function"))
4460 :version "27.1"
4461 :group 'windows)
4462
4463(defun switch-to-prev-buffer-skip-p (skip window buffer &optional bury-or-kill)
4464 "Return non-nil if `switch-to-prev-buffer' should skip BUFFER.
4465SKIP is a value derived from `switch-to-prev-buffer-skip', WINDOW
4466the window `switch-to-prev-buffer' acts upon. Optional argument
4467BURY-OR-KILL is passed unchanged by `switch-to-prev-buffer' and
4468omitted in calls from `switch-to-next-buffer'."
4469 (when skip
4470 (if (functionp skip)
4471 (funcall skip window buffer bury-or-kill)
4472 (get-buffer-window buffer skip))))
4473
4412(defun switch-to-prev-buffer (&optional window bury-or-kill) 4474(defun switch-to-prev-buffer (&optional window bury-or-kill)
4413 "In WINDOW switch to previous buffer. 4475 "In WINDOW switch to previous buffer.
4414WINDOW must be a live window and defaults to the selected one. 4476WINDOW must be a live window and defaults to the selected one.
@@ -4424,6 +4486,12 @@ move the buffer to the end of WINDOW's previous buffers list so a
4424future invocation of `switch-to-prev-buffer' less likely switches 4486future invocation of `switch-to-prev-buffer' less likely switches
4425to it. 4487to it.
4426 4488
4489The option `switch-to-prev-buffer-skip' can be used to not switch
4490to certain buffers, for example, to those already shown in
4491another window. Also, if WINDOW's frame has a `buffer-predicate'
4492parameter, that predicate may inhibit switching to certain
4493buffers.
4494
4427This function is called by `prev-buffer'." 4495This function is called by `prev-buffer'."
4428 (interactive) 4496 (interactive)
4429 (let* ((window (window-normalize-window window t)) 4497 (let* ((window (window-normalize-window window t))
@@ -4433,7 +4501,15 @@ This function is called by `prev-buffer'."
4433 ;; Save this since it's destroyed by `set-window-buffer'. 4501 ;; Save this since it's destroyed by `set-window-buffer'.
4434 (next-buffers (window-next-buffers window)) 4502 (next-buffers (window-next-buffers window))
4435 (pred (frame-parameter frame 'buffer-predicate)) 4503 (pred (frame-parameter frame 'buffer-predicate))
4436 entry new-buffer killed-buffers visible) 4504 (skip
4505 (cond
4506 ((or (functionp switch-to-prev-buffer-skip)
4507 (memq switch-to-prev-buffer-skip '(t visible 0)))
4508 switch-to-prev-buffer-skip)
4509 ((or switch-to-prev-buffer-skip
4510 (not switch-to-visible-buffer))
4511 frame)))
4512 entry new-buffer killed-buffers skipped)
4437 (when (window-minibuffer-p window) 4513 (when (window-minibuffer-p window)
4438 ;; Don't switch in minibuffer window. 4514 ;; Don't switch in minibuffer window.
4439 (unless (setq window (minibuffer-selected-window)) 4515 (unless (setq window (minibuffer-selected-window))
@@ -4456,11 +4532,8 @@ This function is called by `prev-buffer'."
4456 ;; When BURY-OR-KILL is nil, avoid switching to a 4532 ;; When BURY-OR-KILL is nil, avoid switching to a
4457 ;; buffer in WINDOW's next buffers list. 4533 ;; buffer in WINDOW's next buffers list.
4458 (or bury-or-kill (not (memq new-buffer next-buffers)))) 4534 (or bury-or-kill (not (memq new-buffer next-buffers))))
4459 (if (and (not switch-to-visible-buffer) 4535 (if (switch-to-prev-buffer-skip-p skip window new-buffer bury-or-kill)
4460 (get-buffer-window new-buffer frame)) 4536 (setq skipped new-buffer)
4461 ;; Try to avoid showing a buffer visible in some other
4462 ;; window.
4463 (setq visible new-buffer)
4464 (set-window-buffer-start-and-point 4537 (set-window-buffer-start-and-point
4465 window new-buffer (nth 1 entry) (nth 2 entry)) 4538 window new-buffer (nth 1 entry) (nth 2 entry))
4466 (throw 'found t)))) 4539 (throw 'found t))))
@@ -4478,18 +4551,17 @@ This function is called by `prev-buffer'."
4478 (when (and (buffer-live-p buffer) 4551 (when (and (buffer-live-p buffer)
4479 (not (eq buffer old-buffer)) 4552 (not (eq buffer old-buffer))
4480 (or (null pred) (funcall pred buffer)) 4553 (or (null pred) (funcall pred buffer))
4554 ;; Skip buffers whose names start with a space.
4481 (not (eq (aref (buffer-name buffer) 0) ?\s)) 4555 (not (eq (aref (buffer-name buffer) 0) ?\s))
4482 ;; Don't show a buffer shown in a side window before. 4556 ;; Skip buffers shown in a side window before.
4483 (not (buffer-local-value 'window--sides-shown buffer)) 4557 (not (buffer-local-value 'window--sides-shown buffer))
4484 (or bury-or-kill (not (memq buffer next-buffers)))) 4558 (or bury-or-kill (not (memq buffer next-buffers))))
4485 (if (and (not switch-to-visible-buffer) 4559 (if (switch-to-prev-buffer-skip-p skip window buffer bury-or-kill)
4486 (get-buffer-window buffer frame)) 4560 (setq skipped (or skipped buffer))
4487 ;; Try to avoid showing a buffer visible in some other window.
4488 (unless visible
4489 (setq visible buffer))
4490 (setq new-buffer buffer) 4561 (setq new-buffer buffer)
4491 (set-window-buffer-start-and-point window new-buffer) 4562 (set-window-buffer-start-and-point window new-buffer)
4492 (throw 'found t))))) 4563 (throw 'found t)))))
4564
4493 (unless bury-or-kill 4565 (unless bury-or-kill
4494 ;; Scan reverted next buffers last (must not use nreverse 4566 ;; Scan reverted next buffers last (must not use nreverse
4495 ;; here!). 4567 ;; here!).
@@ -4502,14 +4574,16 @@ This function is called by `prev-buffer'."
4502 (not (eq buffer old-buffer)) 4574 (not (eq buffer old-buffer))
4503 (or (null pred) (funcall pred buffer)) 4575 (or (null pred) (funcall pred buffer))
4504 (setq entry (assq buffer (window-prev-buffers window)))) 4576 (setq entry (assq buffer (window-prev-buffers window))))
4505 (setq new-buffer buffer) 4577 (if (switch-to-prev-buffer-skip-p skip window buffer bury-or-kill)
4506 (set-window-buffer-start-and-point 4578 (setq skipped (or skipped buffer))
4507 window new-buffer (nth 1 entry) (nth 2 entry)) 4579 (setq new-buffer buffer)
4508 (throw 'found t)))) 4580 (set-window-buffer-start-and-point
4509 4581 window new-buffer (nth 1 entry) (nth 2 entry))
4510 ;; Show a buffer visible in another window. 4582 (throw 'found t)))))
4511 (when visible 4583
4512 (setq new-buffer visible) 4584 (when skipped
4585 ;; Show first skipped buffer.
4586 (setq new-buffer skipped)
4513 (set-window-buffer-start-and-point window new-buffer))) 4587 (set-window-buffer-start-and-point window new-buffer)))
4514 4588
4515 (if bury-or-kill 4589 (if bury-or-kill
@@ -4547,7 +4621,15 @@ This function is called by `prev-buffer'."
4547 "In WINDOW switch to next buffer. 4621 "In WINDOW switch to next buffer.
4548WINDOW must be a live window and defaults to the selected one. 4622WINDOW must be a live window and defaults to the selected one.
4549Return the buffer switched to, nil if no suitable buffer could be 4623Return the buffer switched to, nil if no suitable buffer could be
4550found. This function is called by `next-buffer'." 4624found.
4625
4626The option `switch-to-prev-buffer-skip' can be used to not switch
4627to certain buffers, for example, to those already shown in
4628another window. Also, if WINDOW's frame has a `buffer-predicate'
4629parameter, that predicate may inhibit switching to certain
4630buffers.
4631
4632This function is called by `next-buffer'."
4551 (interactive) 4633 (interactive)
4552 (let* ((window (window-normalize-window window t)) 4634 (let* ((window (window-normalize-window window t))
4553 (frame (window-frame window)) 4635 (frame (window-frame window))
@@ -4555,7 +4637,15 @@ found. This function is called by `next-buffer'."
4555 (old-buffer (window-buffer window)) 4637 (old-buffer (window-buffer window))
4556 (next-buffers (window-next-buffers window)) 4638 (next-buffers (window-next-buffers window))
4557 (pred (frame-parameter frame 'buffer-predicate)) 4639 (pred (frame-parameter frame 'buffer-predicate))
4558 new-buffer entry killed-buffers visible) 4640 (skip
4641 (cond
4642 ((or (functionp switch-to-prev-buffer-skip)
4643 (memq switch-to-prev-buffer-skip '(t visible 0)))
4644 switch-to-prev-buffer-skip)
4645 ((or switch-to-prev-buffer-skip
4646 (not switch-to-visible-buffer))
4647 frame)))
4648 new-buffer entry killed-buffers skipped)
4559 (when (window-minibuffer-p window) 4649 (when (window-minibuffer-p window)
4560 ;; Don't switch in minibuffer window. 4650 ;; Don't switch in minibuffer window.
4561 (unless (setq window (minibuffer-selected-window)) 4651 (unless (setq window (minibuffer-selected-window))
@@ -4574,10 +4664,12 @@ found. This function is called by `next-buffer'."
4574 (not (eq buffer old-buffer)) 4664 (not (eq buffer old-buffer))
4575 (or (null pred) (funcall pred buffer)) 4665 (or (null pred) (funcall pred buffer))
4576 (setq entry (assq buffer (window-prev-buffers window)))) 4666 (setq entry (assq buffer (window-prev-buffers window))))
4577 (setq new-buffer buffer) 4667 (if (switch-to-prev-buffer-skip-p skip window buffer)
4578 (set-window-buffer-start-and-point 4668 (setq skipped buffer)
4579 window new-buffer (nth 1 entry) (nth 2 entry)) 4669 (setq new-buffer buffer)
4580 (throw 'found t))) 4670 (set-window-buffer-start-and-point
4671 window new-buffer (nth 1 entry) (nth 2 entry))
4672 (throw 'found t))))
4581 ;; Scan the buffer list of WINDOW's frame next, skipping previous 4673 ;; Scan the buffer list of WINDOW's frame next, skipping previous
4582 ;; buffers entries. Skip this step for side windows. 4674 ;; buffers entries. Skip this step for side windows.
4583 (unless window-side 4675 (unless window-side
@@ -4585,14 +4677,13 @@ found. This function is called by `next-buffer'."
4585 (when (and (buffer-live-p buffer) 4677 (when (and (buffer-live-p buffer)
4586 (not (eq buffer old-buffer)) 4678 (not (eq buffer old-buffer))
4587 (or (null pred) (funcall pred buffer)) 4679 (or (null pred) (funcall pred buffer))
4680 ;; Skip buffers whose names start with a space.
4588 (not (eq (aref (buffer-name buffer) 0) ?\s)) 4681 (not (eq (aref (buffer-name buffer) 0) ?\s))
4589 ;; Don't show a buffer shown in a side window before. 4682 ;; Skip buffers shown in a side window before.
4590 (not (buffer-local-value 'window--sides-shown buffer)) 4683 (not (buffer-local-value 'window--sides-shown buffer))
4591 (not (assq buffer (window-prev-buffers window)))) 4684 (not (assq buffer (window-prev-buffers window))))
4592 (if (and (not switch-to-visible-buffer) 4685 (if (switch-to-prev-buffer-skip-p skip window buffer)
4593 (get-buffer-window buffer frame)) 4686 (setq skipped (or skipped buffer))
4594 ;; Try to avoid showing a buffer visible in some other window.
4595 (setq visible buffer)
4596 (setq new-buffer buffer) 4687 (setq new-buffer buffer)
4597 (set-window-buffer-start-and-point window new-buffer) 4688 (set-window-buffer-start-and-point window new-buffer)
4598 (throw 'found t))))) 4689 (throw 'found t)))))
@@ -4605,18 +4696,15 @@ found. This function is called by `next-buffer'."
4605 (cons new-buffer killed-buffers)))) 4696 (cons new-buffer killed-buffers))))
4606 (not (eq new-buffer old-buffer)) 4697 (not (eq new-buffer old-buffer))
4607 (or (null pred) (funcall pred new-buffer))) 4698 (or (null pred) (funcall pred new-buffer)))
4608 (if (and (not switch-to-visible-buffer) 4699 (if (switch-to-prev-buffer-skip-p skip window new-buffer)
4609 (get-buffer-window new-buffer frame)) 4700 (setq skipped (or skipped new-buffer))
4610 ;; Try to avoid showing a buffer visible in some other window.
4611 (unless visible
4612 (setq visible new-buffer))
4613 (set-window-buffer-start-and-point 4701 (set-window-buffer-start-and-point
4614 window new-buffer (nth 1 entry) (nth 2 entry)) 4702 window new-buffer (nth 1 entry) (nth 2 entry))
4615 (throw 'found t)))) 4703 (throw 'found t))))
4616 4704
4617 ;; Show a buffer visible in another window. 4705 (when skipped
4618 (when visible 4706 ;; Show first skipped buffer.
4619 (setq new-buffer visible) 4707 (setq new-buffer skipped)
4620 (set-window-buffer-start-and-point window new-buffer))) 4708 (set-window-buffer-start-and-point window new-buffer)))
4621 4709
4622 ;; Remove `new-buffer' from and restore WINDOW's next buffers. 4710 ;; Remove `new-buffer' from and restore WINDOW's next buffers.