* window.el (display-buffer-function, special-display-p)
(special-display-buffer-names, special-display-regexps) (special-display-function, same-window-p, same-window-buffer-names) (same-window-regexps, pop-up-frames, display-buffer-reuse-frames) (pop-up-frame-function, pop-up-windows) (split-window-preferred-function, split-height-threshold) (split-width-threshold, window--splittable-p) (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) (pop-to-buffer): Move from window.c and buffer.c. (split-window-preferred-horizontally): Remove. * cus-start.el: Remove corresponding declarations. * window.c (pop_up_windows, pop_up_frames) (display_buffer_reuse_frames, Vpop_up_frame_function) (Vdisplay_buffer_function, Veven_window_heights) (Vspecial_display_buffer_names, Vspecial_display_regexps) (Vspecial_display_function, Vsame_window_buffer_names) (Vsame_window_regexps, split_height_threshold) (Vsplit_window_preferred_function): Move those vars to window.el. (display_buffer_1, Fspecial_display_p, Fsame_window_p) (Fdisplay_buffer): Move those functions to window.el. (syms_of_window): Remove corresponding declarations. (display_buffer): New function. (temp_output_buffer_show, Fother_window_for_scrolling): Use it. * dispnew.c (Flast_nonminibuf_frame): New function. * buffer.c (Fpop_to_buffer): Move to window.el.
This commit is contained in:
parent
9e0e0d77da
commit
87478b52f9
9 changed files with 590 additions and 662 deletions
|
@ -1,3 +1,19 @@
|
|||
2008-06-05 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* window.el (display-buffer-function, special-display-p)
|
||||
(special-display-buffer-names, special-display-regexps)
|
||||
(special-display-function, same-window-p, same-window-buffer-names)
|
||||
(same-window-regexps, pop-up-frames, display-buffer-reuse-frames)
|
||||
(pop-up-frame-function, pop-up-windows)
|
||||
(split-window-preferred-function, split-height-threshold)
|
||||
(split-width-threshold, window--splittable-p)
|
||||
(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)
|
||||
(pop-to-buffer): Move from window.c and buffer.c.
|
||||
(split-window-preferred-horizontally): Remove.
|
||||
* cus-start.el: Remove corresponding declarations.
|
||||
|
||||
2008-06-05 Sam Steingold <sds@gnu.org>
|
||||
|
||||
* vc.el (vc-update): Use `save-some-buffers' instead of signaling
|
||||
|
|
|
@ -302,51 +302,7 @@ since it could result in memory overflow and make Emacs crash."
|
|||
"22.1")
|
||||
;; window.c
|
||||
(temp-buffer-show-function windows (choice (const nil) function))
|
||||
(display-buffer-function windows (choice (const nil) function))
|
||||
(pop-up-frames frames boolean)
|
||||
(pop-up-frame-function frames function)
|
||||
(special-display-buffer-names
|
||||
frames
|
||||
(repeat (choice :tag "Buffer"
|
||||
:value ""
|
||||
(string :format "%v")
|
||||
(cons :tag "With attributes"
|
||||
:format "%v"
|
||||
:value ("" . nil)
|
||||
(string :format "%v")
|
||||
(repeat :tag "Attributes"
|
||||
(cons :format "%v"
|
||||
(symbol :tag "Parameter")
|
||||
(sexp :tag "Value")))))))
|
||||
(special-display-regexps
|
||||
frames
|
||||
(repeat (choice :tag "Buffer"
|
||||
:value ""
|
||||
(regexp :format "%v")
|
||||
(cons :tag "With attributes"
|
||||
:format "%v"
|
||||
:value ("" . nil)
|
||||
(regexp :format "%v")
|
||||
(repeat :tag "Attributes"
|
||||
(cons :format "%v"
|
||||
(symbol :tag "Parameter")
|
||||
(sexp :tag "Value")))))))
|
||||
(special-display-function frames function)
|
||||
(same-window-buffer-names windows (repeat (string :format "%v")))
|
||||
(same-window-regexps windows (repeat (regexp :format "%v")))
|
||||
(pop-up-windows windows boolean)
|
||||
(even-window-heights windows boolean)
|
||||
(next-screen-context-lines windows integer)
|
||||
(split-height-threshold windows integer)
|
||||
(split-window-preferred-function
|
||||
windows
|
||||
(choice (const :tag "vertically" nil)
|
||||
;; FIXME: Add `sensibly' which chooses between
|
||||
;; vertical or horizontal splits depending on the size
|
||||
;; and shape of the window.
|
||||
(const :tag "horizontally"
|
||||
split-window-preferred-horizontally))
|
||||
"23.1")
|
||||
(window-min-height windows integer)
|
||||
(window-min-width windows integer)
|
||||
(scroll-preserve-screen-position
|
||||
|
@ -354,7 +310,6 @@ since it could result in memory overflow and make Emacs crash."
|
|||
(const :tag "Off (nil)" :value nil)
|
||||
(const :tag "Full screen (t)" :value t)
|
||||
(other :tag "Always" 1)) "22.1")
|
||||
(display-buffer-reuse-frames windows boolean "21.1")
|
||||
;; xdisp.c
|
||||
(scroll-step windows integer)
|
||||
(scroll-conservatively windows integer)
|
||||
|
|
575
lisp/window.el
575
lisp/window.el
|
@ -193,15 +193,15 @@ Anything else means restrict to the selected frame."
|
|||
(defalias 'some-window 'get-window-with-predicate)
|
||||
|
||||
;; This should probably be written in C (i.e., without using `walk-windows').
|
||||
(defun get-buffer-window-list (buffer &optional minibuf frame)
|
||||
(defun get-buffer-window-list (buffer &optional minibuf all-frames)
|
||||
"Return list of all windows displaying BUFFER, or nil if none.
|
||||
BUFFER can be a buffer or a buffer name.
|
||||
See `walk-windows' for the meaning of MINIBUF and FRAME."
|
||||
See `walk-windows' for the meaning of MINIBUF and ALL-FRAMES."
|
||||
(let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
|
||||
(walk-windows (function (lambda (window)
|
||||
(if (eq (window-buffer window) buffer)
|
||||
(setq windows (cons window windows)))))
|
||||
minibuf frame)
|
||||
minibuf all-frames)
|
||||
windows))
|
||||
|
||||
(defun minibuffer-window-active-p (window)
|
||||
|
@ -517,8 +517,538 @@ See also `window-area-factor' to change the relative size of specific buffers."
|
|||
;; (message "Done in %d rounds" round)
|
||||
))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defcustom display-buffer-function nil
|
||||
"If non-nil, function to call to handle `display-buffer'.
|
||||
It will receive two args, the buffer and a flag which if non-nil
|
||||
means that the currently selected window is not acceptable. It
|
||||
should choose or create a window, display the specified buffer in
|
||||
it, and return the window.
|
||||
|
||||
Commands such as `switch-to-buffer-other-window' and
|
||||
`find-file-other-window' work using this function."
|
||||
:type '(choice
|
||||
(const nil)
|
||||
(function :tag "function"))
|
||||
:group 'windows)
|
||||
|
||||
(defun special-display-p (buffer-name)
|
||||
"Return non-nil if a buffer named BUFFER-NAME gets a special frame.
|
||||
If the value is t, `display-buffer' or `pop-to-buffer' would
|
||||
create a special frame for that buffer using the default frame
|
||||
parameters.
|
||||
|
||||
If the value is a list, it is a list of frame parameters that
|
||||
would be used to make a frame for that buffer. The variables
|
||||
`special-display-buffer-names' and `special-display-regexps'
|
||||
control this."
|
||||
(cond
|
||||
((not (stringp buffer-name)))
|
||||
;; Make sure to return t in the following two cases.
|
||||
((member buffer-name special-display-buffer-names) t)
|
||||
((assoc buffer-name special-display-buffer-names) t)
|
||||
((catch 'found
|
||||
(dolist (regexp special-display-regexps)
|
||||
(cond
|
||||
((stringp regexp)
|
||||
(when (string-match-p regexp buffer-name)
|
||||
(throw 'found t)))
|
||||
((and (consp regexp) (stringp (car regexp))
|
||||
(string-match-p (car regexp) buffer-name))
|
||||
(throw 'found (cdr regexp)))))))))
|
||||
|
||||
(defcustom special-display-buffer-names nil
|
||||
"List of buffer names that should have their own special frames.
|
||||
Displaying a buffer with `display-buffer' or `pop-to-buffer', if
|
||||
its name is in this list, makes a special frame for it using
|
||||
`special-display-function'. See also `special-display-regexps'.
|
||||
|
||||
An element of the list can be a list instead of just a string.
|
||||
There are two ways to use a list as an element:
|
||||
(BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
|
||||
In the first case, the FRAME-PARAMETERS are pairs of the form
|
||||
\(PARAMETER . VALUE); these parameter values are used to create
|
||||
the frame. In the second case, FUNCTION is called with BUFFER as
|
||||
the first argument, followed by the OTHER-ARGS--it can display
|
||||
BUFFER in any way it likes. All this is done by the function
|
||||
found in `special-display-function'.
|
||||
|
||||
If the specified frame parameters include (same-buffer . t), the
|
||||
buffer is displayed in the currently selected window. Otherwise, if
|
||||
they include (same-frame . t), the buffer is displayed in a new window
|
||||
in the currently selected frame.
|
||||
|
||||
If this variable appears \"not to work\", because you add a name to it
|
||||
but that buffer still appears in the selected window, look at the
|
||||
values of `same-window-buffer-names' and `same-window-regexps'.
|
||||
Those variables take precedence over this one."
|
||||
:type '(repeat (choice :tag "Buffer"
|
||||
:value ""
|
||||
(string :format "%v")
|
||||
(cons :tag "With attributes"
|
||||
:format "%v"
|
||||
:value ("" . nil)
|
||||
(string :format "%v")
|
||||
(repeat :tag "Attributes"
|
||||
(cons :format "%v"
|
||||
(symbol :tag "Parameter")
|
||||
(sexp :tag "Value"))))))
|
||||
:group 'frames)
|
||||
|
||||
(defcustom special-display-regexps nil
|
||||
"List of regexps saying which buffers should have their own special frames.
|
||||
When displaying a buffer with `display-buffer' or
|
||||
`pop-to-buffer', if any regexp in this list matches the buffer
|
||||
name, it makes a special frame for the buffer by calling
|
||||
`special-display-function'.
|
||||
|
||||
An element of the list can be a list instead of just a string.
|
||||
There are two ways to use a list as an element:
|
||||
(REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
|
||||
In the first case, the FRAME-PARAMETERS are pairs of the form
|
||||
\(PARAMETER . VALUE); these parameter values are used to create
|
||||
the frame. In the second case, FUNCTION is called with BUFFER as
|
||||
the first argument, followed by the OTHER-ARGS--it can display
|
||||
the buffer in any way it likes. All this is done by the function
|
||||
found in `special-display-function'.
|
||||
|
||||
If the specified frame parameters include (same-buffer . t), the
|
||||
buffer is displayed in the currently selected window. Otherwise,
|
||||
if they include (same-frame . t), the buffer is displayed in a
|
||||
new window in the currently selected frame.
|
||||
|
||||
If this variable appears \"not to work\", because you add a
|
||||
regexp to it but the matching buffers still appear in the
|
||||
selected window, look at the values of `same-window-buffer-names'
|
||||
and `same-window-regexps'. Those variables take precedence over
|
||||
this one."
|
||||
:type '(repeat (choice :tag "Buffer"
|
||||
:value ""
|
||||
(regexp :format "%v")
|
||||
(cons :tag "With attributes"
|
||||
:format "%v"
|
||||
:value ("" . nil)
|
||||
(regexp :format "%v")
|
||||
(repeat :tag "Attributes"
|
||||
(cons :format "%v"
|
||||
(symbol :tag "Parameter")
|
||||
(sexp :tag "Value"))))))
|
||||
:group 'frames)
|
||||
|
||||
(defcustom special-display-function 'special-display-popup-frame
|
||||
"Function to call to make a new frame for a special buffer.
|
||||
It is called with two arguments, the buffer and optional buffer
|
||||
specific data, and should return a window displaying that buffer.
|
||||
The default value normally makes a separate frame for the buffer,
|
||||
using `special-display-frame-alist' to specify the frame
|
||||
parameters.
|
||||
|
||||
But if the buffer specific data includes (same-buffer . t) then
|
||||
the buffer is displayed in the current selected window.
|
||||
Otherwise if it includes (same-frame . t) then the buffer is
|
||||
displayed in a new window in the currently selected frame.
|
||||
|
||||
A buffer is special if it is listed in
|
||||
`special-display-buffer-names' or matches a regexp in
|
||||
`special-display-regexps'."
|
||||
:type 'function
|
||||
:group 'frames)
|
||||
|
||||
(defun same-window-p (buffer-name)
|
||||
"Return non-nil if a buffer named BUFFER-NAME would be shown in the \"same\" window.
|
||||
This function returns non-nil if `display-buffer' or
|
||||
`pop-to-buffer' would show a buffer named BUFFER-NAME in the
|
||||
selected rather than \(as usual\) some other window. See
|
||||
`same-window-buffer-names' and `same-window-regexps'."
|
||||
(cond
|
||||
((not (stringp buffer-name)))
|
||||
;; The elements of `same-window-buffer-names' can be buffer
|
||||
;; names or cons cells whose cars are buffer names.
|
||||
((member buffer-name same-window-buffer-names))
|
||||
((assoc buffer-name same-window-buffer-names))
|
||||
((catch 'found
|
||||
(dolist (regexp same-window-regexps)
|
||||
;; The elements of `same-window-regexps' can be regexps
|
||||
;; or cons cells whose cars are regexps.
|
||||
(when (or (and (stringp regexp)
|
||||
(string-match regexp buffer-name))
|
||||
(and (consp regexp) (stringp (car regexp))
|
||||
(string-match-p (car regexp) buffer-name)))
|
||||
(throw 'found t)))))))
|
||||
|
||||
(defcustom same-window-buffer-names nil
|
||||
"List of names of buffers that should appear in the \"same\" window.
|
||||
`display-buffer' and `pop-to-buffer' show a buffer whose name is
|
||||
on this list in the selected rather than some other window.
|
||||
|
||||
An element of this list can be a cons cell instead of just a
|
||||
string. In that case the car must be a string specifying the
|
||||
buffer name. This is for compatibility with
|
||||
`special-display-buffer-names'; the cdr of the cons cell is
|
||||
ignored.
|
||||
|
||||
See also `same-window-regexps'."
|
||||
:type '(repeat (string :format "%v"))
|
||||
:group 'windows)
|
||||
|
||||
(defcustom same-window-regexps nil
|
||||
"List of regexps saying which buffers should appear in the \"same\" window.
|
||||
`display-buffer' and `pop-to-buffer' show a buffer whose name
|
||||
matches a regexp on this list in the selected rather than some
|
||||
other window.
|
||||
|
||||
An element of this list can be a cons cell instead of just a
|
||||
string. In that case the car must be a string, which specifies
|
||||
the buffer name. This is for compatibility with
|
||||
`special-display-buffer-names'; the cdr of the cons cell is
|
||||
ignored.
|
||||
|
||||
See also `same-window-buffer-names'."
|
||||
:type '(repeat (regexp :format "%v"))
|
||||
:group 'windows)
|
||||
|
||||
(defcustom pop-up-frames nil
|
||||
"Non-nil means `display-buffer' should make a separate frame."
|
||||
:type 'boolean
|
||||
:group 'windows)
|
||||
|
||||
(defcustom display-buffer-reuse-frames nil
|
||||
"Non-nil means `display-buffer' should reuse frames.
|
||||
If the buffer in question is already displayed in a frame, raise
|
||||
that frame."
|
||||
:type 'boolean
|
||||
:version "21.1"
|
||||
:group 'windows)
|
||||
|
||||
(defcustom pop-up-frame-function nil
|
||||
"Function to call to handle automatic new frame creation.
|
||||
It is called with no arguments and should return a newly created frame.
|
||||
|
||||
A typical value might be
|
||||
|
||||
`(lambda () (new-frame pop-up-frame-alist))'
|
||||
|
||||
where `pop-up-frame-alist' would hold the default frame
|
||||
parameters."
|
||||
:type '(choice
|
||||
(const nil)
|
||||
(function :tag "function"))
|
||||
:group 'windows)
|
||||
|
||||
(defcustom pop-up-windows t
|
||||
"Non-nil means `display-buffer' should make a new window."
|
||||
:type 'boolean
|
||||
:group 'windows)
|
||||
|
||||
(defcustom split-window-preferred-function nil
|
||||
"How `display-buffer' shall split windows.
|
||||
Choices are `Vertically', `Horizontally', and `Sensibly' where
|
||||
the latter attempts to split wide windows horizontally, narrow
|
||||
ones vertically. Alternatively, you can set this to a function
|
||||
called with a window as single argument to split that window in
|
||||
two and return the new window."
|
||||
:type '(choice
|
||||
(const :tag "Vertically" nil)
|
||||
(const :tag "Horizontally" horizontally)
|
||||
(const :tag "Sensibly" sensibly)
|
||||
(function :tag "Function"))
|
||||
:version "23.1"
|
||||
:group 'windows)
|
||||
|
||||
(defcustom split-height-threshold 80
|
||||
"Minimum height of window to be split vertically by `display-buffer'.
|
||||
If there is only one window, it can be split regardless of this."
|
||||
:type 'number
|
||||
:version "23.1"
|
||||
:group 'windows)
|
||||
|
||||
(defcustom split-width-threshold 160
|
||||
"Minimum width of window to be split horizontally by `display-buffer'.
|
||||
If there is only one window, it can be split regardless of this."
|
||||
:type 'number
|
||||
:version "23.1"
|
||||
:group 'windows)
|
||||
|
||||
(defun window--splittable-p (window &optional horizontal)
|
||||
"Return non-nil if window WINDOW can be split evenly.
|
||||
Optional argument HORIZONTAL non-nil means check whether WINDOW
|
||||
can be split horizontally.
|
||||
|
||||
WINDOW can be split vertically when the following conditions
|
||||
hold:
|
||||
|
||||
- `window-size-fixed' is either nil or equals `width' for the buffer of
|
||||
WINDOW.
|
||||
|
||||
- WINDOW is at least as high as `split-height-threshold' or it is
|
||||
the only window on its frame.
|
||||
|
||||
- When WINDOW is split evenly, the emanating windows are at least
|
||||
`window-min-height' lines tall and can accomodate at least one
|
||||
line plus - if WINDOW has one - a modeline.
|
||||
|
||||
WINDOW can be split horizontally when the following conditions
|
||||
hold:
|
||||
|
||||
- `window-size-fixed' is either nil or equals `height' for the
|
||||
buffer of WINDOW.
|
||||
|
||||
- WINDOW is at least as wide as `split-width-threshold'.
|
||||
|
||||
- When WINDOW is split evenly, the emanating windows are at least
|
||||
`window-min-width' or two (whichever is larger) columns wide."
|
||||
(when (window-live-p window)
|
||||
(with-selected-window window
|
||||
(if horizontal
|
||||
;; A window can be split horizontally when its width is not
|
||||
;; fixed, it is at least `split-width-threshold' columns wide
|
||||
;; and at least twice as wide as `window-min-width' and 2 (the
|
||||
;; latter value is hardcoded).
|
||||
(and (memq window-size-fixed '(nil height))
|
||||
(>= (window-width window)
|
||||
(max split-width-threshold
|
||||
(* 2 (max window-min-width 2)))))
|
||||
;; A window can be split vertically when its height is not
|
||||
;; fixed, it is at least `split-height-threshold' lines high or
|
||||
;; the only window on its frame, and it is at least twice as
|
||||
;; high as `window-min-height' and 2 if it has a modeline or 1.
|
||||
(and (memq window-size-fixed '(nil width))
|
||||
(>= (window-height window)
|
||||
(max (if (one-window-p 'nomini) 0 split-height-threshold)
|
||||
(* 2 (max window-min-height
|
||||
(if mode-line-format 2 1))))))))))
|
||||
|
||||
(defun window--try-to-split-window (window)
|
||||
"Split window WINDOW if it is splittable.
|
||||
See `split-window-preferred-function' for how WINDOW shall be
|
||||
split. See `window--splittable-p' for how to determine whether a
|
||||
window is splittable. If WINDOW can be split, return the value
|
||||
returned by `split-window' or `split-window-preferred-function'."
|
||||
(when (and (window-live-p window)
|
||||
;; Testing `window-full-width-p' here hardly makes any
|
||||
;; sense nowadays. This can be done more intuitively by
|
||||
;; setting up `split-width-threshold' appropriately.
|
||||
(not (frame-parameter (window-frame window) 'unsplittable)))
|
||||
(or (and (not split-window-preferred-function)
|
||||
(window--splittable-p window)
|
||||
(split-window window))
|
||||
(and (eq split-window-preferred-function 'horizontally)
|
||||
(window--splittable-p window t)
|
||||
(split-window window nil t))
|
||||
(and (eq split-window-preferred-function 'sensibly)
|
||||
;; The following naive aspect-ratio test should become
|
||||
;; more sensible.
|
||||
(or (and (> (window-width window) (window-height window))
|
||||
(window--splittable-p window t)
|
||||
(split-window window nil t))
|
||||
(and (window--splittable-p window)
|
||||
(split-window window))))
|
||||
(and (functionp split-window-preferred-function)
|
||||
(funcall split-window-preferred-function window)))))
|
||||
|
||||
(defun window--frame-usable-p (frame)
|
||||
"Return frame FRAME if it can be used to display another buffer."
|
||||
(let ((window (frame-root-window frame)))
|
||||
(when (or (not (window-live-p window))
|
||||
(and (not (window-minibuffer-p window))
|
||||
(not (window-dedicated-p window))))
|
||||
frame)))
|
||||
|
||||
(defcustom even-window-heights t
|
||||
"If non-nil `display-buffer' will try to even window heights.
|
||||
Otherwise `display-buffer' will leave the window configuration
|
||||
alone. Heights are evened only when `display-buffer' chooses a
|
||||
window that appears above or below the selected window."
|
||||
:type 'boolean
|
||||
:group 'windows)
|
||||
|
||||
(defun window--even-window-heights (window)
|
||||
"Even heights of window WINDOW and selected window.
|
||||
Do this only if these windows are vertically adjacent to each
|
||||
other and `even-window-heights' is non-nil."
|
||||
(when (and even-window-heights
|
||||
(not (eq window (selected-window)))
|
||||
;; Don't resize minibuffer windows.
|
||||
(not (window-minibuffer-p (selected-window)))
|
||||
(/= (window-height (selected-window)) (window-height window))
|
||||
(eq (window-frame window) (window-frame (selected-window)))
|
||||
(let ((sel-edges (window-edges (selected-window)))
|
||||
(win-edges (window-edges window)))
|
||||
(and (= (nth 0 sel-edges) (nth 0 win-edges))
|
||||
(= (nth 2 sel-edges) (nth 2 win-edges))
|
||||
(or (= (nth 1 sel-edges) (nth 3 win-edges))
|
||||
(= (nth 3 sel-edges) (nth 1 win-edges))))))
|
||||
(let ((window-min-height 1))
|
||||
;; Don't throw an error if we can't even window heights for
|
||||
;; whatever reason.
|
||||
(condition-case nil
|
||||
(enlarge-window (/ (- (window-height window) (window-height)) 2))
|
||||
(error nil)))))
|
||||
|
||||
(defun window--display-buffer-1 (window)
|
||||
"Deiconify the frame containing the window WINDOW.
|
||||
Do not deiconify the selected frame. Return WINDOW."
|
||||
(let* ((frame (window-frame window))
|
||||
(visible (frame-visible-p frame)))
|
||||
(unless (or (not visible)
|
||||
;; Assume the selected frame is already visible enough.
|
||||
(eq frame (selected-frame))
|
||||
;; Assume the frame from which we invoked the minibuffer
|
||||
;; is visible.
|
||||
(and (minibuffer-window-active-p (selected-window))
|
||||
(eq frame (window-frame (minibuffer-selected-window)))))
|
||||
(when (eq visible 'icon)
|
||||
(make-frame-visible frame))
|
||||
(raise-frame frame))
|
||||
window))
|
||||
|
||||
(defun window--display-buffer-2 (buffer window)
|
||||
"Display buffer BUFFER in window WINDOW and make its frame visible.
|
||||
Return WINDOW."
|
||||
(when (and (buffer-live-p buffer) (window-live-p window))
|
||||
(set-window-buffer window buffer)
|
||||
(window--display-buffer-1 window)))
|
||||
|
||||
(defun display-buffer (buffer-or-name &optional not-this-window frame)
|
||||
"Make buffer BUFFER-OR-NAME appear in some window but don't select it.
|
||||
BUFFER-OR-NAME must be a buffer or the name of an existing
|
||||
buffer. Return the window chosen to display BUFFER-OR-NAME or
|
||||
nil is no such window is found.
|
||||
|
||||
Optional argument NOT-THIS-WINDOW non-nil means display the
|
||||
buffer in a window other than the selected one, even if it is
|
||||
already displayed in the selected window.
|
||||
|
||||
Optional argument FRAME specifies which frames to investigate
|
||||
when the specified buffer is already displayed. If the buffer is
|
||||
already displayed in some window on one of these frames simply
|
||||
return that window. Possible values of FRAME are:
|
||||
|
||||
`visible' - consider windows on all visible frames.
|
||||
|
||||
0 - consider windows on all visible or iconified frames.
|
||||
|
||||
`t' - consider windows on all frames.
|
||||
|
||||
A specific frame - consider windows on that frame only.
|
||||
|
||||
`nil' - consider windows on the selected frame \(actually the
|
||||
last non-minibuffer frame\) only. If, however, either
|
||||
`display-buffer-reuse-frames' or `pop-up-frames' is non-nil,
|
||||
consider all visible or iconified frames."
|
||||
(interactive "BDisplay buffer:\nP")
|
||||
(let* ((can-use-selected-window
|
||||
;; The selected window is usable unless either NOT-THIS-WINDOW
|
||||
;; is non-nil, it is dedicated to its buffer, or it is the
|
||||
;; `minibuffer-window'.
|
||||
(not (or not-this-window
|
||||
(window-dedicated-p (selected-window))
|
||||
(window-minibuffer-p))))
|
||||
(buffer (if (bufferp buffer-or-name)
|
||||
buffer-or-name
|
||||
(get-buffer buffer-or-name)))
|
||||
(name-of-buffer (buffer-name buffer))
|
||||
;; `frame-to-use' is the frame where to show `buffer' - either
|
||||
;; the selected frame or the last nonminibuffer frame.
|
||||
(frame-to-use
|
||||
(or (window--frame-usable-p (selected-frame))
|
||||
(window--frame-usable-p (last-nonminibuffer-frame))))
|
||||
;; `window-to-use' is the window we use for showing `buffer'.
|
||||
window-to-use)
|
||||
(cond
|
||||
((not (buffer-live-p buffer))
|
||||
(error "No such buffer %s" buffer))
|
||||
(display-buffer-function
|
||||
;; Let `display-buffer-function' do the job.
|
||||
(funcall display-buffer-function buffer not-this-window))
|
||||
((and (not not-this-window)
|
||||
(eq (window-buffer (selected-window)) buffer))
|
||||
;; The selected window already displays BUFFER and
|
||||
;; `not-this-window' is nil, so use it.
|
||||
(window--display-buffer-1 (selected-window)))
|
||||
((and can-use-selected-window (same-window-p name-of-buffer))
|
||||
;; If the buffer's name tells us to use the selected window do so.
|
||||
(window--display-buffer-2 buffer (selected-window)))
|
||||
((let ((frames (or frame
|
||||
(and (or pop-up-frames display-buffer-reuse-frames
|
||||
(not (last-nonminibuffer-frame)))
|
||||
0)
|
||||
(last-nonminibuffer-frame))))
|
||||
(and (setq window-to-use (get-buffer-window buffer frames))
|
||||
(or can-use-selected-window
|
||||
(not (eq (selected-window) window-to-use)))))
|
||||
;; If the buffer is already displayed in some window use that.
|
||||
(window--display-buffer-1 window-to-use))
|
||||
((and special-display-function
|
||||
;; `special-display-p' returns either t or a list of frame
|
||||
;; parameters to pass to `special-display-function'.
|
||||
(let ((pars (special-display-p name-of-buffer)))
|
||||
(when pars
|
||||
(funcall special-display-function
|
||||
(if (eq pars t) buffer pars))))))
|
||||
((or pop-up-frames (not frame-to-use))
|
||||
;; We want or need a new frame.
|
||||
(window--display-buffer-2
|
||||
buffer (frame-selected-window (funcall pop-up-frame-function))))
|
||||
((and pop-up-windows
|
||||
;; Make a new window.
|
||||
(or (not (frame-parameter frame-to-use 'unsplittable))
|
||||
;; If the selected frame cannot be split look at
|
||||
;; `last-nonminibuffer-frame'.
|
||||
(and (eq frame-to-use (selected-frame))
|
||||
(setq frame-to-use (last-nonminibuffer-frame))
|
||||
(window--frame-usable-p frame-to-use)
|
||||
(not (frame-parameter frame-to-use 'unsplittable))))
|
||||
;; Attempt to split largest or most recently used window.
|
||||
(setq window-to-use
|
||||
(or (window--try-to-split-window
|
||||
(get-largest-window frame-to-use t))
|
||||
(window--try-to-split-window
|
||||
(get-lru-window frame-to-use t))))
|
||||
(window--display-buffer-2 buffer window-to-use)))
|
||||
((setq window-to-use
|
||||
;; Reuse an existing window.
|
||||
(or (get-buffer-window buffer 'visible)
|
||||
(get-largest-window 'visible nil)
|
||||
(get-buffer-window buffer 0)
|
||||
(get-largest-window 0 nil)
|
||||
(frame-selected-window (funcall pop-up-frame-function))
|
||||
(get-lru-window t t)))
|
||||
(window--even-window-heights window-to-use)
|
||||
(window--display-buffer-2 buffer window-to-use)))))
|
||||
|
||||
(defun pop-to-buffer (buffer-or-name &optional other-window norecord)
|
||||
"Select buffer BUFFER-OR-NAME in some window, preferably a different one.
|
||||
BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
|
||||
nil. If BUFFER-OR-NAME is a string not naming an existent
|
||||
buffer, create a buffer with that name. If BUFFER-OR-NAME is
|
||||
nil, choose some other buffer.
|
||||
|
||||
If `pop-up-windows' is non-nil, windows can be split to display
|
||||
the buffer. If optional second arg OTHER-WINDOW is non-nil,
|
||||
insist on finding another window even if the specified buffer is
|
||||
already visible in the selected window, and ignore
|
||||
`same-window-regexps' and `same-window-buffer-names'.
|
||||
|
||||
This function returns the buffer it switched to. This uses the
|
||||
function `display-buffer' as a subroutine; see the documentation
|
||||
of `display-buffer' for additional customization information.
|
||||
|
||||
Optional third arg NORECORD non-nil means do not put this buffer
|
||||
at the front of the list of recently selected ones."
|
||||
(let ((buffer
|
||||
;; FIXME: This behavior is carried over from the previous C version
|
||||
;; of pop-to-buffer, but really we should use just
|
||||
;; `get-buffer' here.
|
||||
(if (null buffer-or-name) (other-buffer (current-buffer))
|
||||
(or (get-buffer buffer-or-name)
|
||||
(let ((buf (get-buffer-create buffer-or-name)))
|
||||
(set-buffer-major-mode buf)
|
||||
buf)))))
|
||||
(set-buffer buffer)
|
||||
(select-window (display-buffer buffer other-window) norecord)
|
||||
buffer))
|
||||
|
||||
;; I think this should be the default; I think people will prefer it--rms.
|
||||
(defcustom split-window-keep-point t
|
||||
"*If non-nil, \\[split-window-vertically] keeps the original point \
|
||||
|
@ -614,43 +1144,6 @@ The return value is the new, rightmost window."
|
|||
(setq size (+ (window-width) size)))
|
||||
(split-window-save-restore-data (split-window nil size t) old-w)))
|
||||
|
||||
(defun split-window-preferred-horizontally (window)
|
||||
"Split WINDOW horizontally or select an appropriate existing window.
|
||||
It is called by `display-buffer' to split windows horizontally
|
||||
when the option `split-window-preferred-function' is set to \"horizontally\".
|
||||
This function tries to match the implementation of vertical splitting
|
||||
in `display-buffer' as close as possible but with the logic of
|
||||
horizontal splitting. It returns a new window or an appropriate
|
||||
existing window if splitting is not eligible."
|
||||
(interactive)
|
||||
;; If the largest window is wide enough, eligible for splitting,
|
||||
;; and the only window, split it horizontally.
|
||||
(if (and window
|
||||
(not (frame-parameter (window-frame window) 'unsplittable))
|
||||
(one-window-p (window-frame window))
|
||||
(>= (window-width window) (* 2 window-min-width)))
|
||||
(split-window window nil t)
|
||||
;; Otherwise, if the LRU window is wide enough, eligible for
|
||||
;; splitting and selected or the only window, split it horizontally.
|
||||
(setq window (get-lru-window nil t))
|
||||
(if (and window
|
||||
(not (frame-parameter (window-frame window) 'unsplittable))
|
||||
(or (eq window (selected-window))
|
||||
(one-window-p (window-frame window)))
|
||||
(>= (window-width window) (* 2 window-min-width)))
|
||||
(split-window window nil t)
|
||||
;; Otherwise, if get-lru-window returns nil, try other approaches.
|
||||
(or
|
||||
(get-lru-window nil nil)
|
||||
;; Try visible frames first.
|
||||
(get-buffer-window (current-buffer) 'visible)
|
||||
(get-largest-window 'visible)
|
||||
;; If that didn't work, try iconified frames.
|
||||
(get-buffer-window (current-buffer) 0)
|
||||
(get-largest-window 0)
|
||||
;; As a last resort, make a new frame.
|
||||
(frame-selected-window (funcall pop-up-frame-function))))))
|
||||
|
||||
|
||||
(defun set-window-text-height (window height)
|
||||
"Sets the height in lines of the text display area of WINDOW to HEIGHT.
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2008-06-05 Martin Rudalics <rudalics@gmx.at>
|
||||
|
||||
* window.c (pop_up_windows, pop_up_frames)
|
||||
(display_buffer_reuse_frames, Vpop_up_frame_function)
|
||||
(Vdisplay_buffer_function, Veven_window_heights)
|
||||
(Vspecial_display_buffer_names, Vspecial_display_regexps)
|
||||
(Vspecial_display_function, Vsame_window_buffer_names)
|
||||
(Vsame_window_regexps, split_height_threshold)
|
||||
(Vsplit_window_preferred_function): Move those vars to window.el.
|
||||
(display_buffer_1, Fspecial_display_p, Fsame_window_p)
|
||||
(Fdisplay_buffer): Move those functions to window.el.
|
||||
(syms_of_window): Remove corresponding declarations.
|
||||
(display_buffer): New function.
|
||||
(temp_output_buffer_show, Fother_window_for_scrolling): Use it.
|
||||
* dispnew.c (Flast_nonminibuf_frame): New function.
|
||||
* buffer.c (Fpop_to_buffer): Move to window.el.
|
||||
|
||||
2008-06-05 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* data.c (set_internal): Fix up call to let_shadows_buffer_binding_p.
|
||||
|
|
37
src/buffer.c
37
src/buffer.c
|
@ -1811,42 +1811,6 @@ the window-buffer correspondences. */)
|
|||
return switch_to_buffer_1 (buffer, norecord);
|
||||
}
|
||||
|
||||
DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 3, 0,
|
||||
doc: /* Select buffer BUFFER in some window, preferably a different one.
|
||||
BUFFER may be a buffer, a string \(a buffer name), or nil.
|
||||
If BUFFER is a string which is not the name of an existing buffer,
|
||||
then this function creates a buffer with that name.
|
||||
If BUFFER is nil, then it chooses some other buffer.
|
||||
If `pop-up-windows' is non-nil, windows can be split to do this.
|
||||
If optional second arg OTHER-WINDOW is non-nil, insist on finding another
|
||||
window even if BUFFER is already visible in the selected window,
|
||||
and ignore `same-window-regexps' and `same-window-buffer-names'.
|
||||
This function returns the buffer it switched to.
|
||||
This uses the function `display-buffer' as a subroutine; see the documentation
|
||||
of `display-buffer' for additional customization information.
|
||||
|
||||
Optional third arg NORECORD non-nil means
|
||||
do not put this buffer at the front of the list of recently selected ones. */)
|
||||
(buffer, other_window, norecord)
|
||||
Lisp_Object buffer, other_window, norecord;
|
||||
{
|
||||
register Lisp_Object buf;
|
||||
if (NILP (buffer))
|
||||
buf = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
|
||||
else
|
||||
{
|
||||
buf = Fget_buffer (buffer);
|
||||
if (NILP (buf))
|
||||
{
|
||||
buf = Fget_buffer_create (buffer);
|
||||
Fset_buffer_major_mode (buf);
|
||||
}
|
||||
}
|
||||
Fset_buffer (buf);
|
||||
Fselect_window (Fdisplay_buffer (buf, other_window, Qnil), norecord);
|
||||
return buf;
|
||||
}
|
||||
|
||||
DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
|
||||
doc: /* Return the current buffer as a Lisp object. */)
|
||||
()
|
||||
|
@ -6269,7 +6233,6 @@ The function `kill-all-local-variables' runs this before doing anything else. *
|
|||
defsubr (&Skill_buffer);
|
||||
defsubr (&Sset_buffer_major_mode);
|
||||
defsubr (&Sswitch_to_buffer);
|
||||
defsubr (&Spop_to_buffer);
|
||||
defsubr (&Scurrent_buffer);
|
||||
defsubr (&Sset_buffer);
|
||||
defsubr (&Sbarf_if_buffer_read_only);
|
||||
|
|
|
@ -7061,6 +7061,17 @@ WINDOW nil or omitted means report on the selected window. */)
|
|||
return w->cursor_off_p ? Qnil : Qt;
|
||||
}
|
||||
|
||||
DEFUN ("last-nonminibuffer-frame", Flast_nonminibuf_frame,
|
||||
Slast_nonminibuf_frame, 0, 0, 0,
|
||||
doc: /* Value is last nonminibuffer frame. */)
|
||||
()
|
||||
{
|
||||
Lisp_Object frame;
|
||||
|
||||
XSETFRAME (frame, last_nonminibuf_frame);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Initialization
|
||||
|
@ -7079,6 +7090,7 @@ syms_of_display ()
|
|||
defsubr (&Ssend_string_to_terminal);
|
||||
defsubr (&Sinternal_show_cursor);
|
||||
defsubr (&Sinternal_show_cursor_p);
|
||||
defsubr (&Slast_nonminibuf_frame);
|
||||
|
||||
#if GLYPH_DEBUG
|
||||
defsubr (&Sdump_redisplay_history);
|
||||
|
|
|
@ -2865,7 +2865,6 @@ EXFUN (set_buffer_if_live, 1);
|
|||
EXFUN (Fbarf_if_buffer_read_only, 0);
|
||||
EXFUN (Fcurrent_buffer, 0);
|
||||
EXFUN (Fswitch_to_buffer, 2);
|
||||
EXFUN (Fpop_to_buffer, 3);
|
||||
EXFUN (Fother_buffer, 3);
|
||||
EXFUN (Foverlay_get, 2);
|
||||
EXFUN (Fbuffer_modified_p, 1);
|
||||
|
|
548
src/window.c
548
src/window.c
|
@ -52,8 +52,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
|
||||
|
||||
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configuration_p;
|
||||
Lisp_Object Qdisplay_buffer;
|
||||
Lisp_Object Qscroll_up, Qscroll_down;
|
||||
Lisp_Object Qwindow_size_fixed;
|
||||
|
||||
extern Lisp_Object Qleft_margin, Qright_margin;
|
||||
|
||||
static int displayed_window_lines P_ ((struct window *));
|
||||
|
@ -139,63 +141,10 @@ int mode_line_in_non_selected_windows;
|
|||
EMACS_INT window_min_height;
|
||||
EMACS_INT window_min_width;
|
||||
|
||||
/* Nonzero implies Fdisplay_buffer should create windows. */
|
||||
|
||||
int pop_up_windows;
|
||||
|
||||
/* Nonzero implies make new frames for Fdisplay_buffer. */
|
||||
|
||||
int pop_up_frames;
|
||||
|
||||
/* Nonzero means reuse existing frames for displaying buffers. */
|
||||
|
||||
int display_buffer_reuse_frames;
|
||||
|
||||
/* Non-nil means use this function instead of default */
|
||||
|
||||
Lisp_Object Vpop_up_frame_function;
|
||||
|
||||
/* Function to call to handle Fdisplay_buffer. */
|
||||
|
||||
Lisp_Object Vdisplay_buffer_function;
|
||||
|
||||
/* Non-nil means that Fdisplay_buffer should even the heights of windows. */
|
||||
|
||||
Lisp_Object Veven_window_heights;
|
||||
|
||||
/* List of buffer *names* for buffers that should have their own frames. */
|
||||
|
||||
Lisp_Object Vspecial_display_buffer_names;
|
||||
|
||||
/* List of regexps for buffer names that should have their own frames. */
|
||||
|
||||
Lisp_Object Vspecial_display_regexps;
|
||||
|
||||
/* Function to pop up a special frame. */
|
||||
|
||||
Lisp_Object Vspecial_display_function;
|
||||
|
||||
/* List of buffer *names* for buffers to appear in selected window. */
|
||||
|
||||
Lisp_Object Vsame_window_buffer_names;
|
||||
|
||||
/* List of regexps for buffer names to appear in selected window. */
|
||||
|
||||
Lisp_Object Vsame_window_regexps;
|
||||
|
||||
/* Hook run at end of temp_output_buffer_show. */
|
||||
|
||||
Lisp_Object Qtemp_buffer_show_hook;
|
||||
|
||||
/* Fdisplay_buffer always splits the largest window
|
||||
if that window is more than this high. */
|
||||
|
||||
EMACS_INT split_height_threshold;
|
||||
|
||||
/* How to split windows (horizontally/vertically/hybrid). */
|
||||
|
||||
Lisp_Object Vsplit_window_preferred_function;
|
||||
|
||||
/* Number of lines of continuity in scrolling by screenfuls. */
|
||||
|
||||
EMACS_INT next_screen_context_lines;
|
||||
|
@ -3639,339 +3588,13 @@ select_window_norecord (window)
|
|||
return Fselect_window (window, Qt);
|
||||
}
|
||||
|
||||
/* Deiconify the frame containing the window WINDOW,
|
||||
unless it is the selected frame;
|
||||
then return WINDOW.
|
||||
|
||||
The reason for the exception for the selected frame
|
||||
is that it seems better not to change the selected frames visibility
|
||||
merely because of displaying a different buffer in it.
|
||||
The deiconification is useful when a buffer gets shown in
|
||||
another frame that you were not using lately. */
|
||||
|
||||
static Lisp_Object
|
||||
display_buffer_1 (window)
|
||||
Lisp_Object window;
|
||||
Lisp_Object
|
||||
display_buffer (buffer, not_this_window_p, override_frame)
|
||||
Lisp_Object buffer, not_this_window_p, override_frame;
|
||||
{
|
||||
Lisp_Object frame = XWINDOW (window)->frame;
|
||||
FRAME_PTR f = XFRAME (frame);
|
||||
|
||||
FRAME_SAMPLE_VISIBILITY (f);
|
||||
|
||||
if (EQ (frame, selected_frame))
|
||||
; /* Assume the selected frame is already visible enough. */
|
||||
else if (minibuf_level > 0
|
||||
&& MINI_WINDOW_P (XWINDOW (selected_window))
|
||||
&& WINDOW_LIVE_P (minibuf_selected_window)
|
||||
&& EQ (frame, WINDOW_FRAME (XWINDOW (minibuf_selected_window))))
|
||||
; /* Assume the frame from which we invoked the minibuffer is visible. */
|
||||
else
|
||||
{
|
||||
if (FRAME_ICONIFIED_P (f))
|
||||
Fmake_frame_visible (frame);
|
||||
else if (FRAME_VISIBLE_P (f))
|
||||
Fraise_frame (frame);
|
||||
}
|
||||
|
||||
return window;
|
||||
return call3 (Qdisplay_buffer, buffer, not_this_window_p, override_frame);
|
||||
}
|
||||
|
||||
DEFUN ("special-display-p", Fspecial_display_p, Sspecial_display_p, 1, 1, 0,
|
||||
doc: /* Returns non-nil if a buffer named BUFFER-NAME gets a special frame.
|
||||
If the value is t, `display-buffer' or `pop-to-buffer' would create a
|
||||
special frame for that buffer using the default frame parameters.
|
||||
|
||||
If the value is a list, it is a list of frame parameters that would be used
|
||||
to make a frame for that buffer.
|
||||
The variables `special-display-buffer-names'
|
||||
and `special-display-regexps' control this. */)
|
||||
(buffer_name)
|
||||
Lisp_Object buffer_name;
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
CHECK_STRING (buffer_name);
|
||||
|
||||
tem = Fmember (buffer_name, Vspecial_display_buffer_names);
|
||||
if (!NILP (tem))
|
||||
return Qt;
|
||||
|
||||
tem = Fassoc (buffer_name, Vspecial_display_buffer_names);
|
||||
if (!NILP (tem))
|
||||
return XCDR (tem);
|
||||
|
||||
for (tem = Vspecial_display_regexps; CONSP (tem); tem = XCDR (tem))
|
||||
{
|
||||
Lisp_Object car = XCAR (tem);
|
||||
if (STRINGP (car)
|
||||
&& fast_string_match (car, buffer_name) >= 0)
|
||||
return Qt;
|
||||
else if (CONSP (car)
|
||||
&& STRINGP (XCAR (car))
|
||||
&& fast_string_match (XCAR (car), buffer_name) >= 0)
|
||||
return XCDR (car);
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("same-window-p", Fsame_window_p, Ssame_window_p, 1, 1, 0,
|
||||
doc: /* Returns non-nil if a buffer named BUFFER-NAME would use the same window.
|
||||
More precisely, if `display-buffer' or `pop-to-buffer' would display
|
||||
that buffer in the selected window rather than (as usual) in some other window.
|
||||
See `same-window-buffer-names' and `same-window-regexps'. */)
|
||||
(buffer_name)
|
||||
Lisp_Object buffer_name;
|
||||
{
|
||||
Lisp_Object tem;
|
||||
|
||||
CHECK_STRING (buffer_name);
|
||||
|
||||
tem = Fmember (buffer_name, Vsame_window_buffer_names);
|
||||
if (!NILP (tem))
|
||||
return Qt;
|
||||
|
||||
tem = Fassoc (buffer_name, Vsame_window_buffer_names);
|
||||
if (!NILP (tem))
|
||||
return Qt;
|
||||
|
||||
for (tem = Vsame_window_regexps; CONSP (tem); tem = XCDR (tem))
|
||||
{
|
||||
Lisp_Object car = XCAR (tem);
|
||||
if (STRINGP (car)
|
||||
&& fast_string_match (car, buffer_name) >= 0)
|
||||
return Qt;
|
||||
else if (CONSP (car)
|
||||
&& STRINGP (XCAR (car))
|
||||
&& fast_string_match (XCAR (car), buffer_name) >= 0)
|
||||
return Qt;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/* Use B so the default is (other-buffer). */
|
||||
DEFUN ("display-buffer", Fdisplay_buffer, Sdisplay_buffer, 1, 3,
|
||||
"BDisplay buffer: \nP",
|
||||
doc: /* Make BUFFER appear in some window but don't select it.
|
||||
BUFFER must be the name of an existing buffer, or, when called from Lisp,
|
||||
a buffer.
|
||||
If BUFFER is shown already in some window, just use that one,
|
||||
unless the window is the selected window and the optional second
|
||||
argument NOT-THIS-WINDOW is non-nil (interactively, with prefix arg).
|
||||
If `pop-up-frames' is non-nil, make a new frame if no window shows BUFFER.
|
||||
Returns the window displaying BUFFER.
|
||||
If `display-buffer-reuse-frames' is non-nil, and another frame is currently
|
||||
displaying BUFFER, then simply raise that frame.
|
||||
|
||||
The variables `special-display-buffer-names',
|
||||
`special-display-regexps', `same-window-buffer-names', and
|
||||
`same-window-regexps' customize how certain buffer names are handled.
|
||||
The latter two take effect only if NOT-THIS-WINDOW is nil.
|
||||
|
||||
If optional argument FRAME is `visible', check all visible frames
|
||||
for a window to use.
|
||||
If FRAME is 0, check all visible and iconified frames.
|
||||
If FRAME is t, check all frames.
|
||||
If FRAME is a frame, check only that frame.
|
||||
If FRAME is nil, check only the selected frame
|
||||
(actually the last nonminibuffer frame),
|
||||
unless `pop-up-frames' or `display-buffer-reuse-frames' is non-nil,
|
||||
which means search visible and iconified frames.
|
||||
|
||||
If a full-width window on a splittable frame is available to display
|
||||
the buffer, it may be split, subject to the value of the variable
|
||||
`split-height-threshold'.
|
||||
|
||||
If `even-window-heights' is non-nil, window heights will be evened out
|
||||
if displaying the buffer causes two vertically adjacent windows to be
|
||||
displayed. */)
|
||||
(buffer, not_this_window, frame)
|
||||
Lisp_Object buffer, not_this_window, frame;
|
||||
{
|
||||
register Lisp_Object window, tem, swp;
|
||||
struct frame *f;
|
||||
|
||||
swp = Qnil;
|
||||
buffer = Fget_buffer (buffer);
|
||||
CHECK_BUFFER (buffer);
|
||||
|
||||
if (!NILP (Vdisplay_buffer_function))
|
||||
return call2 (Vdisplay_buffer_function, buffer, not_this_window);
|
||||
|
||||
if (NILP (not_this_window)
|
||||
&& XBUFFER (XWINDOW (selected_window)->buffer) == XBUFFER (buffer))
|
||||
return display_buffer_1 (selected_window);
|
||||
|
||||
/* See if the user has specified this buffer should appear
|
||||
in the selected window. */
|
||||
if (NILP (not_this_window))
|
||||
{
|
||||
swp = Fsame_window_p (XBUFFER (buffer)->name);
|
||||
if (!NILP (swp) && !no_switch_window (selected_window))
|
||||
{
|
||||
Fswitch_to_buffer (buffer, Qnil);
|
||||
return display_buffer_1 (selected_window);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the user wants pop-up-frames or display-buffer-reuse-frames,
|
||||
look for a window showing BUFFER on any visible or iconified frame.
|
||||
Otherwise search only the current frame. */
|
||||
if (! NILP (frame))
|
||||
tem = frame;
|
||||
else if (pop_up_frames
|
||||
|| display_buffer_reuse_frames
|
||||
|| last_nonminibuf_frame == 0)
|
||||
XSETFASTINT (tem, 0);
|
||||
else
|
||||
XSETFRAME (tem, last_nonminibuf_frame);
|
||||
|
||||
window = Fget_buffer_window (buffer, tem);
|
||||
if (!NILP (window)
|
||||
&& (NILP (not_this_window) || !EQ (window, selected_window)))
|
||||
return display_buffer_1 (window);
|
||||
|
||||
/* Certain buffer names get special handling. */
|
||||
if (!NILP (Vspecial_display_function) && NILP (swp))
|
||||
{
|
||||
tem = Fspecial_display_p (XBUFFER (buffer)->name);
|
||||
if (EQ (tem, Qt))
|
||||
return call1 (Vspecial_display_function, buffer);
|
||||
if (CONSP (tem))
|
||||
return call2 (Vspecial_display_function, buffer, tem);
|
||||
}
|
||||
|
||||
/* If there are no frames open that have more than a minibuffer,
|
||||
we need to create a new frame. */
|
||||
if (pop_up_frames || last_nonminibuf_frame == 0)
|
||||
{
|
||||
window = Fframe_selected_window (call0 (Vpop_up_frame_function));
|
||||
Fset_window_buffer (window, buffer, Qnil);
|
||||
return display_buffer_1 (window);
|
||||
}
|
||||
|
||||
f = SELECTED_FRAME ();
|
||||
if (pop_up_windows
|
||||
|| FRAME_MINIBUF_ONLY_P (f)
|
||||
/* If the current frame is a special display frame,
|
||||
don't try to reuse its windows. */
|
||||
|| !NILP (XWINDOW (FRAME_ROOT_WINDOW (f))->dedicated))
|
||||
{
|
||||
Lisp_Object frames;
|
||||
struct gcpro gcpro1;
|
||||
GCPRO1 (buffer);
|
||||
|
||||
frames = Qnil;
|
||||
if (FRAME_MINIBUF_ONLY_P (f))
|
||||
XSETFRAME (frames, last_nonminibuf_frame);
|
||||
|
||||
/* Note that both Fget_largest_window and Fget_lru_window
|
||||
ignore minibuffers and dedicated windows.
|
||||
This means they can return nil. */
|
||||
|
||||
/* If the frame we would try to split cannot be split,
|
||||
try other frames. */
|
||||
if (FRAME_NO_SPLIT_P (NILP (frames) ? f : last_nonminibuf_frame))
|
||||
{
|
||||
/* Try visible frames first. */
|
||||
window = Fget_largest_window (Qvisible, Qt);
|
||||
/* If that didn't work, try iconified frames. */
|
||||
if (NILP (window))
|
||||
window = Fget_largest_window (make_number (0), Qt);
|
||||
#if 0 /* Don't try windows on other displays. */
|
||||
if (NILP (window))
|
||||
window = Fget_largest_window (Qt, Qt);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
window = Fget_largest_window (frames, Qt);
|
||||
|
||||
tem = Qnil;
|
||||
if (!NILP (Vsplit_window_preferred_function))
|
||||
tem = call1 (Vsplit_window_preferred_function, window);
|
||||
|
||||
if (!NILP (tem))
|
||||
window = tem;
|
||||
else
|
||||
/* If the largest window is tall enough, full-width, and either eligible
|
||||
for splitting or the only window, split it. */
|
||||
if (!NILP (window)
|
||||
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
|
||||
&& WINDOW_FULL_WIDTH_P (XWINDOW (window))
|
||||
&& (window_height (window) >= split_height_threshold
|
||||
|| (NILP (XWINDOW (window)->parent)))
|
||||
&& (window_height (window)
|
||||
>= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
|
||||
window = Fsplit_window (window, Qnil, Qnil);
|
||||
else
|
||||
{
|
||||
Lisp_Object upper, other;
|
||||
|
||||
window = Fget_lru_window (frames, Qt);
|
||||
/* If the LRU window is tall enough, and either eligible for
|
||||
splitting and selected or the only window, split it. */
|
||||
if (!NILP (window)
|
||||
&& ! FRAME_NO_SPLIT_P (XFRAME (XWINDOW (window)->frame))
|
||||
&& ((EQ (window, selected_window)
|
||||
&& window_height (window) >= split_height_threshold)
|
||||
|| (NILP (XWINDOW (window)->parent)))
|
||||
&& (window_height (window)
|
||||
>= (2 * window_min_size_2 (XWINDOW (window), 0, 0))))
|
||||
window = Fsplit_window (window, Qnil, Qnil);
|
||||
else
|
||||
window = Fget_lru_window (frames, Qnil);
|
||||
/* If Fget_lru_window returned nil, try other approaches. */
|
||||
|
||||
/* Try visible frames first. */
|
||||
if (NILP (window))
|
||||
window = Fget_buffer_window (buffer, Qvisible);
|
||||
if (NILP (window))
|
||||
window = Fget_largest_window (Qvisible, Qnil);
|
||||
/* If that didn't work, try iconified frames. */
|
||||
if (NILP (window))
|
||||
window = Fget_buffer_window (buffer, make_number (0));
|
||||
if (NILP (window))
|
||||
window = Fget_largest_window (make_number (0), Qnil);
|
||||
|
||||
#if 0 /* Don't try frames on other displays. */
|
||||
if (NILP (window))
|
||||
window = Fget_buffer_window (buffer, Qt);
|
||||
if (NILP (window))
|
||||
window = Fget_largest_window (Qt, Qnil);
|
||||
#endif
|
||||
/* As a last resort, make a new frame. */
|
||||
if (NILP (window))
|
||||
window = Fframe_selected_window (call0 (Vpop_up_frame_function));
|
||||
/* If window appears above or below another,
|
||||
even out their heights. */
|
||||
other = upper = Qnil;
|
||||
if (!NILP (XWINDOW (window)->prev))
|
||||
other = upper = XWINDOW (window)->prev;
|
||||
if (!NILP (XWINDOW (window)->next))
|
||||
other = XWINDOW (window)->next, upper = window;
|
||||
if (!NILP (other)
|
||||
&& !NILP (Veven_window_heights)
|
||||
/* Check that OTHER and WINDOW are vertically arrayed. */
|
||||
&& !EQ (XWINDOW (other)->top_line, XWINDOW (window)->top_line)
|
||||
&& (XFASTINT (XWINDOW (other)->total_lines)
|
||||
> XFASTINT (XWINDOW (window)->total_lines)))
|
||||
{
|
||||
int total = (XFASTINT (XWINDOW (other)->total_lines)
|
||||
+ XFASTINT (XWINDOW (window)->total_lines));
|
||||
enlarge_window (upper,
|
||||
total / 2 - XFASTINT (XWINDOW (upper)->total_lines),
|
||||
0);
|
||||
}
|
||||
}
|
||||
UNGCPRO;
|
||||
}
|
||||
else
|
||||
window = Fget_lru_window (Qnil, Qnil);
|
||||
|
||||
Fset_window_buffer (window, buffer, Qnil);
|
||||
return display_buffer_1 (window);
|
||||
}
|
||||
|
||||
|
||||
DEFUN ("force-window-update", Fforce_window_update, Sforce_window_update,
|
||||
0, 1, 0,
|
||||
doc: /* Force all windows to be updated on next redisplay.
|
||||
|
@ -4041,7 +3664,7 @@ temp_output_buffer_show (buf)
|
|||
call1 (Vtemp_buffer_show_function, buf);
|
||||
else
|
||||
{
|
||||
window = Fdisplay_buffer (buf, Qnil, Qnil);
|
||||
window = display_buffer (buf, Qnil, Qnil);
|
||||
|
||||
if (!EQ (XWINDOW (window)->frame, selected_frame))
|
||||
Fmake_frame_visible (WINDOW_FRAME (XWINDOW (window)));
|
||||
|
@ -5692,7 +5315,7 @@ specifies the window. This takes precedence over
|
|||
{
|
||||
window = Fget_buffer_window (Vother_window_scroll_buffer, Qnil);
|
||||
if (NILP (window))
|
||||
window = Fdisplay_buffer (Vother_window_scroll_buffer, Qt, Qnil);
|
||||
window = display_buffer (Vother_window_scroll_buffer, Qt, Qnil);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7453,6 +7076,9 @@ syms_of_window ()
|
|||
Qwindow_live_p = intern ("window-live-p");
|
||||
staticpro (&Qwindow_live_p);
|
||||
|
||||
Qdisplay_buffer = intern ("display-buffer");
|
||||
staticpro (&Qdisplay_buffer);
|
||||
|
||||
Qtemp_buffer_show_hook = intern ("temp-buffer-show-hook");
|
||||
staticpro (&Qtemp_buffer_show_hook);
|
||||
|
||||
|
@ -7474,21 +7100,6 @@ If this function is used, then it must do the entire job of showing
|
|||
the buffer; `temp-buffer-show-hook' is not run unless this function runs it. */);
|
||||
Vtemp_buffer_show_function = Qnil;
|
||||
|
||||
DEFVAR_LISP ("display-buffer-function", &Vdisplay_buffer_function,
|
||||
doc: /* If non-nil, function to call to handle `display-buffer'.
|
||||
It will receive two args, the buffer and a flag which if non-nil means
|
||||
that the currently selected window is not acceptable.
|
||||
It should choose or create a window, display the specified buffer in it,
|
||||
and return the window.
|
||||
Commands such as `switch-to-buffer-other-window' and `find-file-other-window'
|
||||
work using this function. */);
|
||||
Vdisplay_buffer_function = Qnil;
|
||||
|
||||
DEFVAR_LISP ("even-window-heights", &Veven_window_heights,
|
||||
doc: /* *If non-nil, `display-buffer' should even the window heights.
|
||||
If nil, `display-buffer' will leave the window configuration alone. */);
|
||||
Veven_window_heights = Qt;
|
||||
|
||||
DEFVAR_LISP ("minibuffer-scroll-window", &Vminibuf_scroll_window,
|
||||
doc: /* Non-nil means it is the window that C-M-v in minibuffer should scroll. */);
|
||||
Vminibuf_scroll_window = Qnil;
|
||||
|
@ -7503,148 +7114,14 @@ is displayed in the `mode-line' face. */);
|
|||
doc: /* If non-nil, this is a buffer and \\[scroll-other-window] should scroll its window. */);
|
||||
Vother_window_scroll_buffer = Qnil;
|
||||
|
||||
DEFVAR_BOOL ("pop-up-frames", &pop_up_frames,
|
||||
doc: /* *Non-nil means `display-buffer' should make a separate frame. */);
|
||||
pop_up_frames = 0;
|
||||
|
||||
DEFVAR_BOOL ("auto-window-vscroll", &auto_window_vscroll_p,
|
||||
doc: /* *Non-nil means to automatically adjust `window-vscroll' to view tall lines. */);
|
||||
auto_window_vscroll_p = 1;
|
||||
|
||||
DEFVAR_BOOL ("display-buffer-reuse-frames", &display_buffer_reuse_frames,
|
||||
doc: /* *Non-nil means `display-buffer' should reuse frames.
|
||||
If the buffer in question is already displayed in a frame, raise that frame. */);
|
||||
display_buffer_reuse_frames = 0;
|
||||
|
||||
DEFVAR_LISP ("pop-up-frame-function", &Vpop_up_frame_function,
|
||||
doc: /* Function to call to handle automatic new frame creation.
|
||||
It is called with no arguments and should return a newly created frame.
|
||||
|
||||
A typical value might be `(lambda () (new-frame pop-up-frame-alist))'
|
||||
where `pop-up-frame-alist' would hold the default frame parameters. */);
|
||||
Vpop_up_frame_function = Qnil;
|
||||
|
||||
DEFVAR_LISP ("special-display-buffer-names", &Vspecial_display_buffer_names,
|
||||
doc: /* *List of buffer names that should have their own special frames.
|
||||
Displaying a buffer with `display-buffer' or `pop-to-buffer',
|
||||
if its name is in this list, makes a special frame for it
|
||||
using `special-display-function'. See also `special-display-regexps'.
|
||||
|
||||
An element of the list can be a list instead of just a string.
|
||||
There are two ways to use a list as an element:
|
||||
(BUFFER FRAME-PARAMETERS...) (BUFFER FUNCTION OTHER-ARGS...)
|
||||
In the first case, the FRAME-PARAMETERS are pairs of the form
|
||||
\(PARAMETER . VALUE); these parameter values are used to create the frame.
|
||||
In the second case, FUNCTION is called with BUFFER as the first argument,
|
||||
followed by the OTHER-ARGS--it can display BUFFER in any way it likes.
|
||||
All this is done by the function found in `special-display-function'.
|
||||
|
||||
If the specified frame parameters include (same-buffer . t), the
|
||||
buffer is displayed in the currently selected window. Otherwise, if
|
||||
they include (same-frame . t), the buffer is displayed in a new window
|
||||
in the currently selected frame.
|
||||
|
||||
If this variable appears \"not to work\", because you add a name to it
|
||||
but that buffer still appears in the selected window, look at the
|
||||
values of `same-window-buffer-names' and `same-window-regexps'.
|
||||
Those variables take precedence over this one. */);
|
||||
Vspecial_display_buffer_names = Qnil;
|
||||
|
||||
DEFVAR_LISP ("special-display-regexps", &Vspecial_display_regexps,
|
||||
doc: /* *List of regexps saying which buffers should have their own special frames.
|
||||
When displaying a buffer with `display-buffer' or `pop-to-buffer',
|
||||
if any regexp in this list matches the buffer name, it makes a
|
||||
special frame for the buffer by calling `special-display-function'.
|
||||
|
||||
An element of the list can be a list instead of just a string.
|
||||
There are two ways to use a list as an element:
|
||||
(REGEXP FRAME-PARAMETERS...) (REGEXP FUNCTION OTHER-ARGS...)
|
||||
In the first case, the FRAME-PARAMETERS are pairs of the form
|
||||
\(PARAMETER . VALUE); these parameter values are used to create the frame.
|
||||
In the second case, FUNCTION is called with BUFFER as the first argument,
|
||||
followed by the OTHER-ARGS--it can display the buffer in any way it likes.
|
||||
All this is done by the function found in `special-display-function'.
|
||||
|
||||
If the specified frame parameters include (same-buffer . t), the
|
||||
buffer is displayed in the currently selected window. Otherwise, if
|
||||
they include (same-frame . t), the buffer is displayed in a new window
|
||||
in the currently selected frame.
|
||||
|
||||
If this variable appears \"not to work\", because you add a regexp to it
|
||||
but the matching buffers still appear in the selected window, look at the
|
||||
values of `same-window-buffer-names' and `same-window-regexps'.
|
||||
Those variables take precedence over this one. */);
|
||||
Vspecial_display_regexps = Qnil;
|
||||
|
||||
DEFVAR_LISP ("special-display-function", &Vspecial_display_function,
|
||||
doc: /* Function to call to make a new frame for a special buffer.
|
||||
It is called with two arguments, the buffer and optional buffer specific
|
||||
data, and should return a window displaying that buffer.
|
||||
The default value normally makes a separate frame for the buffer,
|
||||
using `special-display-frame-alist' to specify the frame parameters.
|
||||
But if the buffer specific data includes (same-buffer . t) then the
|
||||
buffer is displayed in the current selected window.
|
||||
Otherwise if it includes (same-frame . t) then the buffer is displayed in
|
||||
a new window in the currently selected frame.
|
||||
|
||||
A buffer is special if it is listed in `special-display-buffer-names'
|
||||
or matches a regexp in `special-display-regexps'. */);
|
||||
Vspecial_display_function = Qnil;
|
||||
|
||||
DEFVAR_LISP ("same-window-buffer-names", &Vsame_window_buffer_names,
|
||||
doc: /* *List of buffer names that should appear in the selected window.
|
||||
Displaying one of these buffers using `display-buffer' or `pop-to-buffer'
|
||||
switches to it in the selected window, rather than making it appear
|
||||
in some other window.
|
||||
|
||||
An element of the list can be a cons cell instead of just a string.
|
||||
Then the car must be a string, which specifies the buffer name.
|
||||
This is for compatibility with `special-display-buffer-names';
|
||||
the cdr of the cons cell is ignored.
|
||||
|
||||
See also `same-window-regexps'. */);
|
||||
Vsame_window_buffer_names = Qnil;
|
||||
|
||||
DEFVAR_LISP ("same-window-regexps", &Vsame_window_regexps,
|
||||
doc: /* *List of regexps saying which buffers should appear in the selected window.
|
||||
If a buffer name matches one of these regexps, then displaying it
|
||||
using `display-buffer' or `pop-to-buffer' switches to it
|
||||
in the selected window, rather than making it appear in some other window.
|
||||
|
||||
An element of the list can be a cons cell instead of just a string.
|
||||
Then the car must be a string, which specifies the buffer name.
|
||||
This is for compatibility with `special-display-buffer-names';
|
||||
the cdr of the cons cell is ignored.
|
||||
|
||||
See also `same-window-buffer-names'. */);
|
||||
Vsame_window_regexps = Qnil;
|
||||
|
||||
DEFVAR_BOOL ("pop-up-windows", &pop_up_windows,
|
||||
doc: /* *Non-nil means display-buffer should make new windows. */);
|
||||
pop_up_windows = 1;
|
||||
|
||||
DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines,
|
||||
doc: /* *Number of lines of continuity when scrolling by screenfuls. */);
|
||||
next_screen_context_lines = 2;
|
||||
|
||||
DEFVAR_INT ("split-height-threshold", &split_height_threshold,
|
||||
doc: /* *A window must be at least this tall to be eligible for splitting
|
||||
by `display-buffer'. The value is in line units.
|
||||
If there is only one window, it is split regardless of this value. */);
|
||||
split_height_threshold = 500;
|
||||
|
||||
DEFVAR_LISP ("split-window-preferred-function",
|
||||
&Vsplit_window_preferred_function,
|
||||
doc: /* Function to use to split a window.
|
||||
This is used by `display-buffer' to allow the user to choose whether
|
||||
to split windows horizontally or vertically or some mix of the two.
|
||||
When this variable is nil, `display-buffer' splits windows vertically.
|
||||
Otherwise, `display-buffer' calls this function to split a window.
|
||||
It is called with a window as single argument and should split it in two
|
||||
and return the new window, or return an appropriate existing window
|
||||
if splitting is not eligible. */);
|
||||
Vsplit_window_preferred_function = Qnil;
|
||||
|
||||
DEFVAR_INT ("window-min-height", &window_min_height,
|
||||
doc: /* Allow deleting windows less than this tall.
|
||||
The value is measured in line units. If a window wants a modeline it
|
||||
|
@ -7724,9 +7201,6 @@ with the relevant frame selected. */);
|
|||
defsubr (&Sdelete_window);
|
||||
defsubr (&Sset_window_buffer);
|
||||
defsubr (&Sselect_window);
|
||||
defsubr (&Sspecial_display_p);
|
||||
defsubr (&Ssame_window_p);
|
||||
defsubr (&Sdisplay_buffer);
|
||||
defsubr (&Sforce_window_update);
|
||||
defsubr (&Ssplit_window);
|
||||
defsubr (&Senlarge_window);
|
||||
|
|
|
@ -760,7 +760,6 @@ extern Lisp_Object Vmouse_event;
|
|||
|
||||
EXFUN (Fnext_window, 3);
|
||||
EXFUN (Fselect_window, 2);
|
||||
EXFUN (Fdisplay_buffer, 3);
|
||||
EXFUN (Fset_window_buffer, 3);
|
||||
EXFUN (Fset_window_hscroll, 2);
|
||||
EXFUN (Fwindow_hscroll, 1);
|
||||
|
|
Loading…
Add table
Reference in a new issue