aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMartin Rudalics2011-08-31 11:27:49 +0200
committerMartin Rudalics2011-08-31 11:27:49 +0200
commitf818cd2a398ced7776c91e41331afb51b00b471a (patch)
treec5747b924ff5b8dee854eea20f28bc7d09495df4 /lisp
parent5bc3b51d1ec7f6ff63e08d5e1c889a84a4eaf29c (diff)
downloademacs-f818cd2a398ced7776c91e41331afb51b00b471a.tar.gz
emacs-f818cd2a398ced7776c91e41331afb51b00b471a.zip
Restore Emacs 23 display-buffer functions and options.
* window.el (display-buffer-window): Rewrite doc-string. (display-buffer-record-window): New function. (display-buffer-macro-specifiers) (display-buffer-even-window-sizes, display-buffer-set-height) (display-buffer-set-width, display-buffer-in-window) (display-buffer-reuse-window, display-buffer-split-specifiers) (display-buffer-side-specifiers, display-buffer-split-window-1) (display-buffer-split-window, display-buffer-split-atom-window) (display-buffer-pop-up-window, display-buffer-pop-up-frame) (display-buffer-pop-up-side-window, display-buffer-in-side-window) (display-buffer-other-window-means-other-frame) (display-buffer-normalize-special) (display-buffer-normalize-default) (display-buffer-normalize-argument) (display-buffer-normalize-alist-1, display-buffer-normalize-alist) (display-buffer-normalize-specifiers, display-buffer-frame) (display-buffer-same-window, display-buffer-same-frame) (display-buffer-other-window) (display-buffer-same-frame-other-window) (display-buffer-other-frame, pop-to-buffer-same-window) (pop-to-buffer-same-frame, pop-to-buffer-other-window) (pop-to-buffer-same-frame-other-window, pop-to-buffer-other-frame) (switch-to-buffer-same-frame) (switch-to-buffer-other-window-same-frame) (display-buffer-alist-of-strings-p, display-buffer-alist-add) (display-buffer-alist-set-1, display-buffer-alist-set-2) (display-buffer-alist-set): Remove. (display-buffer-function, special-display-buffer-names) (special-display-regexps, special-display-function): In doc-string refer to display-buffer-window and quit-restore parameter. (pop-up-frame-alist, pop-up-frame-function, special-display-p) (special-display-frame-alist, special-display-popup-frame) (same-window-buffer-names, same-window-regexps, same-window-p) (pop-up-frames, display-buffer-reuse-frames, pop-up-windows) (split-window-preferred-function, split-height-threshold) (split-width-threshold, window-splittable-p) (split-window-sensibly, window--try-to-split-window) (window--frame-usable-p, even-window-heights) (window--even-window-heights, window--display-buffer-1) (window--display-buffer-2, display-buffer-other-frame): Restore old Emacs 23 code, order and doc-strings where applicable. (display-buffer-default, display-buffer-assq-regexp): New functions. (display-buffer-alist): Rewrite doc-string. (display-buffer-default-action) (display-buffer-overriding-action): New variables. (display-buffer, switch-to-buffer): Rewrite. (pop-to-buffer): Restore Emacs 23 behavior but use window-normalize-buffer-to-display. (switch-to-buffer-other-window, switch-to-buffer-other-frame): Restore Emacs 23 behavior but use window-normalize-buffer-to-switch-to. (pop-to-buffer-same-window): Rewrite. (pop-to-buffer-other-window, pop-to-buffer-other-frame): Rewrite using Emacs 23 options. * org-compat.el (org-pop-to-buffer-same-window): Remove LABEL argument from pop-to-buffer-same-window call.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog58
-rw-r--r--lisp/org/ChangeLog5
-rw-r--r--lisp/org/org-compat.el2
-rw-r--r--lisp/window.el3436
4 files changed, 864 insertions, 2637 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4fa4dfc5700..8bf75bf1a61 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,61 @@
12011-08-31 Martin Rudalics <rudalics@gmx.at>
2
3 * window.el (display-buffer-window): Rewrite doc-string.
4 (display-buffer-record-window): New function.
5 (display-buffer-macro-specifiers)
6 (display-buffer-even-window-sizes, display-buffer-set-height)
7 (display-buffer-set-width, display-buffer-in-window)
8 (display-buffer-reuse-window, display-buffer-split-specifiers)
9 (display-buffer-side-specifiers, display-buffer-split-window-1)
10 (display-buffer-split-window, display-buffer-split-atom-window)
11 (display-buffer-pop-up-window, display-buffer-pop-up-frame)
12 (display-buffer-pop-up-side-window, display-buffer-in-side-window)
13 (display-buffer-other-window-means-other-frame)
14 (display-buffer-normalize-special)
15 (display-buffer-normalize-default)
16 (display-buffer-normalize-argument)
17 (display-buffer-normalize-alist-1, display-buffer-normalize-alist)
18 (display-buffer-normalize-specifiers, display-buffer-frame)
19 (display-buffer-same-window, display-buffer-same-frame)
20 (display-buffer-other-window)
21 (display-buffer-same-frame-other-window)
22 (display-buffer-other-frame, pop-to-buffer-same-window)
23 (pop-to-buffer-same-frame, pop-to-buffer-other-window)
24 (pop-to-buffer-same-frame-other-window, pop-to-buffer-other-frame)
25 (switch-to-buffer-same-frame)
26 (switch-to-buffer-other-window-same-frame)
27 (display-buffer-alist-of-strings-p, display-buffer-alist-add)
28 (display-buffer-alist-set-1, display-buffer-alist-set-2)
29 (display-buffer-alist-set): Remove.
30 (display-buffer-function, special-display-buffer-names)
31 (special-display-regexps, special-display-function): In
32 doc-string refer to display-buffer-window and quit-restore
33 parameter.
34 (pop-up-frame-alist, pop-up-frame-function, special-display-p)
35 (special-display-frame-alist, special-display-popup-frame)
36 (same-window-buffer-names, same-window-regexps, same-window-p)
37 (pop-up-frames, display-buffer-reuse-frames, pop-up-windows)
38 (split-window-preferred-function, split-height-threshold)
39 (split-width-threshold, window-splittable-p)
40 (split-window-sensibly, window--try-to-split-window)
41 (window--frame-usable-p, even-window-heights)
42 (window--even-window-heights, window--display-buffer-1)
43 (window--display-buffer-2, display-buffer-other-frame): Restore
44 old Emacs 23 code, order and doc-strings where applicable.
45 (display-buffer-default, display-buffer-assq-regexp): New functions.
46 (display-buffer-alist): Rewrite doc-string.
47 (display-buffer-default-action)
48 (display-buffer-overriding-action): New variables.
49 (display-buffer, switch-to-buffer): Rewrite.
50 (pop-to-buffer): Restore Emacs 23 behavior but use
51 window-normalize-buffer-to-display.
52 (switch-to-buffer-other-window, switch-to-buffer-other-frame):
53 Restore Emacs 23 behavior but use
54 window-normalize-buffer-to-switch-to.
55 (pop-to-buffer-same-window): Rewrite.
56 (pop-to-buffer-other-window, pop-to-buffer-other-frame): Rewrite
57 using Emacs 23 options.
58
12011-08-31 Michael Albinus <michael.albinus@gmx.de> 592011-08-31 Michael Albinus <michael.albinus@gmx.de>
2 60
3 * net/tramp.el (tramp-root-regexp): Remove. 61 * net/tramp.el (tramp-root-regexp): Remove.
diff --git a/lisp/org/ChangeLog b/lisp/org/ChangeLog
index 1c58b8a9a7f..625e0926c52 100644
--- a/lisp/org/ChangeLog
+++ b/lisp/org/ChangeLog
@@ -1,3 +1,8 @@
12011-08-31 Martin Rudalics <rudalics@gmx.at>
2
3 * org-compat.el (org-pop-to-buffer-same-window): Remove LABEL
4 argument from pop-to-buffer-same-window call.
5
12011-07-30 Carsten Dominik <carsten.dominik@gmail.com> 62011-07-30 Carsten Dominik <carsten.dominik@gmail.com>
2 7
3 * ob.el (org-babel-src-block-regexp): If a code block has a body, 8 * ob.el (org-babel-src-block-regexp): If a code block has a body,
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index edbfa6a1bae..9b0a935a515 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -438,7 +438,7 @@ With two arguments, return floor and remainder of their quotient."
438 "Pop to buffer specified by BUFFER-OR-NAME in the selected window." 438 "Pop to buffer specified by BUFFER-OR-NAME in the selected window."
439 (if (fboundp 'pop-to-buffer-same-window) 439 (if (fboundp 'pop-to-buffer-same-window)
440 (funcall 440 (funcall
441 'pop-to-buffer-same-window buffer-or-name norecord label) 441 'pop-to-buffer-same-window buffer-or-name norecord)
442 (funcall 'switch-to-buffer buffer-or-name norecord))) 442 (funcall 'switch-to-buffer buffer-or-name norecord)))
443 443
444(provide 'org-compat) 444(provide 'org-compat)
diff --git a/lisp/window.el b/lisp/window.el
index 651e78bb419..50deb035420 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -3822,790 +3822,6 @@ subwindows can get as small as `window-safe-min-height' and
3822 (window-state-put-2 ignore)) 3822 (window-state-put-2 ignore))
3823 (window-check frame)))) 3823 (window-check frame))))
3824 3824
3825(defconst display-buffer-macro-specifiers
3826 '((same-window
3827 ;; Use the same window.
3828 (reuse-window same nil nil))
3829 (same-frame
3830 ;; Avoid other frames.
3831 (reuse-window nil same nil)
3832 (pop-up-window (largest . nil) (lru . nil))
3833 (reuse-window nil other nil))
3834 (same-frame-other-window
3835 ;; Avoid other frames and selected window.
3836 (reuse-window other same nil)
3837 (pop-up-window (largest . nil) (lru . nil))
3838 (reuse-window other other nil))
3839 (other-frame
3840 ;; Avoid selected frame.
3841 (reuse-window nil same other)
3842 (pop-up-frame)
3843 (reuse-window nil other other)))
3844 "Buffer display macro specifiers.")
3845
3846(defcustom display-buffer-alist nil
3847 "List associating buffer identifiers with display specifiers.
3848The car of each element of this list is built from a set of cons
3849cells called buffer identifiers. `display-buffer' shows a buffer
3850according to the display specifiers in the element's cdr
3851\(elements are true lists) if at least one of the identifiers
3852matches the first or third argument of `display-buffer'. Such a
3853match occurs in one of the following three cases:
3854
3855- The car of the buffer identifier is the symbol `name' and its
3856 cdr is a string equalling the name of the buffer specified by
3857 the first \(BUFFER-OR-NAME) argument of `display-buffer'.
3858
3859- The car is the symbol `regexp' and the cdr is a regular
3860 expression matching the name of the buffer specified by the
3861 first \(BUFFER-OR-NAME) argument of `display-buffer'.
3862
3863- The car is the symbol `label' and the cdr is a symbol equalling
3864 the third \(LABEL) argument of `display-buffer'.
3865
3866Display specifiers are either symbols, cons cells, or lists.
3867Five specifiers have been reserved to indicate the basic method
3868for displaying the buffer: `reuse-window', `pop-up-window',
3869`pop-up-frame', `use-side-window', and `function'.
3870
3871A list whose car is the symbol `reuse-window' indicates that an
3872existing window shall be reused for displaying the buffer. The
3873second element of this list specifies the window to use and can
3874be one of the following symbols:
3875
3876 nil stands for any window.
3877
3878 `same' stands for the selected window.
3879
3880 `other' stands for any but the selected window.
3881
3882The third element specifies whether the buffer shown in a window
3883that shall be reused must be the same buffer that shall be
3884displayed or another buffer and can be one of the following:
3885
3886 nil means to not care about the window's buffer.
3887
3888 `same' means the window must show the buffer already.
3889
3890 `other' means the window must not show the buffer yet.
3891
3892The fourth element specifies the set of frames to search for a
3893suitable window and can be one of the following:
3894
3895 nil to reuse a window on the selected frame.
3896
3897 `visible' to search visible frames on the current terminal.
3898
3899 `other' stands for any visible frame but the selected one.
3900
3901 0 \(the number zero) to search visible and iconified frames on
3902 the current terminal.
3903
3904 t to search arbitrary frames including invisible ones.
3905
3906If more than one window fits the constraints imposed by these
3907elements, the least recently used candidate is chosen. A side
3908window is never reused unless it already shows the buffer.
3909
3910The following two specifiers are useful when the method equals
3911`reuse-window':
3912
3913- A cons cell whose car is the symbol `reuse-window-even-sizes'
3914 and whose cdr is non-nil means to even out the sizes of a
3915 reused window and the selected window provided they (1) appear
3916 adjacent to each other and (2) the selected window is larger
3917 than the window chosen. If the cdr is nil, this means that the
3918 window sizes are left alone.
3919
3920- A cons cell whose car is the symbol `reuse-window-dedicated'
3921 and whose cdr is non-nil means that a window can be reused even
3922 if it's weakly dedicated to its buffer. If the cdr is t, a
3923 strongly dedicated window can be reused to show the buffer.
3924 Any other non-nil value means only weakly dedicated windows can
3925 be reused. If the cdr is nil, dedicated windows are not
3926 reused.
3927
3928 This specifier should be used in emergency cases only since
3929 windows are usually made dedicated in order to prevent
3930 `display-buffer' from reusing them.
3931
3932A list whose car is the symbol `pop-up-window' and whose cdr is
3933built from cons cells representing window/side tuples indicates
3934that a new window shall be made for displaying the buffer on the
3935selected frame.
3936
3937Window/side tuples are cons cells. The car of such a tuple
3938identifies the window that shall be split. Possible values are
3939`largest', `lru', `selected', and `root' to split the largest,
3940least recently used, selected or root window of the selected
3941frame.
3942
3943If the frame has side windows, these values do allow to split
3944only the selected frame's main window or one of its subwindows.
3945Setting the car to one of `left', `top', `right' and `bottom'
3946splits the corresponding side window, provided such a window
3947exists.
3948
3949The cdr of each pair specifies on which side of the window to
3950split the new window shall appear and can be one of `below',
3951`right', `above', or `left' with the obvious meanings. If the
3952cdr is nil, the window is split in a fashion suitable for its
3953current dimensions. If the cdr specifies a function, that
3954function is called with one argument - the window to split. The
3955function is supposed to split that window and return the new
3956window.
3957
3958`display-buffer' scans these tuples until it can either produce a
3959suitable window or fails. The default value for
3960`display-buffer-alist' contains the tuples \(largest . nil) and
3961\(lru . nil) in order to split the largest window first and, if
3962that fails, the least recently used one.
3963
3964The following specifiers are useful if the method specifier is
3965`pop-up-window'.
3966
3967- A cons cell whose car is the symbol `pop-up-window-min-height'
3968 specifiies the minimum height of the new window. If the cdr is
3969 an integer number, it specifies the minimum number of lines of
3970 the window. A floating point number gives the minimum fraction
3971 of the window height with respect to the height of the frame's
3972 root window. A new window is created only if it can be made at
3973 least as high as specified by the number. If the cdr is nil,
3974 this means to use the value of `window-min-height'.
3975
3976- A cons cell whose car is the symbol `pop-up-window-min-width'
3977 specifies the minimum width of the new window. If the cdr is
3978 an integer number, it specifies the minimum number of columns
3979 of the window. A floating point number gives the minimum
3980 fraction of the window width with respect to the width of the
3981 frame's root window. A new window is created only if it can be
3982 made at least as wide as specified by the number. If the cdr
3983 is nil, this means to use the value of `window-min-width'.
3984
3985- A cons cell whose car is `pop-up-window-set-height' with
3986 the following interpretations for the cdr:
3987
3988 - nil means leave the height of the new window alone.
3989
3990 - A number specifies the desired height of the new window. An
3991 integer number specifies the number of lines of the window.
3992 A floating point number gives the fraction of the window
3993 height with respect to the height of the frame's root window.
3994
3995 - If the cdr specifies a function, that function is called with
3996 one argument - the new window. The function is supposed to
3997 adjust the height of the window; its return value is ignored.
3998 Suitable functions are `shrink-window-if-larger-than-buffer'
3999 and `fit-window-to-buffer'.
4000
4001- A cons cell whose car equals `pop-up-window-set-width' with
4002 the following interpretations for the cdr:
4003
4004 - nil means leave the width of the new window alone.
4005
4006 - A number specifies the desired width of the new window. An
4007 integer number specifies the number of columns of the window.
4008 A floating point number gives the fraction of the window
4009 width with respect to the width of the frame's root window.
4010
4011 - If the cdr specifies a function, that function is called with
4012 one argument - the new window. The function is supposed to
4013 adjust the width of the window; its return value is ignored.
4014
4015 Observe that specifying `pop-up-window-set-height' or
4016 `pop-up-window-set-width' may override restrictions given by
4017 the `pop-up-window-min-height' and `pop-up-window-min-width'
4018 specifiers.
4019
4020- A cons cell whose car is `pop-up-window-split-unsplittable' and
4021 whose cdr is non-nil allows to make a new window on an
4022 unsplittable frame. If the cdr is nil, unsplittable frames are
4023 not split. This specifier should be used in special cases only
4024 since frames are usually made unsplittable in order to prevent
4025 `display-buffer' from splitting them.
4026
4027A list whose car is the symbol `pop-up-frame' specifies that a
4028new frame shall be made for displaying the buffer. The second
4029element, if non-nil, allows popping up a new frame on graphic
4030displays only.
4031
4032The following specifiers are useful if the method specifier is
4033`pop-up-frame'.
4034
4035- A list whose car is the symbol `pop-up-frame-function' together
4036 with a valid function as cdr specifies the function for
4037 creating a new frame. If the cdr is nil, the default function
4038 `make-frame' is called. The function is called with the
4039 parameters and values provided by the specifier described next.
4040
4041- A list whose car is the symbol `pop-up-frame-alist' followed by
4042 an arbitrary number of frame parameter/value tuples, each given
4043 as a cons cell, specifies the parameters passed to the pop-up
4044 frame function.
4045
4046A list of three elements whose car is the symbol
4047`use-side-window' specifies that the buffer shall be displayed in
4048a side window of the selected frame. The second element denotes
4049the side of the frame where the window appears or shall be made.
4050The third element denotes the slot used by the window. If a side
4051window with the specified slot exists already, that window is
4052reused. If no such window exists it is created.
4053
4054The following specifiers are useful in connection with the
4055`use-side-window' method specifier: `reuse-window-dedicated',
4056`pop-up-window-min-height', `pop-up-window-min-width',
4057`pop-up-window-set-height' and `pop-up-window-set-width'.
4058
4059A list whose car is the symbol `function' specifies that the
4060function specified in the second element of the list is
4061responsible for displaying the buffer. `display-buffer' calls
4062this function with the buffer as first argument and the remaining
4063elements of the list as the second.
4064
4065The function should choose or create a window, display the buffer
4066in it, and return the window. It is also responsible for giving
4067the variable `display-buffer-window' and the `quit-restore'
4068parameter of the window used a meaningful value.
4069
4070Within the body of this function avoid calling `display-buffer'
4071with the same buffer as argument since this may lead to endless
4072recursion.
4073
4074Instead of supplying basic method specifiers, it's sometimes more
4075convenient to use macro specifiers. They provide some commonly
4076used display methods but do not support the fine control provided
4077by the basic method specifiers. Macro specifiers are symbols.
4078The following macro specifiers are provided:
4079
4080 `same-window' to display the buffer in the selected window.
4081
4082 `same-frame' to display the buffer on the selected frame.
4083
4084 `other-window' to display the buffer in any window but the
4085 selected one.
4086
4087 `same-frame-other-window' as `other-window' but stay on the
4088 selected frame.
4089
4090 `other-frame' to display the buffer on another visible
4091 frame.
4092
4093 `default' to use the default value of `display-buffer-alist'.
4094
4095One specifier is useful with any method specifier: A list whose
4096car is the symbol `dedicate' and whose cdr is non-nil will
4097dedicate the window to its buffer. The following values are
4098supported:
4099
4100- nil to not dedicate the window to the buffer.
4101
4102- `weak' to weakly dedicate the window to the buffer.
4103
4104- t to strongly dedicate the window to the buffer.
4105
4106A cons cell whose car is `other-window-means-other-frame' and
4107whose cdr is non-nil means that you want calls of
4108`display-buffer' with the second argument t or the symbol
4109`other-window' to display the buffer in another frame. This
4110means, for example, that you prefer functions like
4111`find-file-other-window' or `switch-to-buffer-other-window' to
4112make a new frame instead of a new window on the selected frame.
4113
4114Usually, applications are free to override the specifiers of
4115`display-buffer-alist' by passing their own specifiers as second
4116argument of `display-buffer'. For every `display-buffer-alist'
4117entry you can, however, add a cons cell whose car is the symbol
4118`override' and whose cdr is non-nil, to explicitly override any
4119value supplied by the application.
4120
4121Overriding specifiers supplied by the calling application is, in
4122general, not advisable. It permits, for example, to change the
4123semantics of a function like `display-buffer-other-window' by
4124using the location specifiers `same-window' or `other-frame'."
4125 :risky t
4126 :type
4127 '(repeat
4128 :offset 9
4129 ;; Associations of buffer identifiers and display specifiers.
4130 (list
4131 :format "%v"
4132 ;; Buffer identifiers.
4133 (repeat
4134 :tag "Buffer identifiers"
4135 (choice
4136 :tag "Identifier"
4137 :format "%[%t%] %v" :size 15
4138 (cons
4139 :tag "Name"
4140 :format "%v"
4141 :help-echo "A buffer name."
4142 (const :format "" name)
4143 (string :format "Name: %v\n" :size 32))
4144 (cons
4145 :tag "Regexp"
4146 :format "%v"
4147 :help-echo "A regular expression matching buffer names."
4148 (const :format "" regexp)
4149 (string :format "Regexp: %v\n" :size 32))
4150 (cons
4151 :tag "Label"
4152 :format "%v"
4153 :help-echo "A symbol equalling the buffer display label."
4154 (const :format "" label)
4155 (symbol :format "Label: %v\n" :size 32))))
4156
4157 ;; Display specifiers.
4158 (repeat
4159 :offset 9
4160 :tag "Display specifiers"
4161 :inline t
4162 (list
4163 :inline t
4164 :format "%v"
4165 (choice
4166 :tag "Method"
4167 :value (reuse-window
4168 (reuse-window nil same nil)
4169 (reuse-window-even-sizes . t))
4170 :inline t
4171 :help-echo "Method for displaying the buffer."
4172 :format "%[Method%] %v" :size 15
4173
4174 ;; Reuse window specifiers.
4175 (list
4176 :tag "Reuse window"
4177 :value (reuse-window
4178 (reuse-window nil same nil)
4179 (reuse-window-even-sizes . t))
4180 :format "%t\n%v"
4181 :inline t
4182 ;; For customization purposes only.
4183 (const :format "" reuse-window)
4184 (set
4185 :format "%v"
4186 :inline t
4187 ;; The window to reuse.
4188 (list
4189 :format "%v\n"
4190 (const :format "" reuse-window)
4191 ;; The window type.
4192 (choice
4193 :tag "Window"
4194 :help-echo "Window to reuse."
4195 :value nil
4196 :format "%[Window%] %v" :size 15
4197 (const :tag "Any window" :format "%t" nil)
4198 (const :tag "Same window" :format "%t" same)
4199 (const :tag "Other window" :format "%t" other))
4200 ;; The window's buffer.
4201 (choice
4202 :tag "Buffer"
4203 :help-echo "Buffer shown by reused window."
4204 :value t
4205 :format " %[Buffer%] %v" :size 15
4206 (const :tag "Any buffer" :format "%t" nil)
4207 (const :tag "Same buffer" :format "%t" same)
4208 (const :tag "Other buffer" :format "%t" other))
4209 ;; The window's frame.
4210 (choice
4211 :help-echo "Frames to search for a window to reuse."
4212 :tag "Frame"
4213 :value nil
4214 :format " %[Frame%] %v" :size 15
4215 (const :tag "Same frame only" :format "%t" nil)
4216 (const :tag "Visible frames" :format "%t" visible)
4217 (const :tag "Any other visible frame" :format "%t" other)
4218 (const :tag "Visible and iconified frames" :format "%t" 0)
4219 (const :tag "All frames" :format "%t" t)))
4220 ;; Whether window sizes should be evened out.
4221 (cons
4222 :format "%v\n"
4223 :tag "Even window sizes"
4224 (const :format "" reuse-window-even-sizes)
4225 (choice
4226 :tag "Even window sizes"
4227 :help-echo "Whether to even sizes of selected and reused window."
4228 :value t
4229 :format "%[Even window sizes%] %v" :size 15
4230 (const :tag "Off" :format "%t" nil)
4231 (const :tag "Even window sizes" :format "%t" t)))
4232 ;; Whether to reuse a dedicated window
4233 (cons
4234 :format "%v\n"
4235 (const :format "" reuse-window-dedicated)
4236 (choice
4237 :tag "Reuse dedicated window" :value nil
4238 :help-echo "Reuse a window even if it is dedicated to its buffer."
4239 :format "%[Reuse dedicated window%] %v" :size 15
4240 (const :tag "Off" :format "%t" nil)
4241 (const :tag "Reuse weakly dedicated windows" :format "%t" weak)
4242 (const :tag "Reuse any dedicated window" :format "%t" t)))))
4243
4244 ;; Pop-up window specifiers.
4245 (list
4246 :tag "Pop-up window"
4247 :value (pop-up-window (pop-up-window (largest . nil) (lru . nil)))
4248 :format "%t\n%v"
4249 :inline t
4250 (const :format "" pop-up-window)
4251 (set
4252 :format "%v"
4253 :inline t
4254 ;; Pop-up window list.
4255 (list
4256 :format "%v"
4257 :value (pop-up-window (largest . nil) (lru . nil))
4258 (const :format "" pop-up-window)
4259 (repeat
4260 :tag "Window / Side tuples"
4261 :inline t
4262 (cons
4263 :format "%v\n"
4264 (choice
4265 :tag "Window"
4266 :help-echo "The window to split."
4267 :value largest
4268 :format "%[Window%] %v"
4269 (const :tag "Largest" :format "%t" largest)
4270 (const :tag "Least recently used" :format "%t" lru)
4271 (const :tag "Selected" :format "%t" selected)
4272 (const :tag "Root" :format "%t" root)
4273 (const :tag "Left" :format "%t" left)
4274 (const :tag "Top" :format "%t" top)
4275 (const :tag "Right" :format "%t" right)
4276 (const :tag "Bottom" :format "%t" bottom))
4277 (choice
4278 :tag "Side"
4279 :help-echo "The position of the new window with respect to the window to split."
4280 :value nil
4281 :format " %[Side%] %v"
4282 (const :tag "Dynamic" :format "%t" nil)
4283 (const :tag "Below" :format "%t" below)
4284 (const :tag "Right" :format "%t" right)
4285 (const :tag "Above" :format "%t" above)
4286 (const :tag "Left" :format "%t" left)
4287 (function
4288 :tag "Function" :format "%v" :size 25)))))
4289 ;; Minimum height of pop-up windows.
4290 (cons
4291 :format "%v\n"
4292 (const :format "" pop-up-window-min-height)
4293 (choice
4294 :help-echo "Minimum height of popped-up window."
4295 :format "%[Minimum height%] %v"
4296 (const :tag "Default" :format "%t" :value nil)
4297 (integer :tag "Number of lines" :value 12 :size 5)
4298 (float :tag "Fraction of frame height" :value .25 :size 5)))
4299 ;; Minimum width of pop-up windows.
4300 (cons
4301 :format "%v\n"
4302 (const :format "" pop-up-window-min-width)
4303 (choice
4304 :help-echo "Minimum width of popped-up window."
4305 :format "%[Minimum width%] %v"
4306 (const :tag "Default" :format "%t" :value nil)
4307 (integer :tag "Number of columns" :value 12 :size 5)
4308 (float :tag "Fraction of frame width" :value .25 :size 5)))
4309 ;; Desired height of pop-up windows.
4310 (cons
4311 :format "%v\n"
4312 (const :format "" pop-up-window-set-height)
4313 (choice
4314 :help-echo "Desired height of popped-up window."
4315 :format "%[Desired height%] %v"
4316 (const :tag "Default" :format "%t" :value nil)
4317 (integer :tag "Number of lines" :value 12 :size 5)
4318 (float :tag "Fraction of frame height" :value .25 :size 5)
4319 (function :tag "Function" :size 25)))
4320 ;; Desired width of pop-up windows.
4321 (cons
4322 :format "%v\n"
4323 (const :format "" pop-up-window-set-width)
4324 (choice
4325 :help-echo "Desired width of popped-up window."
4326 :format "%[Desired width%] %v"
4327 (const :tag "Default" :format "%t" :value nil)
4328 (integer :tag "Number of column" :value 12 :size 5)
4329 (float :tag "Fraction of frame width" :value .25 :size 5)
4330 (function :tag "Function" :size 25)))
4331 ;; Split unsplittable frames.
4332 (cons
4333 :format "%v\n"
4334 (const :format "" pop-up-window-unsplittable)
4335 (choice
4336 :help-echo "Allow popping up a window on \"unsplittable\" frames."
4337 :format "%[Split unsplittable frame%] %v"
4338 (const :tag "Off" :format "%t" nil)
4339 (const :tag "Allow" :format "%t" t)))))
4340
4341 ;; Pop-up frame specifiers.
4342 (list
4343 :tag "Pop-up frame"
4344 :value (pop-up-frame
4345 (pop-up-frame))
4346 :format "%t\n%v"
4347 :inline t
4348 (const :format "" pop-up-frame)
4349 (set
4350 :format "%v"
4351 :inline t
4352 ;; Pop-up frame.
4353 (list
4354 :tag "Pop-up a new frame"
4355 :value (pop-up-frame)
4356 :format "%v"
4357 (const :format "" pop-up-frame)
4358 (choice
4359 :tag "Pop-up a new frame"
4360 :help-echo "Whether to pop-up a new frame on a display."
4361 :format "%[Display%] %v\n" :size 15
4362 (const :tag "On any display" :format "%t" nil)
4363 (const :tag "On graphic displays only" :format "%t" t)))
4364 ;; Pop-up frame function.
4365 (cons
4366 :format "%v\n"
4367 (const :format "" pop-up-frame-function)
4368 (choice
4369 :tag "Pop-up frame function"
4370 :value nil
4371 :help-echo "Function to use to pop-up a new frame."
4372 :format "%[Function%] %v" :size 15
4373 (const :tag "Default" :format "%t" nil)
4374 (function
4375 :value make-frame
4376 :format "%t: %v"
4377 :size 25)))
4378 ;; Pop-up frame alist.
4379 (list
4380 :format "%v"
4381 (const :format "" pop-up-frame-alist)
4382 (repeat
4383 :tag "Parameter / Value tuples"
4384 :inline t
4385 (cons
4386 :format "%v\n"
4387 (symbol
4388 :tag "Parameter"
4389 :format "Parameter: %v"
4390 :size 16)
4391 (sexp
4392 :tag "Value"
4393 :format " Value: %v"
4394 :size 8))))))
4395
4396 ;; Use side-window specifiers.
4397 (list
4398 :tag "Use side-window"
4399 :value (use-side-window (use-side-window bottom 0))
4400 :format "%t\n%v"
4401 :inline t
4402 ;; For customization purposes only.
4403 (const :format "" use-side-window)
4404 (set
4405 :format "%v"
4406 :inline t
4407 ;; Side and slot.
4408 (list
4409 :format "%v\n"
4410 :value (use-side-window bottom 0)
4411 (const :format "" use-side-window)
4412 ;; The side.
4413 (choice
4414 :tag "Side"
4415 :help-echo "Side of frame."
4416 :value bottom
4417 :format "%[Side%] %v" :size 15
4418 (const :tag "Left" :format "%t" left)
4419 (const :tag "Top" :format "%t" top)
4420 (const :tag "Right" :format "%t" right)
4421 (const :tag "Bottom" :format "%t" bottom))
4422 ;; The slot
4423 (number
4424 :tag "Slot"
4425 :help-echo "The slot (an arbitrary number, where 0 stands for the center slot)."
4426 :value 0
4427 :format " Slot: %v" :size 8))
4428 ;; Whether to reuse a dedicated side window
4429 (cons
4430 :format "%v\n"
4431 (const :format "" reuse-window-dedicated)
4432 (choice
4433 :tag "Reuse dedicated side window" :value nil
4434 :help-echo "Reuse a side window even if it is dedicated to its buffer."
4435 :format "%[Reuse dedicated side window%] %v" :size 15
4436 (const :tag "Off" :format "%t" nil)
4437 (const :tag "Reuse weakly dedicated side windows" :format "%t" weak)
4438 (const :tag "Reuse any dedicated side window" :format "%t" t)))
4439 ;; Minimum height of pop-up side windows.
4440 (cons
4441 :format "%v\n"
4442 (const :format "" pop-up-window-min-height)
4443 (choice
4444 :help-echo "Minimum height of popped-up side window."
4445 :format "%[Minimum height%] %v"
4446 (const :tag "Default" :format "%t" :value nil)
4447 (integer :tag "Number of lines" :value 12 :size 5)
4448 (float :tag "Fraction of frame height" :value .25 :size 5)))
4449 ;; Minimum width of pop-up windows.
4450 (cons
4451 :format "%v\n"
4452 (const :format "" pop-up-window-min-width)
4453 (choice
4454 :help-echo "Minimum width of popped-up side window."
4455 :format "%[Minimum width%] %v"
4456 (const :tag "Default" :format "%t" :value nil)
4457 (integer :tag "Number of columns" :value 12 :size 5)
4458 (float :tag "Fraction of frame width" :value .25 :size 5)))
4459 ;; Desired height of pop-up windows.
4460 (cons
4461 :format "%v\n"
4462 (const :format "" pop-up-window-set-height)
4463 (choice
4464 :help-echo "Desired height of popped-up side window."
4465 :format "%[Desired height%] %v"
4466 (const :tag "Default" :format "%t" :value nil)
4467 (integer :tag "Number of lines" :value 12 :size 5)
4468 (float :tag "Fraction of frame height" :value .25 :size 5)
4469 (function :tag "Function" :size 25)))
4470 ;; Desired width of pop-up windows.
4471 (cons
4472 :format "%v\n"
4473 (const :format "" pop-up-window-set-width)
4474 (choice
4475 :help-echo "Desired width of popped-up side window."
4476 :format "%[Desired width%] %v"
4477 (const :tag "Default" :format "%t" :value nil)
4478 (integer :tag "Number of column" :value 12 :size 5)
4479 (float :tag "Fraction of frame width" :value .25 :size 5)
4480 (function :tag "Function" :size 25)))))
4481
4482 ;; Function with argument specifiers.
4483 (list
4484 :tag "Function with arguments"
4485 :value (function (function 'ignore))
4486 :format "%t\n%v"
4487 :inline t
4488 ;; For customization purposes only.
4489 (const :format "" function)
4490 (set
4491 :format "%v"
4492 :inline t
4493 (list
4494 :format "%v"
4495 :value (function 'ignore)
4496 (const :format "" function)
4497 (function :tag "Function" :format "%t: %v\n" :size 25)
4498 (list
4499 :format "%v"
4500 (repeat
4501 :tag "Arguments"
4502 :inline t
4503 (sexp
4504 :format "%v\n"
4505 :size 16))))))
4506
4507 ;; Macro specifiers.
4508 (list
4509 :tag "Same window"
4510 :format "%t%v"
4511 :inline t
4512 (const :format "\n" same-window))
4513 (list
4514 :tag "Same frame"
4515 :format "%t%v"
4516 :inline t
4517 (const :format "\n" same-frame))
4518 (list
4519 :tag "Other window"
4520 :format "%t%v"
4521 :inline t
4522 (const :format "\n" other-window))
4523 (list
4524 :tag "Same frame other window"
4525 :format "%t%v"
4526 :inline t
4527 (const :format "\n" same-frame-other-window))
4528 (list
4529 :tag "Other frame"
4530 :format "%t%v"
4531 :inline t
4532 (const :format "\n" other-frame))
4533 (list
4534 :tag "Default"
4535 :format "%t%v"
4536 :inline t
4537 (const :format "\n" default)))))
4538
4539 (set
4540 :format "%v"
4541 :inline t
4542 ;; Dedicate window to buffer.
4543 (cons
4544 :format "%v"
4545 (const :format "" dedicate)
4546 (choice
4547 :help-echo "Mark window as dedicated to its buffer."
4548 :format "%[Dedicate window to buffer%] %v\n" :size 15
4549 (const :tag "Off" :format "%t" nil)
4550 (const :tag "Weak" :format "%t" weak)
4551 (const :tag "Strong" :format "%t" t)))
4552 ;; No other window.
4553 (cons
4554 :format "%v"
4555 (const :format "" no-other-window)
4556 (choice
4557 :help-echo "Whether `other-window' shall ignore the window."
4558 :format "%[No other window%] %v\n" :size 15
4559 (const :tag "Off" :format "%t" nil)
4560 (const :tag "Ignore" :format "%t" t)))
4561 ;; Other window means other frame.
4562 (cons
4563 :format "%v"
4564 (const :format "" other-window-means-other-frame)
4565 (choice
4566 :help-echo "Whether other window means same or other frame."
4567 :format "%[Other window means other frame%] %v\n" :size 15
4568 (const :tag "Off" :format "%t" nil)
4569 (const :tag "On" :format "%t" t)))
4570 ;; Overriding.
4571 (cons
4572 :format "%v\n"
4573 (const :format "" override)
4574 (choice
4575 :help-echo "Override application supplied specifiers."
4576 :format "%[Override%] %v"
4577 (const :tag "Off" :format "%t" nil)
4578 (const :tag "Override" :format "%t" t))))))
4579 :group 'windows
4580 :group 'frames)
4581
4582(defcustom display-buffer-function nil
4583 "If non-nil, function to call to display a buffer.
4584`display-buffer' calls this function with two arguments, the
4585buffer to display and a list of buffer display specifiers, see
4586`display-buffer-alist'.
4587
4588The function is supposed to choose or create a window, display
4589the specified buffer in it, and return the window. It is also
4590responsible for giving the variable `display-buffer-window' and
4591the `quit-restore' parameter of the window used a meaningful
4592value.
4593
4594The function specified here overrides all specifiers of the
4595variable `display-buffer-alist' any specifiers passed to
4596`display-buffer'.
4597
4598If you call `display-buffer' within the body of the function,
4599bind the value of `display-buffer-function' to nil around that
4600call to avoid that the function recursively calls itself."
4601 :type '(choice
4602 (const nil)
4603 (function :tag "Function"))
4604 :group 'windows)
4605
4606;; The following is a global variable which is used externally (by
4607;; help.el) to (1) know which window was used for displaying a buffer
4608;; and (2) whether the window was new or reused.
4609(defvar display-buffer-window nil 3825(defvar display-buffer-window nil
4610 "Window used by `display-buffer' and related information. 3826 "Window used by `display-buffer' and related information.
4611After `display-buffer' displays a buffer in some window this 3827After `display-buffer' displays a buffer in some window this
@@ -4614,1585 +3830,88 @@ display the buffer. The cdr is supposed to be one of the symbols
4614`reuse-buffer-window', `reuse-other-window', `new-window' or 3830`reuse-buffer-window', `reuse-other-window', `new-window' or
4615`new-frame'. 3831`new-frame'.
4616 3832
4617If the buffer display location specifier is one of 'same-window, 3833See the function `display-buffer-record-window' for how this
4618'same-frame, or 'other-frame, the `display-buffer' routines 3834variable can be assigned a value.")
4619assign the value of this variable. If the location specifier is
4620a function, that function becomes responsible for assigning a
4621meaningful value to this variable. See the functions
4622`display-buffer-reuse-window', `display-buffer-pop-up-window' and
4623`display-buffer-pop-up-frame' for how this can be done.")
4624
4625(defun display-buffer-even-window-sizes (window specifiers)
4626 "Even sizes of WINDOW and selected window according to SPECIFIERS.
4627SPECIFIERS must be a list of buffer display specifiers, see the
4628documentation of `display-buffer-alist' for a description.
4629
4630Sizes are evened out if and only if WINDOW and the selected
4631window appear next to each other and the selected window is
4632larger than WINDOW."
4633 (cond
4634 ((or (not (cdr (assq 'reuse-window-even-sizes specifiers)))
4635 ;; Don't resize minibuffer windows.
4636 (window-minibuffer-p)
4637 ;; WINDOW must be adjacent to the selected one.
4638 (not (or (eq window (window-prev-sibling))
4639 (eq window (window-next-sibling))))))
4640 ((and (window-iso-combined-p window)
4641 ;; Resize iff the selected window is higher than WINDOW.
4642 (> (window-total-height) (window-total-height window)))
4643 ;; Don't throw an error if we can't even window heights for
4644 ;; whatever reason. In any case, enlarging the selected window
4645 ;; might fail anyway if there are other windows above or below
4646 ;; WINDOW and the selected one. But for a simple two windows
4647 ;; configuration the present behavior is good enough so why care?
4648 (ignore-errors
4649 (window-resize
4650 window (/ (- (window-total-height) (window-total-height window))
4651 2))))
4652 ((and (window-iso-combined-p window t)
4653 ;; Resize iff the selected window is wider than WINDOW.
4654 (> (window-total-width) (window-total-width window)))
4655 ;; Don't throw an error if we can't even window widths, see
4656 ;; comment above.
4657 (ignore-errors
4658 (window-resize
4659 window (/ (- (window-total-width) (window-total-width window))
4660 2) t)))))
4661
4662(defun display-buffer-set-height (window specifiers)
4663 "Adjust height of WINDOW according to SPECIFIERS.
4664SPECIFIERS must be a list of buffer display specifiers, see the
4665documentation of `display-buffer-alist' for a description."
4666 (let ((set-height (cdr (assq 'pop-up-window-set-height specifiers))))
4667 (cond
4668 ((numberp set-height)
4669 (let* ((height (if (integerp set-height)
4670 set-height
4671 (round
4672 (* (window-total-size (frame-root-window window))
4673 set-height))))
4674 (delta (- height (window-total-size window))))
4675 (when (and (window-resizable-p window delta nil 'safe)
4676 (window-iso-combined-p window))
4677 (window-resize window delta nil 'safe))))
4678 ((functionp set-height)
4679 (ignore-errors (funcall set-height window))))))
4680
4681(defun display-buffer-set-width (window specifiers)
4682 "Adjust width of WINDOW according to SPECIFIERS.
4683SPECIFIERS must be a list of buffer display specifiers, see the
4684documentation of `display-buffer-alist' for a description."
4685 (let ((set-width (cdr (assq 'pop-up-window-set-width specifiers))))
4686 (cond
4687 ((numberp set-width)
4688 (let* ((width (if (integerp set-width)
4689 set-width
4690 (round
4691 (* (window-total-size (frame-root-window window) t)
4692 set-width))))
4693 (delta (- width (window-total-size window t))))
4694 (when (and (window-resizable-p window delta t 'safe)
4695 (window-iso-combined-p window t))
4696 (window-resize window delta t 'safe))))
4697 ((functionp set-width)
4698 (ignore-errors (funcall set-width window))))))
4699
4700(defun display-buffer-in-window (buffer window specifiers)
4701 "Display BUFFER in WINDOW and raise its frame if needed.
4702WINDOW must be a live window and defaults to the selected one.
4703Return WINDOW.
4704
4705SPECIFIERS must be a list of buffer display specifiers, see the
4706documentation of `display-buffer-alist' for a description."
4707 (setq buffer (window-normalize-buffer buffer))
4708 (setq window (window-normalize-live-window window))
4709 (let* ((old-frame (selected-frame))
4710 (new-frame (window-frame window))
4711 (no-other-window (cdr (assq 'no-other-window specifiers))))
4712 ;; Show BUFFER in WINDOW.
4713 (unless (eq buffer (window-buffer window))
4714 ;; If we show another buffer in WINDOW, undedicate it first.
4715 (set-window-dedicated-p window nil))
4716 (set-window-buffer window buffer)
4717 (when no-other-window
4718 (set-window-parameter window 'no-other-window t))
4719 (unless (or (eq old-frame new-frame)
4720 (not (frame-visible-p new-frame))
4721 ;; Assume the selected frame is already visible enough.
4722 (eq new-frame (selected-frame))
4723 ;; Assume the frame from which we invoked the minibuffer
4724 ;; is visible.
4725 (and (minibuffer-window-active-p (selected-window))
4726 (eq new-frame
4727 (window-frame (minibuffer-selected-window)))))
4728 (raise-frame new-frame))
4729 ;; Return window.
4730 window))
4731 3835
4732(defun display-buffer-reuse-window (buffer method &optional specifiers other-window) 3836(defun display-buffer-record-window (type window buffer)
4733 "Display BUFFER in an existing window. 3837 "Record information for window used by `display-buffer'.
4734METHOD must be a list in the form of the cdr of a `reuse-window' 3838TYPE must be one of the symbols reuse-window, pop-up-window, or
4735buffer display specifier, see `display-buffer-alist' for an 3839pop-up-frame. WINDOW is the window used for or created by the
4736explanation. The first element must specifiy the window to use, 3840`display-buffer' routines. BUFFER is the buffer that shall be
4737and can be either nil, `same', `other', or a live window. The 3841displayed."
4738second element must specify the window's buffer and can be either 3842 (cond
4739nil, `same', `other', or a live buffer. The third element is the 3843 ((eq type 'reuse-window)
4740frame to use - either nil, 0, `visible', `other', t, or a live 3844 ;; In `display-buffer-window' record whether we used a window on the
4741frame. 3845 ;; same buffer or another one.
4742 3846 (if (eq (window-buffer window) buffer)
4743Optional argument SPECIFIERS must be a list of valid display
4744specifiers. Optional argument OTHER-WINDOW, if non-nil, means do
4745not use the selected window. Return the window chosen to display
4746BUFFER, nil if none was found."
4747 (let* ((method-window (nth 0 method))
4748 (method-buffer (nth 1 method))
4749 (method-frame (nth 2 method))
4750 (reuse-dedicated (cdr (assq 'reuse-window-dedicated specifiers)))
4751 windows other-frame dedicated time best-window best-time)
4752 (when (eq method-frame 'other)
4753 ;; `other' is not handled by `window-list-1'.
4754 (setq other-frame t)
4755 (setq method-frame t))
4756 (dolist (window (window-list-1 nil 'nomini method-frame))
4757 (let ((window-buffer (window-buffer window)))
4758 (when (and (not (window-minibuffer-p window))
4759 ;; Don't reuse a side window unless it shows the
4760 ;; buffer already.
4761 (or (memq (window-parameter window 'window-side)
4762 '(nil none))
4763 (eq window-buffer buffer))
4764 (or (and (not method-window)
4765 (or (not other-window)
4766 (not (eq window (selected-window)))))
4767 (and (eq method-window 'same)
4768 (not other-window)
4769 (eq window (selected-window)))
4770 (and (eq method-window 'other)
4771 (not (eq window (selected-window))))
4772 ;; Special case for applications that specifiy
4773 ;; the window explicitly.
4774 (eq method-window window))
4775 (or (not method-buffer)
4776 (and (eq method-buffer 'same)
4777 (eq window-buffer buffer))
4778 (and (eq method-buffer 'other)
4779 (not (eq window-buffer buffer)))
4780 ;; Special case for applications that specifiy
4781 ;; the window's buffer explicitly.
4782 (eq method-buffer window-buffer))
4783 (or (not other-frame)
4784 (not (eq (window-frame window) (selected-frame))))
4785 ;; Handle dedicatedness.
4786 (or (eq window-buffer buffer)
4787 ;; The window does not show the same buffer.
4788 (not (setq dedicated (window-dedicated-p window)))
4789 ;; If the window is weakly dedicated to its
4790 ;; buffer, reuse-dedicated must be non-nil.
4791 (and (not (eq dedicated t)) reuse-dedicated)
4792 ;; If the window is strongly dedicated to its
4793 ;; buffer, reuse-dedicated must be t.
4794 (eq reuse-dedicated t)))
4795 (setq windows (cons window windows)))))
4796
4797 (if (eq method-buffer 'same)
4798 ;; When reusing a window on the same buffer use the lru one.
4799 (dolist (window windows)
4800 (setq time (window-use-time window))
4801 (when (or (not best-window) (< time best-time))
4802 (setq best-window window)
4803 (setq best-time time)))
4804 ;; Otherwise, sort windows according to their use-time.
4805 (setq windows
4806 (sort windows
4807 #'(lambda (window-1 window-2)
4808 (<= (window-use-time window-1)
4809 (window-use-time window-2)))))
4810 (setq best-window
4811 ;; Try to get a full-width window (this is silly and can
4812 ;; get us to another frame but let's ignore these issues
4813 ;; for the moment).
4814 (catch 'found
4815 (dolist (window windows)
4816 (when (window-full-width-p window)
4817 (throw 'found window)))
4818 ;; If there's no full-width window return the lru window.
4819 (car windows))))
4820
4821 (when best-window
4822 (display-buffer-even-window-sizes best-window specifiers)
4823 ;; Never change the quit-restore parameter of a window here.
4824 (if (eq (window-buffer best-window) buffer)
4825 (setq display-buffer-window
4826 (cons best-window 'reuse-buffer-window))
4827 (setq display-buffer-window 3847 (setq display-buffer-window
4828 (cons best-window 'reuse-other-window)) 3848 (cons window 'reuse-buffer-window))
4829 (unless (window-parameter best-window 'quit-restore) 3849 (setq display-buffer-window
4830 ;; Don't overwrite an existing quit-restore entry. 3850 (cons window 'reuse-other-window)))
4831 (set-window-parameter 3851 ;; In quit-restore parameter record information about the old buffer
4832 best-window 'quit-restore 3852 ;; unless such information exists already.
4833 (list (window-buffer best-window) (window-start best-window) 3853 (unless (window-parameter window 'quit-restore)
4834 (window-point best-window) buffer
4835 (window-total-size best-window) (selected-window)))))
4836
4837 (display-buffer-in-window buffer best-window specifiers))))
4838
4839(defconst display-buffer-split-specifiers '(largest lru selected root left top right bottom)
4840 "List of symbols identifying window that shall be split.")
4841
4842(defconst display-buffer-side-specifiers '(below right above left nil)
4843 "List of symbols identifying side of split-off window.")
4844
4845(defun display-buffer-split-window-1 (window side min-size)
4846 "Subroutine of `display-buffer-split-window'."
4847 (let* ((horizontal (memq side '(left right)))
4848 (parent (window-parent window))
4849 (resize (and window-splits (window-iso-combined-p window horizontal)))
4850 (old-size
4851 ;; We either resize WINDOW or its parent.
4852 (window-total-size (if resize parent window) horizontal))
4853 new-size)
4854 ;; We don't call split-window-vertically/-horizontally any more
4855 ;; here. If for some reason it's needed we can always do so
4856 ;; (provided we give it an optional SIDE argument).
4857 (cond
4858 (resize
4859 ;; When we resize a combination, the new window must be at least
4860 ;; MIN-SIZE large after the split.
4861 (setq new-size
4862 (max min-size
4863 (min (- old-size (window-min-size parent horizontal))
4864 (/ old-size
4865 ;; Try to make the size of the new window
4866 ;; proportional to the number of iso-arranged
4867 ;; windows in the combination.
4868 (1+ (window-iso-combinations parent horizontal))))))
4869 (when (window-sizable-p parent (- new-size) horizontal)
4870 (split-window window (- new-size) side)))
4871 ((window-live-p window)
4872 (setq new-size (/ old-size 2))
4873 ;; When WINDOW is live, the old _and_ the new window must be at
4874 ;; least MIN-SIZE large after the split.
4875 (when (and (>= new-size min-size)
4876 (window-sizable-p window (- new-size) horizontal))
4877 ;; Do an even split to make Stepan happy.
4878 (split-window window nil side)))
4879 (t
4880 ;; When WINDOW is internal, the new window must be at least
4881 ;; MIN-SIZE large after the split.
4882 (setq new-size
4883 (max min-size
4884 (/ old-size
4885 ;; Try to make the size of the new window
4886 ;; proportional to the number of iso-arranged
4887 ;; subwindows of WINDOW.
4888 (1+ (window-iso-combinations window horizontal)))))
4889 (when (window-sizable-p window (- new-size) horizontal)
4890 (split-window window (- new-size) side))))))
4891
4892(defun display-buffer-split-window (window &optional side specifiers)
4893 "Split WINDOW in a way suitable for `display-buffer'.
4894Optional argument SIDE must be a side specifier \(one of the
4895symbols below, right, above, left, or nil). SPECIFIERS must be a
4896list of buffer display specifiers, see the documentation of
4897`display-buffer-alist' for a description.
4898
4899Return the new window, nil if it could not be created."
4900 (let ((min-height (cdr (assq 'pop-up-window-min-height specifiers)))
4901 (min-width (cdr (assq 'pop-up-window-min-width specifiers)))
4902 size)
4903 ;; Normalize min-height and min-width, we might need both.
4904 (setq min-height
4905 ;; If min-height is specified, it can be as small as
4906 ;; `window-safe-min-height'.
4907 (cond
4908 ((and (integerp min-height)
4909 (>= min-height window-safe-min-height))
4910 min-height)
4911 ((and (floatp min-height)
4912 (<= min-height 1)
4913 (let* ((root-height (window-total-height
4914 (frame-root-window
4915 (window-frame window))))
4916 (height (round (* min-height root-height))))
4917 (when (>= height window-safe-min-height)
4918 height))))
4919 (t window-min-height)))
4920 (setq min-width
4921 ;; If min-width is specified, it can be as small as
4922 ;; `window-safe-min-width'.
4923 (cond
4924 ((and (integerp min-width)
4925 (>= min-width window-safe-min-width))
4926 min-width)
4927 ((and (floatp min-width)
4928 (<= min-width 1)
4929 (let* ((root-width (window-total-width
4930 (frame-root-window
4931 (window-frame window))))
4932 (width (round (* min-width root-width))))
4933 (when (>= width window-safe-min-width)
4934 width))))
4935 (t window-min-width)))
4936
4937 (or (and (memq side '(nil above below))
4938 (display-buffer-split-window-1
4939 window (or side 'below) min-height))
4940 ;; If SIDE is nil and vertical splitting failed, we try again
4941 ;; splitting horizontally this time.
4942 (and (memq side '(nil left right))
4943 (display-buffer-split-window-1
4944 window (or side 'right) min-width))
4945 ;; If WINDOW is live and the root window of its frame, try once
4946 ;; more splitting vertically, disregarding the min-height
4947 ;; specifier this time and using `window-min-height' instead.
4948 (and (memq side '(nil above below))
4949 (<= window-min-height min-height)
4950 (window-live-p window)
4951 (eq window (frame-root-window window))
4952 (display-buffer-split-window-1
4953 window (or side 'below) window-min-height)))))
4954
4955(defun display-buffer-split-atom-window (window &optional side nest specifiers)
4956 "Make WINDOW part of an atomic window."
4957 (let ((ignore-window-parameters t)
4958 (window-nest t)
4959 (selected-window (selected-window))
4960 root new new-parent)
4961
4962 ;; We are in an atomic window.
4963 (when (and (window-parameter window 'window-atom) (not nest))
4964 ;; Split the root window.
4965 (setq window (window-atom-root window)))
4966
4967 (when (setq new (display-buffer-split-window window side specifiers))
4968 (setq new-parent (window-parent window))
4969 ;; WINDOW is or becomes atomic.
4970 (unless (window-parameter window 'window-atom)
4971 (walk-window-subtree
4972 (lambda (window)
4973 (set-window-parameter window 'window-atom t))
4974 window t))
4975 ;; New window and any new parent get their window-atom parameter
4976 ;; set too.
4977 (set-window-parameter new 'window-atom t)
4978 (set-window-parameter new-parent 'window-atom t)
4979 new)))
4980
4981(defun display-buffer-pop-up-window (buffer methods &optional specifiers)
4982 "Display BUFFER in a new window.
4983Return the window displaying BUFFER, nil if popping up the window
4984failed. METHODS must be a list of window/side tuples like those
4985forming the cdr of the `pop-up-window' buffer display specifier.
4986As a special case, the car of such a tuple can be also a live
4987window.
4988
4989Optional argument SPECIFIERS must be a list of buffer display
4990specifiers, see the doc-string of `display-buffer-alist' for a
4991description."
4992 (let* ((frame (display-buffer-frame))
4993 (selected-window (frame-selected-window frame))
4994 cand window side atomic)
4995 (unless (and (cdr (assq 'unsplittable (frame-parameters frame)))
4996 ;; Don't split an unsplittable frame unless
4997 ;; SPECIFIERS allow it.
4998 (not (cdr (assq 'split-unsplittable-frame specifiers))))
4999 (catch 'done
5000 (dolist (method methods)
5001 (setq cand (car method))
5002 (setq side (cdr method))
5003 (setq window
5004 (cond
5005 ((eq cand 'largest)
5006 ;; The largest window.
5007 (get-largest-window frame t))
5008 ((eq cand 'lru)
5009 ;; The least recently used window.
5010 (get-lru-window frame t))
5011 ((eq cand 'selected)
5012 ;; The selected window.
5013 (frame-selected-window frame))
5014 ((eq cand 'root)
5015 ;; If there are side windows, split the main window
5016 ;; else the frame's root window.
5017 (or (window-with-parameter 'window-side 'none nil t)
5018 (frame-root-window frame)))
5019 ((memq cand window-sides)
5020 ;; This should gets us the "root" side window if there
5021 ;; exists more than one window on that side.
5022 (window-with-parameter 'window-side cand nil t))
5023 ((windowp cand)
5024 ;; A window, directly specified.
5025 cand)))
5026
5027 (when (and (window-any-p window)
5028 ;; The window must be on the correct frame,
5029 (eq (window-frame window) frame)
5030 ;; and must be neither a minibuffer window
5031 (not (window-minibuffer-p window))
5032 ;; nor a side window.
5033 (memq (window-parameter window 'window-side)
5034 '(nil none)))
5035 (setq window
5036 (cond
5037 ((memq side display-buffer-side-specifiers)
5038 (if (and (window-buffer window)
5039 (setq atomic (cdr (assq 'atomic specifiers))))
5040 (display-buffer-split-atom-window
5041 window side (eq atomic 'nest) specifiers)
5042 (display-buffer-split-window window side specifiers)))
5043 ((functionp side)
5044 (ignore-errors
5045 ;; Don't pass any specifiers to this function.
5046 (funcall side window)))))
5047
5048 (when (window-live-p window)
5049 ;; In `quit-restore' parameter record that we popped up
5050 ;; this window, its buffer and which window was selected.
5051 (set-window-parameter
5052 window 'quit-restore (list 'new-window buffer selected-window))
5053 ;; For `display-buffer-window' mark window as new.
5054 (setq display-buffer-window (cons window 'new-window))
5055 ;; Install BUFFER in the new window.
5056 (display-buffer-in-window buffer window specifiers)
5057 (let ((dedicate (cdr (assq 'dedicate specifiers))))
5058 (when dedicate
5059 ;; Dedicate window to buffer.
5060 (set-window-dedicated-p window dedicate)))
5061 ;; Adjust sizes if asked for (for `fit-window-to-buffer'
5062 ;; and friends BUFFER must be already shown in the new
5063 ;; window).
5064 (display-buffer-set-height window specifiers)
5065 (display-buffer-set-width window specifiers)
5066 ;; Reset list of window's previous buffers to nil.
5067 (set-window-prev-buffers window nil)
5068 ;; Return the new window.
5069 (throw 'done window))))))))
5070
5071(defun display-buffer-pop-up-frame (buffer &optional graphic-only specifiers)
5072 "Make a new frame for displaying BUFFER.
5073Return the window displaying BUFFER if creating the new frame was
5074successful, nil otherwise. Optional argument GRAPHIC-ONLY
5075non-nil means to make a new frame on graphic displays only.
5076
5077SPECIFIERS must be a list of buffer display specifiers, see the
5078documentation of `display-buffer-alist' for a description."
5079 (unless (or (and graphic-only (not (display-graphic-p)))
5080 noninteractive)
5081 (let* ((selected-window (selected-window))
5082 (function (or (cdr (assq 'pop-up-frame-function specifiers))
5083 'make-frame))
5084 (parameters
5085 (when (symbolp function)
5086 (cdr (assq 'pop-up-frame-alist specifiers))))
5087 (frame
5088 (with-current-buffer buffer
5089 (if (symbolp function)
5090 (funcall function parameters)
5091 (funcall function)))))
5092 (when frame
5093 (let ((window (frame-selected-window frame)))
5094 (set-window-parameter
5095 window 'quit-restore (list 'new-frame buffer selected-window))
5096 (setq display-buffer-window (cons window 'new-frame))
5097 (display-buffer-in-window buffer window specifiers)
5098 (let ((dedicate (cdr (assq 'dedicate specifiers))))
5099 (when dedicate
5100 ;; Dedicate window to buffer.
5101 (set-window-dedicated-p window dedicate)))
5102 window)))))
5103
5104(defun display-buffer-pop-up-side-window (buffer side slot &optional specifiers)
5105 "Display BUFFER in a new window on SIDE of the selected frame.
5106SLOT specifies the slot to use. SPECIFIERS must be a list of
5107buffer display specifiers.
5108
5109Return the window displaying BUFFER, nil if popping up the window
5110failed."
5111 (let* ((root (frame-root-window))
5112 (main (window-with-parameter 'window-side 'none nil t))
5113 (left-or-right (memq side '(left right)))
5114 (main-or-root
5115 (if (and main
5116 (or (and left-or-right (not window-sides-vertical))
5117 (and (not left-or-right) window-sides-vertical)))
5118 main
5119 root))
5120 (selected-window (selected-window))
5121 (on-side (cond
5122 ((eq side 'top) 'above)
5123 ((eq side 'bottom) 'below)
5124 (t side)))
5125 (window
5126 (display-buffer-split-window main-or-root on-side specifiers))
5127 fun)
5128 (when window
5129 ;; We were able to split off a new window.
5130 (unless main
5131 (walk-window-subtree
5132 (lambda (window)
5133 ;; Make all main-or-root subwindows main windows.
5134 (set-window-parameter window 'window-side 'none))
5135 main-or-root t))
5136 ;; Reset window-side parameter of new window's parent to nil.
5137 (set-window-parameter (window-parent window) 'window-side nil)
5138 ;; Initialize window-side parameter of new window to SIDE.
5139 (set-window-parameter window 'window-side side)
5140 ;; Install window-slot parameter of new window.
5141 (set-window-parameter window 'window-slot slot)
5142 ;; In `quit-restore' parameter record that we popped up a new
5143 ;; window.
5144 (set-window-parameter 3854 (set-window-parameter
5145 window 'quit-restore (list 'new-window buffer selected-window)) 3855 window 'quit-restore
5146 ;; For `display-buffer-window' mark window as new. 3856 (list (window-buffer window) (window-start window)
5147 (setq display-buffer-window (cons window 'new-window)) 3857 (window-point window) buffer
5148 ;; Install BUFFER in new window. 3858 (window-total-size window) (selected-window)))))
5149 (display-buffer-in-window buffer window specifiers) 3859 ((eq type 'pop-up-window)
5150 (let ((dedicate (cdr (assq 'dedicate specifiers)))) 3860 ;; In `display-buffer-window' record window as new.
5151 (when dedicate 3861 (setq display-buffer-window (cons window 'new-window))
5152 ;; Dedicate window to buffer. 3862 ;; In `quit-restore' parameter record that we popped up this window,
5153 (set-window-dedicated-p window dedicate))) 3863 ;; its buffer, and which window was selected before.
5154 ;; Adjust sizes of new window if asked for. 3864 (set-window-parameter
5155 (display-buffer-set-height window specifiers) 3865 window 'quit-restore (list 'new-window buffer (selected-window))))
5156 (display-buffer-set-width window specifiers) 3866 ((eq type 'pop-up-frame)
5157 ;; Reset list of new window's previous buffers to nil. 3867 ;; In `display-buffer-window' record window as on new frame.
5158 (set-window-prev-buffers window nil) 3868 (setq display-buffer-window (cons window 'new-frame))
5159 ;; Return the new window. 3869 ;; In `quit-restore' parameter record that we popped up this window
5160 window))) 3870 ;; on a new frame, the buffer, and which window was selected before.
5161 3871 (set-window-parameter
5162(defun display-buffer-in-side-window (buffer side &optional slot specifiers) 3872 window 'quit-restore (list 'new-frame buffer (selected-window))))))
5163 "Display BUFFER in a window on SIDE of the selected frame.
5164SLOT, if non-nil, specifies the window slot where to display the
5165BUFFER. SLOT zero or nil means use the central slot on SIDE.
5166SLOT negative means use a slot preceding the central window.
5167SLOT positive means use a slot following the central window.
5168
5169SPECIFIERS must be a list of buffer display specifiers."
5170 (unless (memq side window-sides)
5171 (error "Invalid side %s specified" side))
5172 (let* ((major (window-with-parameter 'window-side side nil t))
5173 ;; `major' is the major window on SIDE, `windows' the life
5174 ;; windows on SIDE.
5175 (windows (when major (windows-with-parameter 'window-side side)))
5176 (reuse-dedicated (cdr (assq 'reuse-window-dedicated specifiers)))
5177 (slots (when major (window-child-count major)))
5178 (max-slots
5179 (nth (cond
5180 ((eq side 'left) 0)
5181 ((eq side 'top) 1)
5182 ((eq side 'right) 2)
5183 ((eq side 'bottom) 3))
5184 window-sides-slots))
5185 (selected-window (selected-window))
5186 window this-window this-slot prev-window next-window
5187 best-window best-slot abs-slot dedicated new-window)
5188
5189 (unless (numberp slot)
5190 (setq slot 0))
5191 (if (not windows)
5192 ;; No suitable side window exists, make one.
5193 (display-buffer-pop-up-side-window buffer side slot specifiers)
5194 ;; Scan windows on SIDE.
5195 (catch 'found
5196 (dolist (window windows)
5197 (setq this-slot (window-parameter window 'window-slot))
5198 (cond
5199 ((not (numberp this-slot)))
5200 ((and (= this-slot slot)
5201 ;; Dedicatedness check.
5202 (or (not (setq dedicated (window-dedicated-p window)))
5203 ;; If the window is weakly dedicated to its
5204 ;; buffer, reuse-dedicated must be non-nil.
5205 (and (not (eq dedicated t)) reuse-dedicated)
5206 ;; If the window is strongly dedicated to its
5207 ;; buffer, reuse-dedicated must be t.
5208 (eq reuse-dedicated t)))
5209 ;; Window with matching SLOT, use it.
5210 (setq this-window window)
5211 (throw 'found t))
5212 (t
5213 (setq abs-slot (abs (- (abs slot) (abs this-slot))))
5214 (unless (and best-slot (<= best-slot abs-slot))
5215 (setq best-window window)
5216 (setq best-slot abs-slot))
5217 (cond
5218 ((<= this-slot slot)
5219 (setq prev-window window))
5220 ((not next-window)
5221 (setq next-window window)))))))
5222
5223 ;; `this-window' is the first window with the same SLOT.
5224 ;; `prev-window' is the window with the largest slot < SLOT. A new
5225 ;; window will be created after it.
5226 ;; `next-window' is the window with the smallest slot > SLOT. A new
5227 ;; window will be created before it.
5228 ;; `best-window' is the window with the smallest absolute difference
5229 ;; of its slot and SLOT.
5230 (or (and this-window
5231 ;; Reuse this window.
5232 (prog1
5233 (setq window this-window)
5234 (if (eq (window-buffer window) buffer)
5235 (setq display-buffer-window
5236 (cons window 'reuse-buffer-window))
5237 (setq display-buffer-window
5238 (cons window 'reuse-other-window))
5239 (unless (window-parameter window 'quit-restore)
5240 ;; Don't overwrite an existing quit-restore entry.
5241 (set-window-parameter
5242 window 'quit-restore
5243 (list (window-buffer window) (window-start window)
5244 (window-point window) buffer
5245 (window-total-size window) (selected-window)))))))
5246 (and (or (not max-slots) (< slots max-slots))
5247 (or (and next-window
5248 ;; Make new window before next-window.
5249 (let ((next-side
5250 (if (memq side '(left right)) 'above 'left)))
5251 (setq window (display-buffer-split-window
5252 next-window next-side specifiers))))
5253 (and prev-window
5254 ;; Make new window after prev-window.
5255 (let ((prev-side
5256 (if (memq side '(left right)) 'below 'right)))
5257 (setq window (display-buffer-split-window
5258 prev-window prev-side specifiers)))))
5259 (progn
5260 ;; In `quit-restore' parameter record that we popped up
5261 ;; this window, its buffer and the old selected window.
5262 (set-window-parameter
5263 window 'quit-restore
5264 (list 'new-window buffer selected-window))
5265 ;; For `display-buffer-window' mark window as new.
5266 (setq display-buffer-window (cons window 'new-window))
5267 ;; Record that window is new, we need this for
5268 ;; adjusting sizes below.
5269 (setq new-window window)))
5270 (and best-window
5271 (setq window best-window)
5272 ;; Reuse best window (the window nearest to SLOT).
5273 (if (eq (window-buffer window) buffer)
5274 (setq display-buffer-window
5275 (cons window 'reuse-buffer-window))
5276 (setq display-buffer-window
5277 (cons window 'reuse-other-window))
5278
5279 (unless (window-parameter window 'quit-restore)
5280 ;; Don't overwrite an existing quit-restore entry.
5281 (set-window-parameter
5282 window 'quit-restore
5283 (list (window-buffer window) (window-start window)
5284 (window-point window) buffer
5285 (window-total-size window) (selected-window)))))
5286 window))
5287
5288 (when window
5289 (unless (window-parameter window 'window-slot)
5290 ;; Don't change exisiting slot value.
5291 (set-window-parameter window 'window-slot slot))
5292 ;; Install BUFFER in the window.
5293 (display-buffer-in-window buffer window specifiers)
5294 (let ((dedicate (cdr (assq 'dedicate specifiers))))
5295 (when dedicate
5296 ;; Dedicate window to buffer.
5297 (set-window-dedicated-p window dedicate)))
5298 (when new-window
5299 ;; Adjust sizes if asked for (for `fit-window-to-buffer' and
5300 ;; friends BUFFER must be already shown in the new window).
5301 (display-buffer-set-height window specifiers)
5302 (display-buffer-set-width window specifiers)
5303 ;; Reset list of new window's previous buffers to nil.
5304 (set-window-prev-buffers window nil))
5305 ;; Return the window used.
5306 window))))
5307
5308(defun window-normalize-buffer-to-display (buffer-or-name)
5309 "Normalize BUFFER-OR-NAME argument for buffer display functions.
5310If BUFFER-OR-NAME is nil, return the curent buffer. Else, if a
5311buffer specified by BUFFER-OR-NAME exists, return that buffer.
5312If no such buffer exists, create a buffer with the name
5313BUFFER-OR-NAME and return that buffer."
5314 (if buffer-or-name
5315 (or (get-buffer buffer-or-name)
5316 (let ((buffer (get-buffer-create buffer-or-name)))
5317 (set-buffer-major-mode buffer)
5318 buffer))
5319 (current-buffer)))
5320
5321(defun display-buffer-other-window-means-other-frame (buffer-or-name &optional label)
5322 "Return non-nil if BUFFER shall be preferably displayed in another frame.
5323BUFFER must be a live buffer or the name of a live buffer.
5324
5325Return nil if BUFFER shall be preferably displayed in another
5326window on the selected frame. Return non-nil if BUFFER shall be
5327preferably displayed in a window on any but the selected frame.
5328
5329Optional argument LABEL is like the same argument of
5330`display-buffer'.
5331
5332The calculation of the return value is exclusively based on the
5333user preferences expressed in `display-buffer-alist'."
5334 (let* ((buffer-name
5335 (buffer-name (window-normalize-buffer buffer-or-name)))
5336 (default (display-buffer-normalize-default buffer-name))
5337 (alist (display-buffer-normalize-alist buffer-name label)))
5338 (or (cdr (assq 'other-window-means-other-frame default))
5339 (cdr (assq 'other-window-means-other-frame (cdr alist))))))
5340
5341(defun display-buffer-normalize-special (&optional args)
5342 "Return buffer display specifiers for `special-display-frame-alist'."
5343 (progn ;; <-- reserved for with-no-warnings
5344 (if (and (listp args) (symbolp (car args)))
5345 ;; Note: `display-buffer' funcalls this so take "(nth 1 args)"
5346 ;; where `special-display-popup-frame' (which uses apply) takes
5347 ;; "(cdr args)".
5348 `((function ,(car args) ,(nth 1 args)))
5349 (append
5350 '((reuse-window nil same 0))
5351 (when (and (listp args) (cdr (assq 'same-window args)))
5352 '((reuse-window same nil nil) (reuse-dedicated . weak)))
5353 (when (and (listp args)
5354 (or (cdr (assq 'same-frame args))
5355 (cdr (assq 'same-window args))))
5356 '((pop-up-window (largest . nil) (lru . nil))
5357 (reuse-window nil nil nil)))
5358 (unless display-buffer-mark-dedicated
5359 ;; Don't make anything created above dedicated unless requested.
5360 ;; Otherwise the dedication request below gets in our way.
5361 '((dedicate . nil)))
5362 `((pop-up-frame t)
5363 ,(append '(pop-up-frame-alist)
5364 (when (listp args) args)
5365 special-display-frame-alist)
5366 (dedicate . t))))))
5367
5368(defun display-buffer-normalize-default (buffer-or-name)
5369 "Subroutine of `display-buffer-normalize-specifiers'.
5370BUFFER-OR-NAME is the buffer to display.
5371
5372This routine provides a compatibility layer for the obsolete
5373Emacs 23 buffer display options to set up the corresponding
5374buffer display specifiers."
5375 (progn ;; <-- reserved for with-no-warnings
5376 (let* ((buffer (window-normalize-buffer buffer-or-name))
5377 (buffer-name (buffer-name buffer))
5378 (pop-up-frames
5379 (and (boundp 'pop-up-frames)
5380 (or (and (eq pop-up-frames 'graphic-only)
5381 (display-graphic-p))
5382 pop-up-frames)))
5383 specifiers args)
5384 ;; `other-window-means-other-frame'
5385 (when pop-up-frames
5386 (setq specifiers
5387 (cons (cons 'other-window-means-other-frame t) specifiers)))
5388
5389 ;; `even-window-heights'
5390 (unless (and (boundp 'even-window-heights)
5391 (not even-window-heights))
5392 (setq specifiers
5393 (cons (cons 'reuse-window-even-sizes t) specifiers)))
5394
5395 ;; `display-buffer-mark-dedicated'
5396 (when (and (boundp 'display-buffer-mark-dedicated)
5397 display-buffer-mark-dedicated)
5398 (setq specifiers
5399 (cons (cons 'dedicate display-buffer-mark-dedicated)
5400 specifiers)))
5401
5402 ;; `pop-up-window-min-height'
5403 (let ((min-height
5404 (if (boundp 'split-height-threshold)
5405 (if (numberp split-height-threshold)
5406 (/ split-height-threshold 2)
5407 1.0)
5408 40)))
5409 (setq specifiers
5410 (cons (cons 'pop-up-window-min-height min-height)
5411 specifiers)))
5412
5413 ;; `pop-up-window-min-width'
5414 (let ((min-width
5415 (if (boundp 'split-width-threshold)
5416 (if (numberp split-width-threshold)
5417 (/ split-width-threshold 2)
5418 1.0)
5419 80)))
5420 (setq specifiers
5421 (cons (cons 'pop-up-window-min-width min-width)
5422 specifiers)))
5423
5424 ;; `pop-up-window'
5425 (unless (and (boundp 'pop-up-windows) (not pop-up-windows))
5426 (let ((fun (when (and (boundp 'split-window-preferred-function)
5427 (not (eq split-window-preferred-function
5428 'split-window-sensibly)))
5429 split-window-preferred-function)))
5430 ;; `pop-up-window'
5431 (setq specifiers
5432 (cons
5433 (list 'pop-up-window (cons 'largest fun) (cons 'lru fun))
5434 specifiers))))
5435
5436 ;; `pop-up-frame-function'
5437 (when (and (boundp 'pop-up-frame-function)
5438 (not (equal pop-up-frame-function
5439 '(lambda nil
5440 (make-frame pop-up-frame-alist)))))
5441 (setq specifiers
5442 (cons (cons 'pop-up-frame-function pop-up-frame-function)
5443 specifiers)))
5444
5445 ;; `pop-up-frame-alist'
5446 (when pop-up-frame-alist
5447 (setq specifiers
5448 (cons (cons 'pop-up-frame-alist pop-up-frame-alist)
5449 specifiers)))
5450
5451 ;; `pop-up-frame'
5452 (when pop-up-frames
5453 ;; `pop-up-frame-function'. If `pop-up-frame-function' uses the
5454 ;; now obsolete `pop-up-frame-alist' it will continue to do so.
5455 ;; `pop-up-frame'
5456 (setq specifiers
5457 ;; Maybe we should merge graphic-only into the following?
5458 (cons (list 'pop-up-frame t) specifiers)))
5459
5460 ;; `special-display'
5461 (when (and (boundp 'special-display-function)
5462 special-display-function
5463 (fboundp 'special-display-p)
5464 (setq args (special-display-p buffer-name)))
5465 ;; `special-display-p' returns either t or a list of arguments
5466 ;; to pass to `special-display-function'.
5467 (if (eq special-display-function 'special-display-popup-frame)
5468 (setq specifiers
5469 (append (display-buffer-normalize-special args)
5470 specifiers))
5471 (setq specifiers
5472 (cons
5473 `(function ,special-display-function ,(when (listp args) args))
5474 specifiers))))
5475
5476 ;; Reuse window showing same buffer on visible or iconified frame.
5477 ;; `pop-up-frames', `display-buffer-reuse-frames' means search for
5478 ;; a window showing the buffer on some visible or iconfied frame.
5479 ;; `last-nonminibuffer-frame' non-nil means search that frame.
5480 (let ((frames (or (and (or pop-up-frames
5481 (and (boundp 'display-buffer-reuse-frames)
5482 display-buffer-reuse-frames)
5483 (not (last-nonminibuffer-frame)))
5484 ;; All visible or iconfied frames.
5485 0)
5486 ;; The following usually returns the same frame
5487 ;; so we implicitly search for a window showing
5488 ;; the buffer on the same frame already.
5489 (last-nonminibuffer-frame))))
5490 (when frames
5491 (setq specifiers
5492 (cons (list 'reuse-window 'other 'same frames)
5493 specifiers))))
5494
5495 ;; `same-window'
5496 (when (and (fboundp 'same-window-p) (same-window-p buffer-name))
5497 ;; Try to reuse the same (selected) window.
5498 (setq specifiers
5499 (cons (list 'reuse-window 'same nil nil) specifiers)))
5500
5501 ;; Same window if showing this buffer already. Can be overridden
5502 ;; by `other-window' argument if the buffer is already shown in
5503 ;; the same window.
5504 (setq specifiers
5505 (cons (list 'reuse-window 'same 'same nil) specifiers))
5506
5507 specifiers)))
5508
5509(defun display-buffer-normalize-argument (buffer-name specifiers other-window-means-other-frame)
5510 "Normalize second argument of `display-buffer'.
5511BUFFER-NAME is the name of the buffer that shall be displayed,
5512SPECIFIERS is the second argument of `display-buffer'.
5513OTHER-WINDOW-MEANS-OTHER-FRAME non-nil means use other-frame for
5514other-window."
5515 (progn ;; <-- reserved for with-no-warnings
5516 (let (normalized entry specifier pars)
5517 (cond
5518 ((not specifiers)
5519 nil)
5520 ((listp specifiers)
5521 ;; If SPECIFIERS is a list, we assume it is a list of valid
5522 ;; specifiers.
5523 (dolist (specifier specifiers)
5524 (cond
5525 ((consp specifier)
5526 (setq normalized (cons specifier normalized)))
5527 ((eq specifier 'other-window)
5528 ;; `other-window' must be treated separately.
5529 (let ((entry (assq (if other-window-means-other-frame
5530 'other-frame
5531 'same-frame-other-window)
5532 display-buffer-macro-specifiers)))
5533 (dolist (item (cdr entry))
5534 (setq normalized (cons item normalized)))))
5535 ((symbolp specifier)
5536 ;; Might be a macro specifier, try to expand it (the cdr is a
5537 ;; list and we have to reverse it later, so do it one at a
5538 ;; time).
5539 (let ((entry (assq specifier display-buffer-macro-specifiers)))
5540 (dolist (item (cdr entry))
5541 (setq normalized (cons item normalized)))))))
5542 ;; Reverse list.
5543 (nreverse normalized))
5544 ((setq entry (assq specifiers display-buffer-macro-specifiers))
5545 ;; A macro specifier.
5546 (cdr entry))
5547 (t
5548 ;; Anything else means use another window according to the
5549 ;; non-overriding specifiers of `display-buffer-alist' and the
5550 ;; specifiers produced by `display-buffer-normalize-default'.
5551 '((other-window . t)))))))
5552
5553(defun display-buffer-normalize-alist-1 (specifiers label)
5554 "Subroutine of `display-buffer-normalize-alist'.
5555SPECIFIERS is a list of buffer display specfiers. LABEL is the
5556same argument of `display-buffer'."
5557 (let (normalized entry)
5558 (cond
5559 ((not specifiers)
5560 nil)
5561 ((listp specifiers)
5562 ;; If SPECIFIERS is a list, we assume it is a list of specifiers.
5563 (dolist (specifier specifiers)
5564 (cond
5565 ((consp specifier)
5566 (setq normalized (cons specifier normalized)))
5567 ((symbolp specifier)
5568 ;; Might be a macro specifier, try to expand it (the cdr is a
5569 ;; list and we have to reverse it later, so do it one at a
5570 ;; time).
5571 (let ((entry (assq specifier display-buffer-macro-specifiers)))
5572 (dolist (item (cdr entry))
5573 (setq normalized (cons item normalized)))))))
5574 ;; Reverse list.
5575 (nreverse normalized))
5576 ((setq entry (assq specifiers display-buffer-macro-specifiers))
5577 ;; A macro specifier.
5578 (cdr entry)))))
5579
5580(defun display-buffer-normalize-alist (buffer-name label)
5581 "Normalize `display-buffer-alist'.
5582BUFFER-NAME must be the name of the buffer that shall be displayed.
5583LABEL the corresponding argument of `display-buffer'."
5584 (let (list-1 list-2)
5585 (dolist (entry display-buffer-alist)
5586 (when (and (listp entry)
5587 (catch 'match
5588 (dolist (id (car entry))
5589 (when (consp id)
5590 (let ((type (car id))
5591 (value (cdr id)))
5592 (when (or (and (eq type 'name) (stringp value)
5593 (equal value buffer-name))
5594 (and (eq type 'regexp) (stringp value)
5595 (string-match-p value buffer-name))
5596 (and (eq type 'label) (eq value label)))
5597 (throw 'match t)))))))
5598 (let* ((specifiers (cdr entry))
5599 (normalized
5600 (display-buffer-normalize-alist-1 specifiers label)))
5601 (if (cdr (assq 'override specifiers))
5602 (setq list-1
5603 (if list-1
5604 (append list-1 normalized)
5605 normalized))
5606 (setq list-2
5607 (if list-2
5608 (append list-2 normalized)
5609 normalized))))))
5610
5611 (cons list-1 list-2)))
5612
5613(defun display-buffer-normalize-specifiers (buffer-name specifiers label)
5614 "Return normalized specifiers for a buffer matching BUFFER-NAME or LABEL.
5615BUFFER-NAME must be a string specifying a valid buffer name.
5616SPECIFIERS and LABEL are the homonymous arguments of
5617`display-buffer'.
5618
5619The method for displaying the buffer specified by BUFFER-NAME or
5620LABEL is established by appending the following four lists of
5621specifiers:
5622
5623- The specifiers in `display-buffer-alist' whose buffer
5624 identifier matches BUFFER-NAME or LABEL and whose 'override
5625 component is set.
5626
5627- SPECIFIERS.
5628
5629- The specifiers in `display-buffer-alist' whose buffer
5630 identifier matches BUFFER-NAME or LABEL and whose 'override
5631 component is not set."
5632 (let* ((default (display-buffer-normalize-default buffer-name))
5633 (alist (display-buffer-normalize-alist buffer-name label))
5634 (other-window-means-other-frame
5635 (or (cdr (assq 'other-window-means-other-frame default))
5636 (cdr (assq 'other-window-means-other-frame (cdr alist)))))
5637 (arg2 (display-buffer-normalize-argument
5638 buffer-name specifiers other-window-means-other-frame))
5639 (arg3
5640 ;; Handle special meaning of the LABEL argument of
5641 ;; `display-buffer'.
5642 (when (or (memq label '(visible 0 t)) (frame-live-p label))
5643 ;; LABEL must be one of visible (any visible frame), 0 (any
5644 ;; visible or iconfied frame), t (any frame), or a live
5645 ;; frame.
5646 `((reuse-window nil same ,label)))))
5647 (append
5648 ;; Overriding user specifiers.
5649 (car alist)
5650 ;; Special value of third argument of display-buffer.
5651 arg3
5652 ;; Second argument of display-buffer.
5653 arg2
5654 ;; Non-overriding user specifiers.
5655 (cdr alist)
5656 ;; Default specifiers.
5657 default)))
5658
5659;; Minibuffer-only frames should be documented better. They really
5660;; deserve a separate section in the manual. Also
5661;; `last-nonminibuffer-frame' is nowhere documented in the manual.
5662(defun display-buffer-frame (&optional frame)
5663 "Return FRAME if it is live and not a minibuffer-only frame.
5664Return the value of `last-nonminibuffer-frame' otherwise."
5665 (setq frame (window-normalize-frame frame))
5666 (if (and (frame-live-p frame)
5667 ;; A not very nice way to get that information.
5668 (not (window-minibuffer-p (frame-root-window frame))))
5669 frame
5670 (last-nonminibuffer-frame)))
5671
5672(defun display-buffer (&optional buffer-or-name specifiers label)
5673 "Make the buffer specified by BUFFER-OR-NAME appear in some window.
5674Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
5675buffer name), or nil. If BUFFER-OR-NAME is a string not naming
5676an existent buffer, create a buffer with that name. If
5677BUFFER-OR-NAME is nil or omitted, display the current buffer.
5678Interactively, prompt for the buffer name using the minibuffer.
5679
5680Return the window chosen to display the buffer or nil if no such
5681window is found. Do not change the selected window unless the
5682buffer is shown on a different frame than the selected one.
5683
5684Optional argument SPECIFIERS must be a list of buffer display
5685specifiers, see the documentation of `display-buffer-alist' for a
5686description.
5687
5688For convenience, SPECIFIERS may also consist of a single buffer
5689display location specifier or t, where the latter means to
5690display the buffer in any but the selected window. If SPECIFIERS
5691is nil or omitted, this means to exclusively use the specifiers
5692provided by the variable `display-buffer-alist' and the function
5693`display-buffer-normalize-default'.
5694
5695As a special case, the `reuse-window' specifier allows to specify
5696as second element an arbitrary window, as third element an
5697arbitrary buffer, and as fourth element an arbitrary frame. As
5698first element of a window/side pair of the `pop-up-window'
5699specifier you can specifiy an arbitrary window.
5700
5701The optional third argument LABEL, if non-nil, must be a symbol
5702specifiying the buffer display label. Applications should set
5703this when the buffer shall be displayed in some special way but
5704BUFFER-OR-NAME does not identify the buffer as special. Typical
5705buffers that fit into this category are those whose names are
5706derived from the name of the file they are visiting. A user can
5707override SPECIFIERS by adding an entry to `display-buffer-alist'
5708whose car contains LABEL and whose cdr specifies the preferred
5709alternative display method.
5710
5711The following values of LABEL have a special meaning and allow to
5712specify the set of frames to investigate when the buffer already
5713appears in a window:
5714
5715`visible' - the set of visible frames.
5716
57170 - the set of visible or iconified frames.
5718
5719t - the set of all frames.
5720
5721A live frame - the set containing that frame as its only element.
5722
5723If the buffer is already displayed in a window on a frame in the
5724specified set, return that window.
5725
5726The method to display the buffer is derived by combining the
5727values of `display-buffer-alist' and SPECIFIERS. Highest
5728priority is given to overriding elements of
5729`display-buffer-alist'. Next come the elements specified by
5730SPECIFIERS, followed by the non-overriding elements of
5731`display-buffer-alist'.
5732
5733The result must be a list of valid buffer display specifiers. If
5734`display-buffer-function' is non-nil, call it with the buffer and
5735this list as arguments."
5736 (interactive "BDisplay buffer:\nP")
5737 (let* ((buffer (window-normalize-buffer-to-display buffer-or-name))
5738 (buffer-name (buffer-name buffer))
5739 (normalized
5740 ;; Normalize specifiers.
5741 (display-buffer-normalize-specifiers buffer-name specifiers label))
5742 ;; Don't use a minibuffer frame.
5743 (frame (display-buffer-frame))
5744 ;; `window' is the window we use for showing `buffer'.
5745 window specifier method other-window)
5746 ;; Reset this.
5747 (setq display-buffer-window nil)
5748 (if display-buffer-function
5749 ;; Let `display-buffer-function' do the job.
5750 (funcall display-buffer-function buffer specifiers)
5751 ;; Retrieve the next location specifier while there a specifiers
5752 ;; left and we don't have a valid window.
5753 (while (and normalized (not (window-live-p window)))
5754 (setq specifier (car normalized))
5755 (setq normalized (cdr normalized))
5756 (setq method (car specifier))
5757 (setq window
5758 (cond
5759 ((eq method 'reuse-window)
5760 (display-buffer-reuse-window
5761 buffer (cdr specifier) normalized other-window))
5762 ((eq method 'pop-up-window)
5763 (display-buffer-pop-up-window
5764 buffer (cdr specifier) normalized))
5765 ((eq method 'pop-up-frame)
5766 (display-buffer-pop-up-frame
5767 buffer (cdr specifier) normalized))
5768 ((eq method 'use-side-window)
5769 (display-buffer-in-side-window
5770 buffer (nth 1 specifier) (nth 2 specifier) normalized))
5771 ((eq method 'function)
5772 (funcall (nth 1 specifier) buffer (nth 2 specifier)))
5773 ((eq method 'other-window)
5774 (setq other-window t)))))
5775
5776 ;; If we don't have a window yet, try a fallback method. All
5777 ;; specifiers have been used up by now. Try reusing a window
5778 (or (and (window-live-p window) window)
5779 ;; on the selected frame,
5780 (display-buffer-reuse-window
5781 buffer '(nil nil nil) nil other-window)
5782 ;; showing BUFFER on any visible frame,
5783 (display-buffer-reuse-window
5784 buffer '(nil same visible) nil other-window)
5785 ;; not showing BUFFER on any visible frame,
5786 (display-buffer-reuse-window
5787 buffer '(nil other visible) nil other-window)
5788 ;; showing BUFFER on any visible or iconified frame,
5789 (display-buffer-reuse-window
5790 buffer '(nil same 0) nil other-window)
5791 ;; not showing BUFFER on any visible or iconified frame.
5792 (display-buffer-reuse-window
5793 buffer '(nil other 0) nil other-window)
5794 ;; If everything failed so far, try popping up a new frame
5795 ;; regardless of graphic-only restrictions.
5796 (display-buffer-pop-up-frame buffer)))))
5797
5798(defun display-buffer-same-window (&optional buffer-or-name label)
5799 "Display buffer specified by BUFFER-OR-NAME in the selected window.
5800Another window will be used only if the buffer can't be shown in
5801the selected window, usually because it is dedicated to another
5802buffer. Optional argument BUFFER-OR-NAME and LABEL are as for
5803`display-buffer'."
5804 (interactive "BDisplay buffer in same window:\nP")
5805 (display-buffer buffer-or-name 'same-window label))
5806
5807(defun display-buffer-same-frame (&optional buffer-or-name label)
5808 "Display buffer specified by BUFFER-OR-NAME in a window on the same frame.
5809Another frame will be used only if there is no other choice.
5810Optional argument BUFFER-OR-NAME and LABEL are as for
5811`display-buffer'."
5812 (interactive "BDisplay buffer on same frame:\nP")
5813 (display-buffer buffer-or-name 'same-frame label))
5814
5815(defun display-buffer-other-window (&optional buffer-or-name label)
5816 "Display buffer specified by BUFFER-OR-NAME in another window.
5817The selected window will be used only if there is no other
5818choice. Windows on the selected frame are preferred to windows
5819on other frames. Optional argument BUFFER-OR-NAME and LABEL are as
5820for `display-buffer'."
5821 (interactive "BDisplay buffer in another window:\nP")
5822 (display-buffer buffer-or-name 'other-window label))
5823
5824(defun display-buffer-same-frame-other-window (&optional buffer-or-name label)
5825 "Display buffer specified by BUFFER-OR-NAME in another window on the same frame.
5826The selected window or another frame will be used only if there
5827is no other choice. Optional argument BUFFER-OR-NAME and LABEL are
5828as for `display-buffer'."
5829 (interactive "BDisplay buffer in another window on same frame:\nP")
5830 (display-buffer buffer-or-name 'same-frame-other-window label))
5831
5832(defun display-buffer-other-frame (&optional buffer-or-name label)
5833 "Display buffer specified by BUFFER-OR-NAME on another frame.
5834The selected frame will be used only if there is no other choice.
5835Optional argument BUFFER-OR-NAME and LABEL are as for
5836`display-buffer'.
5837
5838If this command uses another frame, it will also select that frame."
5839 (interactive "BDisplay buffer in other frame: ")
5840 (display-buffer buffer-or-name 'other-frame label))
5841
5842(defun pop-to-buffer (&optional buffer-or-name specifiers norecord label)
5843 "Display buffer specified by BUFFER-OR-NAME and select the window used.
5844Optional argument BUFFER-OR-NAME may be a buffer, a string \(a
5845buffer name), or nil. If BUFFER-OR-NAME is a string naming a buffer
5846that does not exist, create a buffer with that name. If
5847BUFFER-OR-NAME is nil or omitted, display the current buffer.
5848Interactively, prompt for the buffer name using the minibuffer.
5849
5850Optional second argument SPECIFIERS can be: a list of buffer
5851display specifiers (see `display-buffer-alist'); a single
5852location specifier; t, which means to display the buffer in any
5853but the selected window; or nil, which means to exclusively apply
5854the specifiers customized by the user. See `display-buffer' for
5855more details.
5856
5857Optional argument NORECORD non-nil means do not put the displayed
5858buffer at the front of the buffer list, and do not make the window
5859displaying it the most recently selected one.
5860
5861The optional argument LABEL, if non-nil, is a symbol specifying the
5862display purpose. Applications should set this when the buffer
5863should be displayed in a special way but BUFFER-OR-NAME does not
5864identify the buffer as special. Buffers that typically fit into
5865this category are those whose names have been derived from the
5866name of the file they are visiting.
5867
5868Returns the displayed buffer, or nil if displaying the buffer failed.
5869
5870This uses the function `display-buffer' as a subroutine; see the
5871documentations of `display-buffer' and `display-buffer-alist' for
5872additional information."
5873 (interactive "BPop to buffer:\nP")
5874 (let ((buffer (window-normalize-buffer-to-display buffer-or-name))
5875 (old-window (selected-window))
5876 (old-frame (selected-frame))
5877 new-window new-frame)
5878 (set-buffer buffer)
5879 (setq new-window (display-buffer buffer specifiers label))
5880 (setq new-frame (window-frame new-window))
5881 (if (eq old-frame new-frame)
5882 ;; Make sure new-window gets selected (Bug#8615), (Bug#6954).
5883 (select-window new-window norecord)
5884 ;; `display-buffer' has chosen another frame, make sure it gets
5885 ;; input focus and is risen.
5886 (select-frame-set-input-focus new-frame norecord))
5887 buffer))
5888
5889(defun pop-to-buffer-same-window (&optional buffer-or-name norecord label)
5890 "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
5891Another window will be used only if the buffer can't be shown in
5892the selected window, usually because it is dedicated to another
5893buffer. Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are
5894as for `pop-to-buffer'."
5895 (interactive "BPop to buffer in selected window:\nP")
5896 (pop-to-buffer buffer-or-name 'same-window norecord label))
5897
5898(defun pop-to-buffer-same-frame (&optional buffer-or-name norecord label)
5899 "Pop to buffer specified by BUFFER-OR-NAME in a window on the selected frame.
5900Another frame will be used only if there is no other choice.
5901Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
5902`pop-to-buffer'."
5903 (interactive "BPop to buffer on same frame:\nP")
5904 (pop-to-buffer buffer-or-name 'same-frame norecord label))
5905
5906(defun pop-to-buffer-other-window (&optional buffer-or-name norecord label)
5907 "Pop to buffer specified by BUFFER-OR-NAME in another window.
5908The selected window will be used only if there is no other
5909choice. Windows on the selected frame are preferred to windows
5910on other frames. Optional arguments BUFFER-OR-NAME, NORECORD and
5911LABEL are as for `pop-to-buffer'."
5912 (interactive "BPop to buffer in another window:\nP")
5913 (pop-to-buffer buffer-or-name 'other-window norecord))
5914
5915(defun pop-to-buffer-same-frame-other-window (&optional buffer-or-name norecord label)
5916 "Pop to buffer specified by BUFFER-OR-NAME in another window on the selected frame.
5917The selected window or another frame will be used only if there
5918is no other choice. Optional arguments BUFFER-OR-NAME, NORECORD
5919and LABEL are as for `pop-to-buffer'."
5920 (interactive "BPop to buffer in another window on same frame:\nP")
5921 (pop-to-buffer buffer-or-name 'same-frame-other-window norecord label))
5922
5923(defun pop-to-buffer-other-frame (&optional buffer-or-name norecord label)
5924 "Pop to buffer specified by BUFFER-OR-NAME on another frame.
5925The selected frame will be used only if there's no other choice.
5926Optional arguments BUFFER-OR-NAME, NORECORD and LABEL are as for
5927`pop-to-buffer'."
5928 (interactive "BPop to buffer on another frame:\nP")
5929 (pop-to-buffer buffer-or-name 'other-frame norecord label))
5930 3873
5931(defun read-buffer-to-switch (prompt) 3874(defcustom display-buffer-function nil
5932 "Read the name of a buffer to switch to, prompting with PROMPT. 3875 "If non-nil, function to call to handle `display-buffer'.
5933Return the neame of the buffer as a string. 3876It will receive two args, the buffer and a flag which if non-nil
5934 3877means that the currently selected window is not acceptable. It
5935This function is intended for the `switch-to-buffer' family of 3878should choose or create a window, display the specified buffer in
5936commands since these need to omit the name of the current buffer 3879it, and return the window.
5937from the list of completions and default values." 3880
5938 (let ((rbts-completion-table (internal-complete-buffer-except))) 3881The function specified here is responsible for setting the value
5939 (minibuffer-with-setup-hook 3882of `display-buffer-window' and the quit-restore parameter of the
5940 (lambda () 3883window used."
5941 (setq minibuffer-completion-table rbts-completion-table) 3884 :type '(choice
5942 ;; Since rbts-completion-table is built dynamically, we 3885 (const nil)
5943 ;; can't just add it to the default value of 3886 (function :tag "function"))
5944 ;; icomplete-with-completion-tables, so we add it
5945 ;; here manually.
5946 (if (and (boundp 'icomplete-with-completion-tables)
5947 (listp icomplete-with-completion-tables))
5948 (set (make-local-variable 'icomplete-with-completion-tables)
5949 (cons rbts-completion-table
5950 icomplete-with-completion-tables))))
5951 (read-buffer prompt (other-buffer (current-buffer))
5952 (confirm-nonexistent-file-or-buffer)))))
5953
5954(defun window-normalize-buffer-to-switch-to (buffer-or-name)
5955 "Normalize BUFFER-OR-NAME argument of buffer switching functions.
5956If BUFFER-OR-NAME is nil, return the buffer returned by
5957`other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME
5958exists, return that buffer. If no such buffer exists, create a
5959buffer with the name BUFFER-OR-NAME and return that buffer."
5960 (if buffer-or-name
5961 (or (get-buffer buffer-or-name)
5962 (let ((buffer (get-buffer-create buffer-or-name)))
5963 (set-buffer-major-mode buffer)
5964 buffer))
5965 (other-buffer)))
5966
5967(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
5968 "Switch to buffer BUFFER-OR-NAME in the selected window.
5969If called interactively, prompt for the buffer name using the
5970minibuffer. The variable `confirm-nonexistent-file-or-buffer'
5971determines whether to request confirmation before creating a new
5972buffer.
5973
5974BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
5975nil. If BUFFER-OR-NAME is a string that does not identify an
5976existing buffer, create a buffer with that name. If
5977BUFFER-OR-NAME is nil, switch to the buffer returned by
5978`other-buffer'.
5979
5980Optional argument NORECORD non-nil means do not put the buffer
5981specified by BUFFER-OR-NAME at the front of the buffer list and
5982do not make the window displaying it the most recently selected
5983one.
5984
5985If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
5986in the currently selected window; signal an error if that is
5987impossible (e.g. if the selected window is minibuffer-only).
5988If non-nil, BUFFER-OR-NAME may be displayed in another window.
5989
5990Return the buffer switched to."
5991 (interactive
5992 (list (read-buffer-to-switch "Switch to buffer: ") nil nil))
5993 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
5994 (if (null force-same-window)
5995 (pop-to-buffer
5996 buffer '(same-window (reuse-window-dedicated . weak)) norecord)
5997 (cond
5998 ;; Don't call set-window-buffer if it's not needed since it
5999 ;; might signal an error (e.g. if the window is dedicated).
6000 ((eq buffer (window-buffer)))
6001 ((window-minibuffer-p)
6002 (error "Cannot switch buffers in minibuffer window"))
6003 ((eq (window-dedicated-p) t)
6004 (error "Cannot switch buffers in a dedicated window"))
6005 (t (set-window-buffer nil buffer)))
6006
6007 (unless norecord
6008 (select-window (selected-window)))
6009 (set-buffer buffer))))
6010
6011(defun switch-to-buffer-same-frame (buffer-or-name &optional norecord)
6012 "Switch to buffer BUFFER-OR-NAME in a window on the selected frame.
6013Another frame will be used only if there is no other choice.
6014Arguments BUFFER-OR-NAME and NORECORD have the same meaning as
6015for `switch-to-buffer'.
6016
6017This function is intended for interactive use only. Lisp
6018functions should call `pop-to-buffer-same-frame' instead."
6019 (interactive
6020 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
6021 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
6022 (pop-to-buffer buffer 'same-frame norecord)))
6023
6024(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
6025 "Switch to buffer BUFFER-OR-NAME in another window.
6026The selected window will be used only if there is no other
6027choice. Windows on the selected frame are preferred to windows
6028on other frames. Arguments BUFFER-OR-NAME and NORECORD have the
6029same meaning as for `switch-to-buffer'.
6030
6031This function is intended for interactive use only. Lisp
6032functions should call `pop-to-buffer-other-window' instead."
6033 (interactive
6034 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
6035 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
6036 (pop-to-buffer buffer 'other-window norecord)))
6037
6038(defun switch-to-buffer-other-window-same-frame (buffer-or-name &optional norecord)
6039 "Switch to buffer BUFFER-OR-NAME in another window on the selected frame.
6040The selected window or another frame will be used only if there
6041is no other choice. Arguments BUFFER-OR-NAME and NORECORD have
6042the same meaning as for `switch-to-buffer'.
6043
6044This function is intended for interactive use only. Lisp
6045functions should call `pop-to-buffer-other-window-same-frame'
6046instead."
6047 (interactive
6048 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
6049 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
6050 (pop-to-buffer buffer 'same-frame-other-window norecord)))
6051
6052(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
6053 "Switch to buffer BUFFER-OR-NAME on another frame.
6054The same frame will be used only if there is no other choice.
6055Arguments BUFFER-OR-NAME and NORECORD have the same meaning
6056as for `switch-to-buffer'.
6057
6058This function is intended for interactive use only. Lisp
6059functions should call `pop-to-buffer-other-frame' instead."
6060 (interactive
6061 (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
6062 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
6063 (pop-to-buffer buffer 'other-frame norecord)))
6064
6065;;; Obsolete definitions of `display-buffer' below.
6066(defcustom same-window-buffer-names nil
6067 "List of names of buffers that should appear in the \"same\" window.
6068`display-buffer' and `pop-to-buffer' show a buffer whose name is
6069on this list in the selected rather than some other window.
6070
6071An element of this list can be a cons cell instead of just a
6072string. In that case, the cell's car must be a string specifying
6073the buffer name. This is for compatibility with
6074`special-display-buffer-names'; the cdr of the cons cell is
6075ignored.
6076
6077See also `same-window-regexps'."
6078 :type '(repeat (string :format "%v"))
6079 :group 'windows)
6080
6081(defcustom same-window-regexps nil
6082 "List of regexps saying which buffers should appear in the \"same\" window.
6083`display-buffer' and `pop-to-buffer' show a buffer whose name
6084matches a regexp on this list in the selected rather than some
6085other window.
6086
6087An element of this list can be a cons cell instead of just a
6088string. In that case, the cell's car must be a regexp matching
6089the buffer name. This is for compatibility with
6090`special-display-regexps'; the cdr of the cons cell is ignored.
6091
6092See also `same-window-buffer-names'."
6093 :type '(repeat (regexp :format "%v"))
6094 :group 'windows) 3887 :group 'windows)
6095 3888
6096(defun same-window-p (buffer-name) 3889(defcustom pop-up-frame-alist nil
6097 "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window. 3890 "Alist of parameters for automatically generated new frames.
6098This function returns non-nil if `display-buffer' or 3891You can set this in your init file; for example,
6099`pop-to-buffer' would show a buffer named BUFFER-NAME in the
6100selected rather than \(as usual\) some other window. See
6101`same-window-buffer-names' and `same-window-regexps'."
6102 (let ((buffer-names (with-no-warnings same-window-buffer-names))
6103 (regexps (with-no-warnings same-window-regexps)))
6104 (cond
6105 ((not (stringp buffer-name)))
6106 ;; The elements of `same-window-buffer-names' can be buffer
6107 ;; names or cons cells whose cars are buffer names.
6108 ((member buffer-name buffer-names))
6109 ((assoc buffer-name buffer-names))
6110 ((catch 'found
6111 (dolist (regexp regexps)
6112 ;; The elements of `same-window-regexps' can be regexps
6113 ;; or cons cells whose cars are regexps.
6114 (when (or (and (stringp regexp)
6115 (string-match regexp buffer-name))
6116 (and (consp regexp) (stringp (car regexp))
6117 (string-match-p (car regexp) buffer-name)))
6118 (throw 'found t))))))))
6119
6120(defcustom special-display-frame-alist
6121 '((height . 14) (width . 80) (unsplittable . t))
6122 "Alist of parameters for special frames.
6123Special frames are used for buffers whose names are listed in
6124`special-display-buffer-names' and for buffers whose names match
6125one of the regular expressions in `special-display-regexps'.
6126 3892
6127This variable can be set in your init file, like this: 3893 (setq pop-up-frame-alist '((width . 80) (height . 20)))
6128 3894
6129 (setq special-display-frame-alist '((width . 80) (height . 20))) 3895If non-nil, the value you specify here is used by the default
3896`pop-up-frame-function' for the creation of new frames.
6130 3897
6131These supersede the values given in `default-frame-alist'." 3898Since `pop-up-frame-function' is used by `display-buffer' for
3899making new frames, any value specified here by default affects
3900the automatic generation of new frames via `display-buffer' and
3901all functions based on it. The behavior of `make-frame' is not
3902affected by this variable."
6132 :type '(repeat (cons :format "%v" 3903 :type '(repeat (cons :format "%v"
6133 (symbol :tag "Parameter") 3904 (symbol :tag "Parameter")
6134 (sexp :tag "Value"))) 3905 (sexp :tag "Value")))
6135 :group 'frames) 3906 :group 'frames)
6136 3907
6137(defun special-display-popup-frame (buffer &optional args) 3908(defcustom pop-up-frame-function
6138 "Display BUFFER in a special frame and return the window chosen. 3909 (lambda () (make-frame pop-up-frame-alist))
6139If BUFFER is already displayed in a visible or iconified frame, 3910 "Function used by `display-buffer' for creating a new frame.
6140raise that frame. Otherwise, display BUFFER in a way as 3911This function is called with no arguments and should return a new
6141specified by optional argument ARGS. 3912frame. The default value calls `make-frame' with the argument
6142 3913`pop-up-frame-alist'."
6143If ARGS is an alist, use it as a list of frame parameters. If
6144these parameters contain \(same-window . t), display BUFFER in
6145the selected window. If they contain \(same-frame . t), display
6146BUFFER in a window on the selected frame.
6147
6148If ARGS is a list whose car is a symbol, use (car ARGS) as a
6149function to do the work. Pass it BUFFER as first argument,
6150and (cdr ARGS) as the rest of the arguments."
6151 (if (and args (symbolp (car args)))
6152 (apply (car args) buffer (cdr args))
6153 (let ((window (get-buffer-window buffer 0)))
6154 (or
6155 ;; If we have a window already, make it visible.
6156 (when window
6157 (let ((frame (window-frame window)))
6158 (make-frame-visible frame)
6159 (raise-frame frame)
6160 window))
6161 ;; Reuse the current window if the user requested it.
6162 (when (cdr (assq 'same-window args))
6163 (display-buffer-reuse-window
6164 buffer '(same nil nil) '((reuse-dedicated . weak))))
6165 ;; Stay on the same frame if requested.
6166 (when (or (cdr (assq 'same-frame args))
6167 (cdr (assq 'same-window args)))
6168 (or (display-buffer-pop-up-window
6169 buffer '((largest . nil) (lru . nil)))
6170 (display-buffer-reuse-window
6171 buffer '(nil nil nil))))
6172 ;; If no window yet, make one in a new frame.
6173 (let ((frame
6174 (with-current-buffer buffer
6175 (make-frame
6176 (append args (with-no-warnings
6177 special-display-frame-alist))))))
6178 (set-window-buffer (frame-selected-window frame) buffer)
6179 (set-window-dedicated-p (frame-selected-window frame) t)
6180 (frame-selected-window frame))))))
6181
6182(defcustom special-display-function 'special-display-popup-frame
6183 "Function to call for displaying special buffers.
6184This function is called with two arguments - the buffer and,
6185optionally, a list - and should return a window displaying that
6186buffer. The default value usually makes a separate frame for the
6187buffer using `special-display-frame-alist' to specify the frame
6188parameters. See the definition of `special-display-popup-frame'
6189for how to specify such a function.
6190
6191A buffer is special when its name is either listed in
6192`special-display-buffer-names' or matches a regexp in
6193`special-display-regexps'."
6194 :type 'function 3914 :type 'function
6195 :group 'windows
6196 :group 'frames) 3915 :group 'frames)
6197 3916
6198(defcustom special-display-buffer-names nil 3917(defcustom special-display-buffer-names nil
@@ -6230,6 +3949,9 @@ named BUFFER-NAME as first argument, and OTHER-ARGS as the
6230second. If `special-display-function' specifies some other 3949second. If `special-display-function' specifies some other
6231function, that function is called with the buffer named 3950function, that function is called with the buffer named
6232BUFFER-NAME as first, and the element's cdr as second argument. 3951BUFFER-NAME as first, and the element's cdr as second argument.
3952In any case, that function is responsible for setting the value
3953of `display-buffer-window' and the quit-restore parameter of the
3954window used.
6233 3955
6234If this variable appears \"not to work\", because you added a 3956If this variable appears \"not to work\", because you added a
6235name to it but the corresponding buffer is displayed in the 3957name to it but the corresponding buffer is displayed in the
@@ -6335,17 +4057,15 @@ matching BUFFER-NAME. If `special-display-buffer-names' or
6335`special-display-regexps' contain a list entry whose car equals 4057`special-display-regexps' contain a list entry whose car equals
6336or matches BUFFER-NAME, the return value is the cdr of that 4058or matches BUFFER-NAME, the return value is the cdr of that
6337entry." 4059entry."
6338 (let ((buffer-names (with-no-warnings special-display-buffer-names)) 4060 (let (tmp)
6339 (regexps (with-no-warnings special-display-regexps))
6340 tmp)
6341 (cond 4061 (cond
6342 ((not (stringp buffer-name))) 4062 ((not (stringp buffer-name)))
6343 ((member buffer-name buffer-names) 4063 ((member buffer-name special-display-buffer-names)
6344 t) 4064 t)
6345 ((setq tmp (assoc buffer-name buffer-names)) 4065 ((setq tmp (assoc buffer-name special-display-buffer-names))
6346 (cdr tmp)) 4066 (cdr tmp))
6347 ((catch 'found 4067 ((catch 'found
6348 (dolist (regexp regexps) 4068 (dolist (regexp special-display-regexps)
6349 (cond 4069 (cond
6350 ((stringp regexp) 4070 ((stringp regexp)
6351 (when (string-match-p regexp buffer-name) 4071 (when (string-match-p regexp buffer-name)
@@ -6354,34 +4074,142 @@ entry."
6354 (string-match-p (car regexp) buffer-name)) 4074 (string-match-p (car regexp) buffer-name))
6355 (throw 'found (cdr regexp)))))))))) 4075 (throw 'found (cdr regexp))))))))))
6356 4076
6357(defcustom pop-up-frame-alist nil 4077(defcustom special-display-frame-alist
6358 "Alist of parameters for automatically generated new frames. 4078 '((height . 14) (width . 80) (unsplittable . t))
6359You can set this in your init file; for example, 4079 "Alist of parameters for special frames.
4080Special frames are used for buffers whose names are listed in
4081`special-display-buffer-names' and for buffers whose names match
4082one of the regular expressions in `special-display-regexps'.
6360 4083
6361 (setq pop-up-frame-alist '((width . 80) (height . 20))) 4084This variable can be set in your init file, like this:
6362 4085
6363If non-nil, the value you specify here is used by the default 4086 (setq special-display-frame-alist '((width . 80) (height . 20)))
6364`pop-up-frame-function' for the creation of new frames.
6365 4087
6366Since `pop-up-frame-function' is used by `display-buffer' for 4088These supersede the values given in `default-frame-alist'."
6367making new frames, any value specified here by default affects
6368the automatic generation of new frames via `display-buffer' and
6369all functions based on it. The behavior of `make-frame' is not
6370affected by this variable."
6371 :type '(repeat (cons :format "%v" 4089 :type '(repeat (cons :format "%v"
6372 (symbol :tag "Parameter") 4090 (symbol :tag "Parameter")
6373 (sexp :tag "Value"))) 4091 (sexp :tag "Value")))
6374 :group 'frames) 4092 :group 'frames)
6375 4093
6376(defcustom pop-up-frame-function 4094(defun special-display-popup-frame (buffer &optional args)
6377 (lambda () (make-frame pop-up-frame-alist)) 4095 "Display BUFFER and return the window chosen.
6378 "Function used by `display-buffer' for creating a new frame. 4096If BUFFER is already displayed in a visible or iconified frame,
6379This function is called with no arguments and should return a new 4097raise that frame. Otherwise, display BUFFER in a new frame.
6380frame. The default value calls `make-frame' with the argument 4098
6381`pop-up-frame-alist'." 4099Optional argument ARGS is a list specifying additional
4100information.
4101
4102If ARGS is an alist, use it as a list of frame parameters. If
4103these parameters contain \(same-window . t), display BUFFER in
4104the selected window. If they contain \(same-frame . t), display
4105BUFFER in a window of the selected frame.
4106
4107If ARGS is a list whose car is a symbol, use (car ARGS) as a
4108function to do the work. Pass it BUFFER as first argument,
4109and (cdr ARGS) as second."
4110 (if (and args (symbolp (car args)))
4111 (apply (car args) buffer (cdr args))
4112 (let ((window (get-buffer-window buffer 0)))
4113 (or
4114 ;; If we have a window already, make it visible.
4115 (when window
4116 (let ((frame (window-frame window)))
4117 (make-frame-visible frame)
4118 (raise-frame frame)
4119 (display-buffer-record-window 'reuse-window window buffer)
4120 window))
4121 ;; Reuse the current window if the user requested it.
4122 (when (cdr (assq 'same-window args))
4123 (condition-case nil
4124 (progn (switch-to-buffer buffer nil t) (selected-window))
4125 (error nil)))
4126 ;; Stay on the same frame if requested.
4127 (when (or (cdr (assq 'same-frame args)) (cdr (assq 'same-window args)))
4128 (let* ((pop-up-windows t)
4129 pop-up-frames
4130 special-display-buffer-names special-display-regexps)
4131 (display-buffer buffer)))
4132 ;; If no window yet, make one in a new frame.
4133 (let ((frame
4134 (with-current-buffer buffer
4135 (make-frame (append args special-display-frame-alist)))))
4136 (display-buffer-record-window
4137 'pop-up-frame (frame-selected-window frame) buffer)
4138 (set-window-buffer (frame-selected-window frame) buffer)
4139 (set-window-dedicated-p (frame-selected-window frame) t)
4140 (frame-selected-window frame))))))
4141
4142(defcustom special-display-function 'special-display-popup-frame
4143 "Function to call for displaying special buffers.
4144This function is called with two arguments - the buffer and,
4145optionally, a list - and should return a window displaying that
4146buffer. The default value usually makes a separate frame for the
4147buffer using `special-display-frame-alist' to specify the frame
4148parameters. See the definition of `special-display-popup-frame'
4149for how to specify such a function.
4150
4151A buffer is special when its name is either listed in
4152`special-display-buffer-names' or matches a regexp in
4153`special-display-regexps'.
4154
4155The function specified here is responsible for setting the value
4156of `display-buffer-window' and the quit-restore parameter of the
4157window used."
6382 :type 'function 4158 :type 'function
6383 :group 'frames) 4159 :group 'frames)
6384 4160
4161(defcustom same-window-buffer-names nil
4162 "List of names of buffers that should appear in the \"same\" window.
4163`display-buffer' and `pop-to-buffer' show a buffer whose name is
4164on this list in the selected rather than some other window.
4165
4166An element of this list can be a cons cell instead of just a
4167string. In that case, the cell's car must be a string specifying
4168the buffer name. This is for compatibility with
4169`special-display-buffer-names'; the cdr of the cons cell is
4170ignored.
4171
4172See also `same-window-regexps'."
4173 :type '(repeat (string :format "%v"))
4174 :group 'windows)
4175
4176(defcustom same-window-regexps nil
4177 "List of regexps saying which buffers should appear in the \"same\" window.
4178`display-buffer' and `pop-to-buffer' show a buffer whose name
4179matches a regexp on this list in the selected rather than some
4180other window.
4181
4182An element of this list can be a cons cell instead of just a
4183string. In that case, the cell's car must be a regexp matching
4184the buffer name. This is for compatibility with
4185`special-display-regexps'; the cdr of the cons cell is ignored.
4186
4187See also `same-window-buffer-names'."
4188 :type '(repeat (regexp :format "%v"))
4189 :group 'windows)
4190
4191(defun same-window-p (buffer-name)
4192 "Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
4193This function returns non-nil if `display-buffer' or
4194`pop-to-buffer' would show a buffer named BUFFER-NAME in the
4195selected rather than \(as usual\) some other window. See
4196`same-window-buffer-names' and `same-window-regexps'."
4197 (cond
4198 ((not (stringp buffer-name)))
4199 ;; The elements of `same-window-buffer-names' can be buffer
4200 ;; names or cons cells whose cars are buffer names.
4201 ((member buffer-name same-window-buffer-names))
4202 ((assoc buffer-name same-window-buffer-names))
4203 ((catch 'found
4204 (dolist (regexp same-window-regexps)
4205 ;; The elements of `same-window-regexps' can be regexps
4206 ;; or cons cells whose cars are regexps.
4207 (when (or (and (stringp regexp)
4208 (string-match regexp buffer-name))
4209 (and (consp regexp) (stringp (car regexp))
4210 (string-match-p (car regexp) buffer-name)))
4211 (throw 'found t)))))))
4212
6385(defcustom pop-up-frames nil 4213(defcustom pop-up-frames nil
6386 "Whether `display-buffer' should make a separate frame. 4214 "Whether `display-buffer' should make a separate frame.
6387If nil, never make a separate frame. 4215If nil, never make a separate frame.
@@ -6392,17 +4220,15 @@ Any other non-nil value means always make a separate frame."
6392 (const :tag "Never" nil) 4220 (const :tag "Never" nil)
6393 (const :tag "On graphic displays only" graphic-only) 4221 (const :tag "On graphic displays only" graphic-only)
6394 (const :tag "Always" t)) 4222 (const :tag "Always" t))
6395 :group 'windows 4223 :group 'windows)
6396 :group 'frames)
6397 4224
6398(defcustom display-buffer-reuse-frames nil 4225(defcustom display-buffer-reuse-frames nil
6399 "Set and non-nil means `display-buffer' should reuse frames. 4226 "Non-nil means `display-buffer' should reuse frames.
6400If the buffer in question is already displayed in a frame, raise 4227If the buffer in question is already displayed in a frame, raise
6401that frame." 4228that frame."
6402 :type 'boolean 4229 :type 'boolean
6403 :version "21.1" 4230 :version "21.1"
6404 :group 'windows 4231 :group 'windows)
6405 :group 'frames)
6406 4232
6407(defcustom pop-up-windows t 4233(defcustom pop-up-windows t
6408 "Non-nil means `display-buffer' should make a new window." 4234 "Non-nil means `display-buffer' should make a new window."
@@ -6410,21 +4236,23 @@ that frame."
6410 :group 'windows) 4236 :group 'windows)
6411 4237
6412(defcustom split-window-preferred-function 'split-window-sensibly 4238(defcustom split-window-preferred-function 'split-window-sensibly
6413 "Function called by `display-buffer' to split a window. 4239 "Function called by `display-buffer' routines to split a window.
6414This function is called with a window as single argument and is 4240This function is called with a window as single argument and is
6415supposed to split that window and return the new window. If the 4241supposed to split that window and return the new window. If the
6416window can (or shall) not be split, it is supposed to return nil. 4242window can (or shall) not be split, it is supposed to return nil.
6417
6418The default is to call the function `split-window-sensibly' which 4243The default is to call the function `split-window-sensibly' which
6419tries to split the window in a way which seems most suitable. 4244tries to split the window in a way which seems most suitable.
6420You can customize the options `split-height-threshold' and/or 4245You can customize the options `split-height-threshold' and/or
6421`split-width-threshold' in order to have `split-window-sensibly' 4246`split-width-threshold' in order to have `split-window-sensibly'
6422prefer either vertical or horizontal splitting. 4247prefer either vertical or horizontal splitting.
6423 4248
6424If you set this to any other function, bear in mind that 4249If you set this to any other function, bear in mind that the
6425`display-buffer' may call that function repeatedly; the option 4250`display-buffer' routines may call this function two times. The
6426`pop-up-windows' controls which windows may become the argument 4251argument of the first call is the largest window on its frame.
6427of this function. 4252If that call fails to return a live window, the function is
4253called again with the least recently used window as argument. If
4254that call fails too, `display-buffer' will use an existing window
4255to display its buffer.
6428 4256
6429The window selected at the time `display-buffer' was invoked is 4257The window selected at the time `display-buffer' was invoked is
6430still selected when this function is called. Hence you can 4258still selected when this function is called. Hence you can
@@ -6436,38 +4264,27 @@ not want to split the selected window."
6436 :group 'windows) 4264 :group 'windows)
6437 4265
6438(defcustom split-height-threshold 80 4266(defcustom split-height-threshold 80
6439 "Minimum height for splitting a window to display a buffer. 4267 "Minimum height for splitting windows sensibly.
6440If this is an integer, `display-buffer' can split a window 4268If this is an integer, `split-window-sensibly' may split a window
6441vertically only if it has at least this many lines. If this is 4269vertically only if it has at least this many lines. If this is
6442nil, `display-buffer' does not split windows vertically. If a 4270nil, `split-window-sensibly' is not allowed to split a window
6443window is the only window on its frame, `display-buffer' may 4271vertically. If, however, a window is the only window on its
6444split it vertically disregarding the value of this variable." 4272frame, `split-window-sensibly' may split it vertically
4273disregarding the value of this variable."
6445 :type '(choice (const nil) (integer :tag "lines")) 4274 :type '(choice (const nil) (integer :tag "lines"))
6446 :version "23.1" 4275 :version "23.1"
6447 :group 'windows) 4276 :group 'windows)
6448 4277
6449(defcustom split-width-threshold 160 4278(defcustom split-width-threshold 160
6450 "Minimum width for splitting a window to display a buffer. 4279 "Minimum width for splitting windows sensibly.
6451If this is an integer, `display-buffer' can split a window 4280If this is an integer, `split-window-sensibly' may split a window
6452horizontally only if it has at least this many columns. If this 4281horizontally only if it has at least this many columns. If this
6453is nil, `display-buffer' cannot split windows horizontally." 4282is nil, `split-window-sensibly' is not allowed to split a window
4283horizontally."
6454 :type '(choice (const nil) (integer :tag "columns")) 4284 :type '(choice (const nil) (integer :tag "columns"))
6455 :version "23.1" 4285 :version "23.1"
6456 :group 'windows) 4286 :group 'windows)
6457 4287
6458(defcustom even-window-heights t
6459 "If non-nil `display-buffer' will try to even window heights.
6460Otherwise `display-buffer' will leave the window configuration
6461alone. Heights are evened only when `display-buffer' chooses a
6462window that appears above or below the selected window."
6463 :type 'boolean
6464 :group 'windows)
6465
6466(defvar display-buffer-mark-dedicated nil
6467 "Non-nil means `display-buffer' marks the windows it creates as dedicated.
6468The actual non-nil value of this variable will be copied to the
6469`window-dedicated-p' flag.")
6470
6471(defun window-splittable-p (window &optional horizontal) 4288(defun window-splittable-p (window &optional horizontal)
6472 "Return non-nil if `split-window-sensibly' may split WINDOW. 4289 "Return non-nil if `split-window-sensibly' may split WINDOW.
6473Optional argument HORIZONTAL nil or omitted means check whether 4290Optional argument HORIZONTAL nil or omitted means check whether
@@ -6549,11 +4366,11 @@ more likely to occur.
6549Have a look at the function `window-splittable-p' if you want to 4366Have a look at the function `window-splittable-p' if you want to
6550know how `split-window-sensibly' determines whether WINDOW can be 4367know how `split-window-sensibly' determines whether WINDOW can be
6551split." 4368split."
6552 (or (and (with-no-warnings (window-splittable-p window)) 4369 (or (and (window-splittable-p window)
6553 ;; Split window vertically. 4370 ;; Split window vertically.
6554 (with-selected-window window 4371 (with-selected-window window
6555 (split-window-vertically))) 4372 (split-window-vertically)))
6556 (and (with-no-warnings (window-splittable-p window t)) 4373 (and (window-splittable-p window t)
6557 ;; Split window horizontally. 4374 ;; Split window horizontally.
6558 (with-selected-window window 4375 (with-selected-window window
6559 (split-window-horizontally))) 4376 (split-window-horizontally)))
@@ -6563,236 +4380,583 @@ split."
6563 ;; minibuffer window, try to split it vertically disregarding 4380 ;; minibuffer window, try to split it vertically disregarding
6564 ;; the value of `split-height-threshold'. 4381 ;; the value of `split-height-threshold'.
6565 (let ((split-height-threshold 0)) 4382 (let ((split-height-threshold 0))
6566 (when (with-no-warnings (window-splittable-p window)) 4383 (when (window-splittable-p window)
6567 (with-selected-window window 4384 (with-selected-window window
6568 (split-window-vertically))))))) 4385 (split-window-vertically)))))))
6569 4386
6570;; Functions for converting Emacs 23 buffer display options to buffer 4387(defun window--try-to-split-window (window)
6571;; display specifiers. 4388 "Try to split WINDOW.
6572(defun display-buffer-alist-of-strings-p (list) 4389Return value returned by `split-window-preferred-function' if it
6573 "Return t if LIST is a non-empty list of strings." 4390represents a live window, nil otherwise."
6574 (when list 4391 (and (window-live-p window)
6575 (catch 'failed 4392 (not (frame-parameter (window-frame window) 'unsplittable))
6576 (dolist (item list) 4393 (let ((new-window
6577 (unless (stringp item) 4394 ;; Since `split-window-preferred-function' might
6578 (throw 'failed nil))) 4395 ;; throw an error use `condition-case'.
6579 t))) 4396 (condition-case nil
6580 4397 (funcall split-window-preferred-function window)
6581(defun display-buffer-alist-add (identifiers specifiers &optional no-custom) 4398 (error nil))))
6582 "Helper function for `display-buffer-alist-set'." 4399 (and (window-live-p new-window) new-window))))
6583 (unless identifiers 4400
6584 (setq identifiers '((regexp . ".*")))) 4401(defun window--frame-usable-p (frame)
6585 (unless (atom specifiers) 4402 "Return FRAME if it can be used to display a buffer."
6586 (setq specifiers (delq nil specifiers))) 4403 (when (frame-live-p frame)
6587 4404 (let ((window (frame-root-window frame)))
6588 (if no-custom 4405 ;; `frame-root-window' may be an internal window which is considered
6589 (setq display-buffer-alist 4406 ;; "dead" by `window-live-p'. Hence if `window' is not live we
6590 (cons (cons identifiers specifiers) display-buffer-alist)) 4407 ;; implicitly know that `frame' has a visible window we can use.
6591 (customize-set-variable 4408 (unless (and (window-live-p window)
6592 'display-buffer-alist 4409 (or (window-minibuffer-p window)
6593 (cons (cons identifiers specifiers) display-buffer-alist)))) 4410 ;; If the window is soft-dedicated, the frame is usable.
6594 4411 ;; Actually, even if the window is really dedicated,
6595(defun display-buffer-alist-set-1 () 4412 ;; the frame is still usable by splitting it.
6596 "Helper function for `display-buffer-alist-set'." 4413 ;; At least Emacs-22 allowed it, and it is desirable
6597 (progn ;; with-no-warnings 4414 ;; when displaying same-frame windows.
6598 (append 4415 nil ; (eq t (window-dedicated-p window))
6599 '(reuse-window (reuse-window nil same 0)) 4416 ))
6600 `(pop-up-frame (pop-up-frame t) 4417 frame))))
6601 ,(append '(pop-up-frame-alist) 4418
6602 special-display-frame-alist)) 4419(defcustom even-window-heights t
6603 '((dedicate . weak))))) 4420 "If non-nil `display-buffer' will try to even window heights.
6604 4421Otherwise `display-buffer' will leave the window configuration
6605(defun display-buffer-alist-set-2 (args) 4422alone. Heights are evened only when `display-buffer' chooses a
6606 "Helper function for `display-buffer-alist-set'." 4423window that appears above or below the selected window."
6607 (progn ;; with-no-warnings 4424 :type 'boolean
6608 (if (and (listp args) (symbolp (car args))) 4425 :group 'windows)
6609 `(function (function ,(car args) ,(cdr args))) 4426
6610 (append 4427(defun window--even-window-heights (window)
6611 '(reuse-window (reuse-window nil same 0)) 4428 "Even heights of WINDOW and selected window.
6612 (when (and (listp args) (cdr (assq 'same-window args))) 4429Do this only if these windows are vertically adjacent to each
6613 '(reuse-window 4430other, `even-window-heights' is non-nil, and the selected window
6614 (reuse-window same nil nil) (reuse-window-dedicated . weak))) 4431is higher than WINDOW."
6615 (when (and (listp args) 4432 (when (and even-window-heights
6616 (or (cdr (assq 'same-frame args)) 4433 (not (eq window (selected-window)))
6617 (cdr (assq 'same-window args)))) 4434 ;; Don't resize minibuffer windows.
6618 '(pop-up-window (pop-up-window (largest . nil) (lru . nil)))) 4435 (not (window-minibuffer-p (selected-window)))
6619 (when (and (listp args) 4436 (> (window-height (selected-window)) (window-height window))
6620 (or (cdr (assq 'same-frame args)) 4437 (eq (window-frame window) (window-frame (selected-window)))
6621 (cdr (assq 'same-window args)))) 4438 (let ((sel-edges (window-edges (selected-window)))
6622 '(reuse-window (reuse-window nil nil nil))) 4439 (win-edges (window-edges window)))
6623 `(pop-up-frame (pop-up-frame t) 4440 (and (= (nth 0 sel-edges) (nth 0 win-edges))
6624 ,(append '(pop-up-frame-alist) 4441 (= (nth 2 sel-edges) (nth 2 win-edges))
6625 (when (listp args) args) 4442 (or (= (nth 1 sel-edges) (nth 3 win-edges))
6626 special-display-frame-alist)) 4443 (= (nth 3 sel-edges) (nth 1 win-edges))))))
6627 '((dedicate . weak)))))) 4444 (let ((window-min-height 1))
6628 4445 ;; Don't throw an error if we can't even window heights for
6629(defun display-buffer-alist-set (&optional no-custom add) 4446 ;; whatever reason.
6630 "Set `display-buffer-alist' from Emacs 23 buffer display options. 4447 (condition-case nil
6631Optional argument NO-CUSTOM nil means use `customize-set-variable' 4448 (enlarge-window (/ (- (window-height window) (window-height)) 2))
6632to set the value of `display-buffer-alist'. NO-CUSTOM non-nil 4449 (error nil)))))
6633means to use `setq' instead. 4450
6634 4451(defun window--display-buffer-1 (window)
6635Optional argument ADD nil means to replace the actual value of 4452 "Raise the frame containing WINDOW.
6636`display-buffer-alist' with the value calculated here. ADD 4453Do not raise the selected frame. Return WINDOW."
6637non-nil means prepend the value calculated here to the current 4454 (let* ((frame (window-frame window))
6638value of `display-buffer-alist'. Return `display-buffer-alist'." 4455 (visible (frame-visible-p frame)))
6639 (unless add 4456 (unless (or (not visible)
6640 (if no-custom 4457 ;; Assume the selected frame is already visible enough.
6641 (setq display-buffer-alist nil) 4458 (eq frame (selected-frame))
6642 (customize-set-variable 'display-buffer-alist nil))) 4459 ;; Assume the frame from which we invoked the minibuffer
6643 4460 ;; is visible.
6644 ;; Disable warnings, there are too many obsolete options here. 4461 (and (minibuffer-window-active-p (selected-window))
6645 (progn ;; with-no-warnings 4462 (eq frame (window-frame (minibuffer-selected-window)))))
6646 `other-window-means-other-frame' 4463 (raise-frame frame))
6647 (when pop-up-frames 4464 window))
6648 (display-buffer-alist-add 4465
6649 nil '(pop-up-frame 4466(defun window--display-buffer-2 (buffer window &optional dedicated)
6650 (other-window-means-other-frame . t)) no-custom)) 4467 "Display BUFFER in WINDOW and make its frame visible.
6651 4468Set `window-dedicated-p' to DEDICATED if non-nil.
6652 ;; `reuse-window-even-sizes' 4469Return WINDOW."
6653 (when even-window-heights 4470 (when (and (buffer-live-p buffer) (window-live-p window))
6654 (display-buffer-alist-add 4471 (set-window-buffer window buffer)
6655 nil '(reuse-window (reuse-window-even-sizes . t)) no-custom)) 4472 (when dedicated
6656 4473 (set-window-dedicated-p window dedicated))
6657 ;; `dedicate' 4474 (window--display-buffer-1 window)))
6658 (when display-buffer-mark-dedicated 4475
6659 (display-buffer-alist-add 4476(defvar display-buffer-mark-dedicated nil
6660 nil '(dedicate (display-buffer-mark-dedicated . t)) no-custom)) 4477 "If non-nil, `display-buffer' marks the windows it creates as dedicated.
6661 4478The actual non-nil value of this variable will be copied to the
6662 ;; `pop-up-window' group 4479`window-dedicated-p' flag.")
6663 (let ((fun (unless (eq split-window-preferred-function 4480
6664 'split-window-sensibly) 4481(defun display-buffer-default (buffer-or-name &optional not-this-window frame)
6665 split-window-preferred-function)) 4482 "Make buffer BUFFER-OR-NAME appear in some window but don't select it.
6666 (min-height 4483BUFFER-OR-NAME must be a buffer or the name of an existing
6667 (if (numberp split-height-threshold) 4484buffer. Return the window chosen to display BUFFER-OR-NAME or
6668 (/ split-height-threshold 2) 4485nil if no such window is found.
6669 1.0)) 4486
6670 (min-width 4487Optional argument NOT-THIS-WINDOW non-nil means display the
6671 (if (numberp split-width-threshold) 4488buffer in a window other than the selected one, even if it is
6672 (/ split-width-threshold 2) 4489already displayed in the selected window.
6673 1.0))) 4490
6674 (display-buffer-alist-add 4491Optional argument FRAME specifies which frames to investigate
6675 nil 4492when the specified buffer is already displayed. If the buffer is
6676 (list 4493already displayed in some window on one of these frames simply
6677 'pop-up-window 4494return that window. Possible values of FRAME are:
6678 ;; `pop-up-window' 4495
6679 (when pop-up-windows 4496`visible' - consider windows on all visible frames on the current
6680 (list 'pop-up-window (cons 'largest fun) (cons 'lru fun))) 4497terminal.
6681 ;; `pop-up-window-min-height' 4498
6682 (cons 'pop-up-window-min-height min-height) 44990 - consider windows on all visible or iconified frames on the
6683 ;; `pop-up-window-min-width' 4500current terminal.
6684 (cons 'pop-up-window-min-width min-width)) 4501
6685 no-custom)) 4502t - consider windows on all frames.
6686 4503
6687 ;; `pop-up-frame' group 4504A specific frame - consider windows on that frame only.
6688 (when (or pop-up-frames 4505
6689 (not (equal pop-up-frame-function 4506nil - consider windows on the selected frame \(actually the
6690 '(lambda nil 4507last non-minibuffer frame\) only. If, however, either
6691 (make-frame pop-up-frame-alist)))) 4508`display-buffer-reuse-frames' or `pop-up-frames' is non-nil
6692 pop-up-frame-alist) 4509\(non-nil and not graphic-only on a text-only terminal),
6693 (display-buffer-alist-add 4510consider all visible or iconified frames on the current terminal."
6694 nil 4511 (interactive "BDisplay buffer:\nP")
6695 (list 4512 (let* ((can-use-selected-window
6696 'pop-up-frame 4513 ;; The selected window is usable unless either NOT-THIS-WINDOW
6697 (when pop-up-frames 4514 ;; is non-nil, it is dedicated to its buffer, or it is the
6698 ;; `pop-up-frame' 4515 ;; `minibuffer-window'.
6699 (list 'pop-up-frame 4516 (not (or not-this-window
6700 (when (eq pop-up-frames 'graphic-only) 4517 (window-dedicated-p (selected-window))
6701 t))) 4518 (window-minibuffer-p))))
6702 (unless (equal pop-up-frame-function 4519 (buffer (if (bufferp buffer-or-name)
6703 '(lambda nil 4520 buffer-or-name
6704 (make-frame pop-up-frame-alist))) 4521 (get-buffer buffer-or-name)))
6705 ;; `pop-up-frame-function' 4522 (name-of-buffer (buffer-name buffer))
6706 (cons 'pop-up-frame-function pop-up-frame-function)) 4523 ;; On text-only terminals do not pop up a new frame when
6707 (when pop-up-frame-alist 4524 ;; `pop-up-frames' equals graphic-only.
6708 ;; `pop-up-frame-alist' 4525 (use-pop-up-frames (if (eq pop-up-frames 'graphic-only)
6709 (cons 'pop-up-frame-alist pop-up-frame-alist))) 4526 (display-graphic-p)
6710 no-custom)) 4527 pop-up-frames))
6711 4528 ;; `frame-to-use' is the frame where to show `buffer' - either
6712 ;; `special-display-regexps' 4529 ;; the selected frame or the last nonminibuffer frame.
6713 (if (display-buffer-alist-of-strings-p special-display-regexps) 4530 (frame-to-use
6714 ;; Handle case where `special-display-regexps' is a plain list 4531 (or (window--frame-usable-p (selected-frame))
6715 ;; of strings specially. 4532 (window--frame-usable-p (last-nonminibuffer-frame))))
6716 (let (list) 4533 ;; `window-to-use' is the window we use for showing `buffer'.
6717 (dolist (regexp special-display-regexps) 4534 window-to-use popped-up-frame)
6718 (setq list (cons (cons 'regexp regexp) list))) 4535 (cond
6719 (setq list (nreverse list)) 4536 ((not (buffer-live-p buffer))
6720 (display-buffer-alist-add 4537 (error "No such buffer %s" buffer))
6721 list (display-buffer-alist-set-1) no-custom)) 4538 (display-buffer-function
6722 ;; Else iterate over the entries. 4539 ;; Let `display-buffer-function' do the job.
6723 (dolist (item special-display-regexps) 4540 (funcall display-buffer-function buffer not-this-window))
6724 (if (stringp item) 4541 ((and (not not-this-window)
6725 (display-buffer-alist-add 4542 (eq (window-buffer (selected-window)) buffer))
6726 `((regexp . ,item)) (display-buffer-alist-set-1) 4543 ;; The selected window already displays BUFFER and
6727 no-custom) 4544 ;; `not-this-window' is nil, so use it.
6728 (display-buffer-alist-add 4545 (display-buffer-record-window 'reuse-window (selected-window) buffer)
6729 `((regexp . ,(car item))) 4546 (window--display-buffer-1 (selected-window)))
6730 (display-buffer-alist-set-2 (cdr item)) 4547 ((and can-use-selected-window (same-window-p name-of-buffer))
6731 no-custom)))) 4548 ;; If the buffer's name tells us to use the selected window do so.
6732 4549 (display-buffer-record-window 'reuse-window (selected-window) buffer)
6733 ;; `special-display-buffer-names' 4550 (window--display-buffer-2 buffer (selected-window)))
6734 (if (display-buffer-alist-of-strings-p special-display-buffer-names) 4551 ((let ((frames (or frame
6735 ;; Handle case where `special-display-buffer-names' is a plain 4552 (and (or use-pop-up-frames
6736 ;; list of strings specially. 4553 display-buffer-reuse-frames
6737 (let (list) 4554 (not (last-nonminibuffer-frame)))
6738 (dolist (name special-display-buffer-names) 4555 0)
6739 (setq list (cons (cons 'name name) list))) 4556 (last-nonminibuffer-frame))))
6740 (setq list (nreverse list)) 4557 (setq window-to-use
6741 (display-buffer-alist-add 4558 (catch 'found
6742 list (display-buffer-alist-set-1) no-custom)) 4559 ;; Search frames for a window displaying BUFFER. Return
6743 ;; Else iterate over the entries. 4560 ;; the selected window only if we are allowed to do so.
6744 (dolist (item special-display-buffer-names) 4561 (dolist (window (get-buffer-window-list buffer 'nomini frames))
6745 (if (stringp item) 4562 (when (or can-use-selected-window
6746 (display-buffer-alist-add 4563 (not (eq (selected-window) window)))
6747 `((name . ,item)) (display-buffer-alist-set-1) 4564 (throw 'found window))))))
6748 no-custom) 4565 ;; The buffer is already displayed in some window; use that.
6749 (display-buffer-alist-add 4566 (display-buffer-record-window 'reuse-window window-to-use buffer)
6750 `((name . ,(car item))) 4567 (window--display-buffer-1 window-to-use))
6751 (display-buffer-alist-set-2 (cdr item)) 4568 ((and special-display-function
6752 no-custom)))) 4569 ;; `special-display-p' returns either t or a list of frame
6753 4570 ;; parameters to pass to `special-display-function'.
6754 ;; `same-window-regexps' 4571 (let ((pars (special-display-p name-of-buffer)))
6755 (if (display-buffer-alist-of-strings-p same-window-regexps) 4572 (when pars
6756 ;; Handle case where `same-window-regexps' is a plain list of 4573 (funcall special-display-function
6757 ;; strings specially. 4574 buffer (if (listp pars) pars))))))
6758 (let (list) 4575 ((or use-pop-up-frames (not frame-to-use))
6759 (dolist (regexp same-window-regexps) 4576 ;; We want or need a new frame.
6760 (setq list (cons (cons 'regexp regexp) list))) 4577 (setq window-to-use
6761 (setq list (nreverse list)) 4578 (frame-selected-window (funcall pop-up-frame-function)))
6762 (display-buffer-alist-add 4579 (display-buffer-record-window 'pop-up-frame window-to-use buffer)
6763 list '(reuse-window (reuse-window same nil nil)) no-custom)) 4580 (window--display-buffer-2 buffer window-to-use))
6764 (dolist (entry same-window-regexps) 4581 ((and pop-up-windows
6765 (display-buffer-alist-add 4582 ;; Make a new window.
6766 `((regexp . ,(if (stringp entry) entry (car entry)))) 4583 (or (not (frame-parameter frame-to-use 'unsplittable))
6767 '(reuse-window (reuse-window same nil nil)) no-custom))) 4584 ;; If the selected frame cannot be split look at
6768 4585 ;; `last-nonminibuffer-frame'.
6769 ;; `same-window-buffer-names' 4586 (and (eq frame-to-use (selected-frame))
6770 (if (display-buffer-alist-of-strings-p same-window-buffer-names) 4587 (setq frame-to-use (last-nonminibuffer-frame))
6771 ;; Handle case where `same-window-buffer-names' is a plain list 4588 (window--frame-usable-p frame-to-use)
6772 ;; of strings specially. 4589 (not (frame-parameter frame-to-use 'unsplittable))))
6773 (let (list) 4590 ;; Attempt to split largest or least recently used window.
6774 (dolist (name same-window-buffer-names) 4591 (setq window-to-use
6775 (setq list (cons (cons 'name name) list))) 4592 (or (window--try-to-split-window
6776 (setq list (nreverse list)) 4593 (get-largest-window frame-to-use t))
6777 (display-buffer-alist-add 4594 (window--try-to-split-window
6778 list '(reuse-window (reuse-window same nil nil)) no-custom)) 4595 (get-lru-window frame-to-use t))))
6779 (dolist (entry same-window-buffer-names) 4596 (display-buffer-record-window 'pop-up-window window-to-use buffer)
6780 (display-buffer-alist-add 4597 (window--display-buffer-2 buffer window-to-use)))
6781 `((name . ,(if (stringp entry) entry (car entry)))) 4598 ((let ((window-to-undedicate
6782 '(reuse-window (reuse-window same nil nil)) no-custom))) 4599 ;; When NOT-THIS-WINDOW is non-nil, temporarily dedicate
6783 4600 ;; the selected window to its buffer, to avoid that some of
6784 ;; `reuse-window' 4601 ;; the `get-' routines below choose it. (Bug#1415)
6785 (display-buffer-alist-add 4602 (and not-this-window (not (window-dedicated-p))
6786 nil `(reuse-window 4603 (set-window-dedicated-p (selected-window) t)
6787 (reuse-window 4604 (selected-window))))
6788 nil same 4605 (unwind-protect
6789 ,(when (or display-buffer-reuse-frames pop-up-frames) 4606 (setq window-to-use
6790 ;; "0" (all visible and iconified frames) is 4607 ;; Reuse an existing window.
6791 ;; hardcoded in Emacs 23. 4608 (or (get-lru-window frame-to-use)
6792 0))) 4609 (let ((window (get-buffer-window buffer 'visible)))
6793 no-custom) 4610 (unless (and not-this-window
6794 4611 (eq window (selected-window)))
6795 display-buffer-alist)) 4612 window))
4613 (get-largest-window 'visible)
4614 (let ((window (get-buffer-window buffer 0)))
4615 (unless (and not-this-window
4616 (eq window (selected-window)))
4617 window))
4618 (get-largest-window 0)
4619 (prog1
4620 (frame-selected-window (funcall pop-up-frame-function))
4621 (setq popped-up-frame t))))
4622 (when (window-live-p window-to-undedicate)
4623 ;; Restore dedicated status of selected window.
4624 (set-window-dedicated-p window-to-undedicate nil))))
4625 (display-buffer-record-window
4626 (if popped-up-frame 'pop-up-frame 'reuse-window) window-to-use buffer)
4627 (window--even-window-heights window-to-use)
4628 (window--display-buffer-2 buffer window-to-use)))))
4629
4630(defun window-normalize-buffer-to-display (buffer-or-name)
4631 "Normalize BUFFER-OR-NAME argument for buffer display functions.
4632If BUFFER-OR-NAME is nil, return the curent buffer. Else, if a
4633buffer specified by BUFFER-OR-NAME exists, return that buffer.
4634If no such buffer exists, create a buffer with the name
4635BUFFER-OR-NAME and return that buffer."
4636 (if buffer-or-name
4637 (or (get-buffer buffer-or-name)
4638 (let ((buffer (get-buffer-create buffer-or-name)))
4639 (set-buffer-major-mode buffer)
4640 buffer))
4641 (current-buffer)))
4642
4643(defvar display-buffer-alist nil
4644 "Specifications of user preferences for `display-buffer'.
4645This is a list of elements of the form (CONDITION . ACTION) where
4646CONDITION is either a regexp matching buffer names, or a function
4647that takes a buffer and returns a boolean. ACTION is a list of
4648the form (FUNCTION . ALIST) where FUNCTION can be either a
4649function or a list of functions. Those functions will be called
4650with 2 arguments: the buffer to display and an ALIST built from
4651the various alists specified in the various ACTIONs. It should
4652either return the window used, or nil to fallback to the next
4653function.")
4654
4655(defvar display-buffer-default-action (list #'display-buffer-default)
4656 "Default action to perform to display a buffer.
4657This is an ACTION just like in `display-buffer-alist'.")
4658
4659(defvar display-buffer-overriding-action '(nil)
4660 "Overriding action to perform to display a buffer.
4661This is an ACTION just like in `display-buffer-alist'.")
4662
4663(defun display-buffer-assq-regexp (buffer-name alist)
4664 "Retrieve ALIST entry corresponding to BUFFER-NAME."
4665 (catch 'match
4666 (dolist (entry alist)
4667 (let ((key (car entry))
4668 (value (cdr entry)))
4669 (when (or (and (stringp key)
4670 (string-match-p key buffer-name))
4671 (and (symbolp key) (functionp key)
4672 (funcall key buffer-name alist)))
4673 (throw 'match (cdr entry)))))))
4674
4675(defun display-buffer (&optional buffer-or-name action frame)
4676 "Display BUFFER in some window."
4677 (let* ((buffer (window-normalize-buffer-to-display buffer-or-name))
4678 (buffer-name (buffer-name buffer))
4679 (user-action
4680 (display-buffer-assq-regexp buffer-name display-buffer-alist))
4681 (functions
4682 (append
4683 (list (car display-buffer-overriding-action))
4684 (list (car user-action))
4685 (and (listp action) (list (car action)))
4686 (list (car display-buffer-default-action))))
4687 (specifiers (append (cdr display-buffer-overriding-action)
4688 (cdr user-action)
4689 (and (listp action) (cdr action))
4690 (cdr display-buffer-default-action)))
4691 function window)
4692 (while (and functions (not window))
4693 (setq function (car functions))
4694 (cond
4695 ((listp function)
4696 (while (and function (not window))
4697 (cond
4698 ((eq (car function) 'display-buffer-default)
4699 (setq window
4700 (display-buffer-default
4701 buffer (memq action '(t other-window)) frame)))
4702 ((functionp (car function))
4703 (setq window (funcall (car function) buffer specifiers))))
4704 (setq function (cdr function))))
4705 ((eq function 'display-buffer-default)
4706 (setq window
4707 (display-buffer-default
4708 buffer (memq action '(t other-window)) frame)))
4709 ((functionp function)
4710 (setq window
4711 (funcall function buffer specifiers))))
4712 (setq functions (cdr functions)))
4713
4714 window))
4715
4716(defun display-buffer-other-frame (buffer)
4717 "Display buffer BUFFER in another frame.
4718This uses the function `display-buffer' as a subroutine; see
4719its documentation for additional customization information."
4720 (interactive "BDisplay buffer in other frame: ")
4721 (let ((pop-up-frames t)
4722 same-window-buffer-names same-window-regexps
4723 ;;(old-window (selected-window))
4724 new-window)
4725 (setq new-window (display-buffer buffer t))
4726 ;; This may have been here in order to prevent the new frame from hiding
4727 ;; the old frame. But it does more harm than good.
4728 ;; Maybe we should call `raise-window' on the old-frame instead? --Stef
4729 ;;(lower-frame (window-frame new-window))
4730
4731 ;; This may have been here in order to make sure the old-frame gets the
4732 ;; focus. But not only can it cause an annoying flicker, with some
4733 ;; window-managers it just makes the window invisible, with no easy
4734 ;; way to recover it. --Stef
4735 ;;(make-frame-invisible (window-frame old-window))
4736 ;;(make-frame-visible (window-frame old-window))
4737 ))
4738
4739(defun pop-to-buffer (buffer-or-name &optional other-window norecord)
4740 "Select buffer BUFFER-OR-NAME in some window, preferably a different one.
4741BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4742nil. If BUFFER-OR-NAME is a string not naming an existent
4743buffer, create a buffer with that name. If BUFFER-OR-NAME is
4744nil, choose some other buffer.
4745
4746If `pop-up-windows' is non-nil, windows can be split to display
4747the buffer. If optional second arg OTHER-WINDOW is non-nil,
4748insist on finding another window even if the specified buffer is
4749already visible in the selected window, and ignore
4750`same-window-regexps' and `same-window-buffer-names'.
4751
4752If the window to show BUFFER-OR-NAME is not on the selected
4753frame, raise that window's frame and give it input focus.
4754
4755This function returns the buffer it switched to. This uses the
4756function `display-buffer' as a subroutine; see the documentation
4757of `display-buffer' for additional customization information.
4758
4759Optional third arg NORECORD non-nil means do not put this buffer
4760at the front of the list of recently selected ones."
4761 (interactive "BPop to buffer:\nP")
4762 (let ((buffer (window-normalize-buffer-to-display buffer-or-name))
4763 (old-window (selected-window))
4764 (old-frame (selected-frame))
4765 new-window new-frame)
4766 (set-buffer buffer)
4767 (setq new-window (display-buffer buffer other-window))
4768 (setq new-frame (window-frame new-window))
4769 (if (eq old-frame new-frame)
4770 ;; Make sure new-window gets selected (Bug#8615), (Bug#6954).
4771 (select-window new-window norecord)
4772 ;; `display-buffer' has chosen another frame, make sure it gets
4773 ;; input focus and is risen.
4774 (select-frame-set-input-focus new-frame norecord))
4775 buffer))
4776
4777(defun pop-to-buffer-same-window (&optional buffer-or-name norecord)
4778 "Pop to buffer specified by BUFFER-OR-NAME in the selected window.
4779Another window will be used only if the buffer can't be shown in
4780the selected window, usually because it is dedicated to another
4781buffer. Optional arguments BUFFER-OR-NAME and NORECORD are as
4782for `pop-to-buffer'."
4783 (interactive "BPop to buffer in selected window:\nP")
4784 (let ((buffer (window-normalize-buffer-to-display buffer-or-name)))
4785 (cond
4786 ((eq buffer (window-buffer))
4787 (unless norecord
4788 (select-window (selected-window)))
4789 (set-buffer buffer))
4790 ((or (window-minibuffer-p) (window-dedicated-p))
4791 (pop-to-buffer buffer norecord))
4792 (t
4793 (set-window-buffer nil buffer)
4794 (unless norecord
4795 (select-window (selected-window)))
4796 (set-buffer buffer)))))
4797
4798(defun pop-to-buffer-other-window (&optional buffer-or-name norecord)
4799 "Pop to buffer specified by BUFFER-OR-NAME in another window.
4800The selected window will be used only if there is no other
4801choice. Windows on the selected frame are preferred to windows
4802on other frames. Optional arguments BUFFER-OR-NAME and NORECORD
4803are as for `pop-to-buffer'."
4804 (interactive "BPop to buffer in another window:\nP")
4805 (let ((pop-up-windows t)
4806 same-window-buffer-names same-window-regexps)
4807 (pop-to-buffer buffer-or-name t norecord)))
4808
4809(defun pop-to-buffer-other-frame (&optional buffer-or-name norecord)
4810 "Pop to buffer specified by BUFFER-OR-NAME on another frame.
4811The selected frame will be used only if there's no other choice.
4812Optional arguments BUFFER-OR-NAME and NORECORD are as for
4813`pop-to-buffer'."
4814 (interactive "BPop to buffer on another frame:\nP")
4815 (let ((pop-up-frames t)
4816 same-window-buffer-names same-window-regexps)
4817 (pop-to-buffer buffer-or-name t norecord)))
4818
4819(defun read-buffer-to-switch (prompt)
4820 "Read the name of a buffer to switch to, prompting with PROMPT.
4821Return the neame of the buffer as a string.
4822
4823This function is intended for the `switch-to-buffer' family of
4824commands since these need to omit the name of the current buffer
4825from the list of completions and default values."
4826 (let ((rbts-completion-table (internal-complete-buffer-except)))
4827 (minibuffer-with-setup-hook
4828 (lambda ()
4829 (setq minibuffer-completion-table rbts-completion-table)
4830 ;; Since rbts-completion-table is built dynamically, we
4831 ;; can't just add it to the default value of
4832 ;; icomplete-with-completion-tables, so we add it
4833 ;; here manually.
4834 (if (and (boundp 'icomplete-with-completion-tables)
4835 (listp icomplete-with-completion-tables))
4836 (set (make-local-variable 'icomplete-with-completion-tables)
4837 (cons rbts-completion-table
4838 icomplete-with-completion-tables))))
4839 (read-buffer prompt (other-buffer (current-buffer))
4840 (confirm-nonexistent-file-or-buffer)))))
4841
4842(defun window-normalize-buffer-to-switch-to (buffer-or-name)
4843 "Normalize BUFFER-OR-NAME argument of buffer switching functions.
4844If BUFFER-OR-NAME is nil, return the buffer returned by
4845`other-buffer'. Else, if a buffer specified by BUFFER-OR-NAME
4846exists, return that buffer. If no such buffer exists, create a
4847buffer with the name BUFFER-OR-NAME and return that buffer."
4848 (if buffer-or-name
4849 (or (get-buffer buffer-or-name)
4850 (let ((buffer (get-buffer-create buffer-or-name)))
4851 (set-buffer-major-mode buffer)
4852 buffer))
4853 (other-buffer)))
4854
4855(defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
4856 "Switch to buffer BUFFER-OR-NAME in the selected window.
4857If called interactively, prompt for the buffer name using the
4858minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4859determines whether to request confirmation before creating a new
4860buffer.
4861
4862BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4863nil. If BUFFER-OR-NAME is a string that does not identify an
4864existing buffer, create a buffer with that name. If
4865BUFFER-OR-NAME is nil, switch to the buffer returned by
4866`other-buffer'.
4867
4868Optional argument NORECORD non-nil means do not put the buffer
4869specified by BUFFER-OR-NAME at the front of the buffer list and
4870do not make the window displaying it the most recently selected
4871one.
4872
4873If FORCE-SAME-WINDOW is non-nil, BUFFER-OR-NAME must be displayed
4874in the currently selected window; signal an error if that is
4875impossible (e.g. if the selected window is minibuffer-only).
4876If non-nil, BUFFER-OR-NAME may be displayed in another window.
4877
4878Return the buffer switched to."
4879 (interactive
4880 (list (read-buffer-to-switch "Switch to buffer: ") nil nil))
4881 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
4882 (if (null force-same-window)
4883 (cond
4884 ((eq buffer (window-buffer))
4885 (unless norecord
4886 (select-window (selected-window)))
4887 (set-buffer buffer))
4888 ((or (window-minibuffer-p) (window-dedicated-p))
4889 (pop-to-buffer buffer))
4890 (t
4891 (set-window-buffer nil buffer)
4892 (unless norecord
4893 (select-window (selected-window)))
4894 (set-buffer buffer)))
4895 (cond
4896 ;; Don't call set-window-buffer if it's not needed since it
4897 ;; might signal an error (e.g. if the window is dedicated).
4898 ((eq buffer (window-buffer)))
4899 ((window-minibuffer-p)
4900 (error "Cannot switch buffers in minibuffer window"))
4901 ((eq (window-dedicated-p) t)
4902 (error "Cannot switch buffers in a dedicated window"))
4903 (t (set-window-buffer nil buffer)))
4904
4905 (unless norecord
4906 (select-window (selected-window)))
4907 (set-buffer buffer))))
4908
4909(defun switch-to-buffer-other-window (buffer-or-name &optional norecord)
4910 "Select the buffer specified by BUFFER-OR-NAME in another window.
4911BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4912nil. Return the buffer switched to.
4913
4914If called interactively, prompt for the buffer name using the
4915minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4916determines whether to request confirmation before creating a new
4917buffer.
4918
4919If BUFFER-OR-NAME is a string and does not identify an existing
4920buffer, create a new buffer with that name. If BUFFER-OR-NAME is
4921nil, switch to the buffer returned by `other-buffer'.
4922
4923Optional second argument NORECORD non-nil means do not put this
4924buffer at the front of the list of recently selected ones.
4925
4926This uses the function `display-buffer' as a subroutine; see its
4927documentation for additional customization information."
4928 (interactive
4929 (list (read-buffer-to-switch "Switch to buffer in other window: ")))
4930 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
4931 (pop-up-windows t)
4932 same-window-buffer-names same-window-regexps)
4933 (pop-to-buffer buffer t norecord)))
4934
4935(defun switch-to-buffer-other-frame (buffer-or-name &optional norecord)
4936 "Switch to buffer BUFFER-OR-NAME in another frame.
4937BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
4938nil. Return the buffer switched to.
4939
4940If called interactively, prompt for the buffer name using the
4941minibuffer. The variable `confirm-nonexistent-file-or-buffer'
4942determines whether to request confirmation before creating a new
4943buffer.
4944
4945If BUFFER-OR-NAME is a string and does not identify an existing
4946buffer, create a new buffer with that name. If BUFFER-OR-NAME is
4947nil, switch to the buffer returned by `other-buffer'.
4948
4949Optional second arg NORECORD non-nil means do not put this
4950buffer at the front of the list of recently selected ones.
4951
4952This uses the function `display-buffer' as a subroutine; see its
4953documentation for additional customization information."
4954 (interactive
4955 (list (read-buffer-to-switch "Switch to buffer in other frame: ")))
4956 (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
4957 (pop-up-frames t)
4958 same-window-buffer-names same-window-regexps)
4959 (pop-to-buffer buffer t norecord)))
6796 4960
6797(defun set-window-text-height (window height) 4961(defun set-window-text-height (window height)
6798 "Set the height in lines of the text display area of WINDOW to HEIGHT. 4962 "Set the height in lines of the text display area of WINDOW to HEIGHT.