38412
|
1 ;;; window.el --- GNU Emacs window commands aside from those written in C
|
773
|
2
|
64762
|
3 ;; Copyright (C) 1985, 1989, 1992, 1993, 1994, 2000, 2001, 2002,
|
68651
|
4 ;; 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
841
|
5
|
773
|
6 ;; Maintainer: FSF
|
39117
|
7 ;; Keywords: internal
|
36
|
8
|
|
9 ;; This file is part of GNU Emacs.
|
|
10
|
|
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
12 ;; it under the terms of the GNU General Public License as published by
|
707
|
13 ;; the Free Software Foundation; either version 2, or (at your option)
|
36
|
14 ;; any later version.
|
|
15
|
|
16 ;; GNU Emacs is distributed in the hope that it will be useful,
|
|
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19 ;; GNU General Public License for more details.
|
|
20
|
|
21 ;; You should have received a copy of the GNU General Public License
|
14169
|
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
|
64091
|
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
24 ;; Boston, MA 02110-1301, USA.
|
36
|
25
|
33708
|
26 ;;; Commentary:
|
|
27
|
|
28 ;; Window tree functions.
|
|
29
|
773
|
30 ;;; Code:
|
36
|
31
|
61764
|
32 (defvar window-size-fixed nil
|
|
33 "*Non-nil in a buffer means windows displaying the buffer are fixed-size.
|
63162
|
34 If the value is `height', then only the window's height is fixed.
|
61764
|
35 If the value is `width', then only the window's width is fixed.
|
|
36 Any other non-nil value fixes both the width and the height.
|
|
37 Emacs won't change the size of any window displaying that buffer,
|
|
38 unless you explicitly change the size, or Emacs has no other choice.")
|
|
39 (make-variable-buffer-local 'window-size-fixed)
|
|
40
|
43093
|
41 (defmacro save-selected-window (&rest body)
|
|
42 "Execute BODY, then select the window that was selected before BODY.
|
63759
|
43 The value returned is the value of the last form in BODY.
|
|
44
|
|
45 This macro saves and restores the current buffer, since otherwise
|
|
46 its normal operation could potentially make a different
|
63760
|
47 buffer current. It does not alter the buffer list ordering.
|
63759
|
48
|
|
49 This macro saves and restores the selected window, as well as
|
|
50 the selected window in each frame. If the previously selected
|
|
51 window of some frame is no longer live at the end of BODY, that
|
|
52 frame's selected window is left alone. If the selected window is
|
|
53 no longer live, then whatever window is selected at the end of
|
|
54 BODY remains selected."
|
48941
7262fd90146a
(save-selected-window): Save and restore selected windows of all frames.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
55 `(let ((save-selected-window-window (selected-window))
|
55825
|
56 ;; It is necessary to save all of these, because calling
|
|
57 ;; select-window changes frame-selected-window for whatever
|
|
58 ;; frame that window is in.
|
48941
7262fd90146a
(save-selected-window): Save and restore selected windows of all frames.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
59 (save-selected-window-alist
|
7262fd90146a
(save-selected-window): Save and restore selected windows of all frames.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
60 (mapcar (lambda (frame) (list frame (frame-selected-window frame)))
|
7262fd90146a
(save-selected-window): Save and restore selected windows of all frames.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
61 (frame-list))))
|
63759
|
62 (save-current-buffer
|
|
63 (unwind-protect
|
|
64 (progn ,@body)
|
|
65 (dolist (elt save-selected-window-alist)
|
|
66 (and (frame-live-p (car elt))
|
|
67 (window-live-p (cadr elt))
|
|
68 (set-frame-selected-window (car elt) (cadr elt))))
|
|
69 (if (window-live-p save-selected-window-window)
|
|
70 (select-window save-selected-window-window))))))
|
43093
|
71
|
42818
|
72 (defun window-body-height (&optional window)
|
|
73 "Return number of lines in window WINDOW for actual buffer text.
|
|
74 This does not include the mode line (if any) or the header line (if any)."
|
|
75 (or window (setq window (selected-window)))
|
42876
|
76 (if (window-minibuffer-p window)
|
|
77 (window-height window)
|
|
78 (with-current-buffer (window-buffer window)
|
|
79 (max 1 (- (window-height window)
|
|
80 (if mode-line-format 1 0)
|
|
81 (if header-line-format 1 0))))))
|
42818
|
82
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
83 (defun one-window-p (&optional nomini all-frames)
|
56391
|
84 "Return non-nil if the selected window is the only window.
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
85 Optional arg NOMINI non-nil means don't count the minibuffer
|
56391
|
86 even if it is active. Otherwise, the minibuffer is counted
|
|
87 when it is active.
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
88
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
89 The optional arg ALL-FRAMES t means count windows on all frames.
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
90 If it is `visible', count windows on all visible frames.
|
33708
|
91 ALL-FRAMES nil or omitted means count only the selected frame,
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
92 plus the minibuffer it uses (which may be on another frame).
|
56391
|
93 ALL-FRAMES 0 means count all windows in all visible or iconified frames.
|
|
94 If ALL-FRAMES is anything else, count only the selected frame."
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
95 (let ((base-window (selected-window)))
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
96 (if (and nomini (eq base-window (minibuffer-window)))
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
97 (setq base-window (next-window base-window)))
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
98 (eq base-window
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
99 (next-window base-window (if nomini 'arg) all-frames))))
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
100
|
52615
|
101 (defun window-current-scroll-bars (&optional window)
|
|
102 "Return the current scroll-bar settings in window WINDOW.
|
63179
|
103 Value is a cons (VERTICAL . HORIZONTAL) where VERTICAL specifies the
|
52615
|
104 current location of the vertical scroll-bars (left, right, or nil),
|
63179
|
105 and HORIZONTAL specifies the current location of the horizontal scroll
|
52615
|
106 bars (top, bottom, or nil)."
|
|
107 (let ((vert (nth 2 (window-scroll-bars window)))
|
|
108 (hor nil))
|
|
109 (when (or (eq vert t) (eq hor t))
|
56391
|
110 (let ((fcsb (frame-current-scroll-bars
|
52615
|
111 (window-frame (or window (selected-window))))))
|
|
112 (if (eq vert t)
|
|
113 (setq vert (car fcsb)))
|
|
114 (if (eq hor t)
|
|
115 (setq hor (cdr fcsb)))))
|
|
116 (cons vert hor)))
|
|
117
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
118 (defun walk-windows (proc &optional minibuf all-frames)
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
119 "Cycle through all visible windows, calling PROC for each one.
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
120 PROC is called with a window as argument.
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
121
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
122 Optional second arg MINIBUF t means count the minibuffer window even
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
123 if not active. MINIBUF nil or omitted means count the minibuffer iff
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
124 it is active. MINIBUF neither t nor nil means not to count the
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
125 minibuffer even if it is active.
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
126
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
127 Several frames may share a single minibuffer; if the minibuffer
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
128 counts, all windows on all frames that share that minibuffer count
|
15057
|
129 too. Therefore, if you are using a separate minibuffer frame
|
|
130 and the minibuffer is active and MINIBUF says it counts,
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
131 `walk-windows' includes the windows in the frame from which you
|
15057
|
132 entered the minibuffer, as well as the minibuffer window.
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
133
|
11302
|
134 ALL-FRAMES is the optional third argument.
|
|
135 ALL-FRAMES nil or omitted means cycle within the frames as specified above.
|
|
136 ALL-FRAMES = `visible' means include windows on all visible frames.
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
137 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
|
11302
|
138 ALL-FRAMES = t means include windows on all frames including invisible frames.
|
26268
|
139 If ALL-FRAMES is a frame, it means include windows on that frame.
|
15076
|
140 Anything else means restrict to the selected frame."
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
141 ;; If we start from the minibuffer window, don't fail to come back to it.
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
142 (if (window-minibuffer-p (selected-window))
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
143 (setq minibuf t))
|
26268
|
144 (save-selected-window
|
|
145 (if (framep all-frames)
|
|
146 (select-window (frame-first-window all-frames)))
|
30005
|
147 (let* (walk-windows-already-seen
|
|
148 (walk-windows-current (selected-window)))
|
26268
|
149 (while (progn
|
|
150 (setq walk-windows-current
|
|
151 (next-window walk-windows-current minibuf all-frames))
|
30005
|
152 (not (memq walk-windows-current walk-windows-already-seen)))
|
|
153 (setq walk-windows-already-seen
|
|
154 (cons walk-windows-current walk-windows-already-seen))
|
|
155 (funcall proc walk-windows-current)))))
|
|
156
|
39172
|
157 (defun get-window-with-predicate (predicate &optional minibuf
|
|
158 all-frames default)
|
30005
|
159 "Return a window satisfying PREDICATE.
|
|
160
|
|
161 This function cycles through all visible windows using `walk-windows',
|
|
162 calling PREDICATE on each one. PREDICATE is called with a window as
|
|
163 argument. The first window for which PREDICATE returns a non-nil
|
|
164 value is returned. If no window satisfies PREDICATE, DEFAULT is
|
|
165 returned.
|
|
166
|
|
167 Optional second arg MINIBUF t means count the minibuffer window even
|
|
168 if not active. MINIBUF nil or omitted means count the minibuffer iff
|
|
169 it is active. MINIBUF neither t nor nil means not to count the
|
|
170 minibuffer even if it is active.
|
|
171
|
|
172 Several frames may share a single minibuffer; if the minibuffer
|
|
173 counts, all windows on all frames that share that minibuffer count
|
|
174 too. Therefore, if you are using a separate minibuffer frame
|
|
175 and the minibuffer is active and MINIBUF says it counts,
|
|
176 `walk-windows' includes the windows in the frame from which you
|
|
177 entered the minibuffer, as well as the minibuffer window.
|
|
178
|
|
179 ALL-FRAMES is the optional third argument.
|
|
180 ALL-FRAMES nil or omitted means cycle within the frames as specified above.
|
|
181 ALL-FRAMES = `visible' means include windows on all visible frames.
|
|
182 ALL-FRAMES = 0 means include windows on all visible and iconified frames.
|
|
183 ALL-FRAMES = t means include windows on all frames including invisible frames.
|
|
184 If ALL-FRAMES is a frame, it means include windows on that frame.
|
|
185 Anything else means restrict to the selected frame."
|
|
186 (catch 'found
|
33708
|
187 (walk-windows #'(lambda (window)
|
30005
|
188 (when (funcall predicate window)
|
|
189 (throw 'found window)))
|
|
190 minibuf all-frames)
|
|
191 default))
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
192
|
39172
|
193 (defalias 'some-window 'get-window-with-predicate)
|
|
194
|
66310
|
195 ;; This should probably be written in C (i.e., without using `walk-windows').
|
|
196 (defun get-buffer-window-list (buffer &optional minibuf frame)
|
|
197 "Return list of all windows displaying BUFFER, or nil if none.
|
|
198 BUFFER can be a buffer or a buffer name.
|
|
199 See `walk-windows' for the meaning of MINIBUF and FRAME."
|
|
200 (let ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) windows)
|
|
201 (walk-windows (function (lambda (window)
|
|
202 (if (eq (window-buffer window) buffer)
|
|
203 (setq windows (cons window windows)))))
|
|
204 minibuf frame)
|
|
205 windows))
|
|
206
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
207 (defun minibuffer-window-active-p (window)
|
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
208 "Return t if WINDOW (a minibuffer window) is now active."
|
11149
|
209 (eq window (active-minibuffer-window)))
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
210
|
36
|
211 (defun count-windows (&optional minibuf)
|
33708
|
212 "Return the number of visible windows.
|
22328
|
213 This counts the windows in the selected frame and (if the minibuffer is
|
|
214 to be counted) its minibuffer frame (if that's not the same frame).
|
|
215 The optional arg MINIBUF non-nil means count the minibuffer
|
14836
|
216 even if it is inactive."
|
36
|
217 (let ((count 0))
|
3375
13ddc81f0b43
(count-windows): PROC argument of walk-windows takes an argument.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
218 (walk-windows (function (lambda (w)
|
36
|
219 (setq count (+ count 1))))
|
|
220 minibuf)
|
|
221 count))
|
|
222
|
33708
|
223 (defun window-safely-shrinkable-p (&optional window)
|
36366
|
224 "Non-nil if the WINDOW can be shrunk without shrinking other windows.
|
|
225 If WINDOW is nil or omitted, it defaults to the currently selected window."
|
53894
0a356c1b7057
(window-safely-shrinkable-p): Don't change the buffer-list.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
226 (with-selected-window (or window (selected-window))
|
0a356c1b7057
(window-safely-shrinkable-p): Don't change the buffer-list.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
227 (let ((edges (window-edges)))
|
0a356c1b7057
(window-safely-shrinkable-p): Don't change the buffer-list.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
228 (or (= (nth 2 edges) (nth 2 (window-edges (previous-window))))
|
0a356c1b7057
(window-safely-shrinkable-p): Don't change the buffer-list.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
229 (= (nth 0 edges) (nth 0 (window-edges (next-window))))))))
|
0a356c1b7057
(window-safely-shrinkable-p): Don't change the buffer-list.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
230
|
67478
|
231
|
|
232 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
233 ;;; `balance-windows' subroutines using `window-tree'
|
33708
|
234
|
67478
|
235 ;;; Translate from internal window tree format
|
|
236
|
|
237 (defun bw-get-tree (&optional window-or-frame)
|
|
238 "Get a window split tree in our format.
|
|
239
|
|
240 WINDOW-OR-FRAME must be nil, a frame, or a window. If it is nil,
|
|
241 then the whole window split tree for `selected-frame' is returned.
|
|
242 If it is a frame, then this is used instead. If it is a window,
|
|
243 then the smallest tree containing that window is returned."
|
|
244 (when window-or-frame
|
|
245 (unless (or (framep window-or-frame)
|
|
246 (windowp window-or-frame))
|
|
247 (error "Not a frame or window: %s" window-or-frame)))
|
|
248 (let ((subtree (bw-find-tree-sub window-or-frame)))
|
|
249 (if (integerp subtree)
|
|
250 nil
|
|
251 (bw-get-tree-1 subtree))))
|
|
252
|
|
253 (defun bw-get-tree-1 (split)
|
|
254 (if (windowp split)
|
|
255 split
|
|
256 (let ((dir (car split))
|
|
257 (edges (car (cdr split)))
|
|
258 (childs (cdr (cdr split))))
|
|
259 (list
|
|
260 (cons 'dir (if dir 'ver 'hor))
|
|
261 (cons 'b (nth 3 edges))
|
|
262 (cons 'r (nth 2 edges))
|
|
263 (cons 't (nth 1 edges))
|
|
264 (cons 'l (nth 0 edges))
|
|
265 (cons 'childs (mapcar #'bw-get-tree-1 childs))))))
|
|
266
|
|
267 (defun bw-find-tree-sub (window-or-frame &optional get-parent)
|
|
268 (let* ((window (when (windowp window-or-frame) window-or-frame))
|
|
269 (frame (when (windowp window) (window-frame window)))
|
|
270 (wt (car (window-tree frame))))
|
|
271 (when (< 1 (length (window-list frame 0)))
|
|
272 (if window
|
|
273 (bw-find-tree-sub-1 wt window get-parent)
|
|
274 wt))))
|
|
275
|
|
276 (defun bw-find-tree-sub-1 (tree win &optional get-parent)
|
|
277 (unless (windowp win) (error "Not a window: %s" win))
|
|
278 (if (memq win tree)
|
|
279 (if get-parent
|
|
280 get-parent
|
|
281 tree)
|
|
282 (let ((childs (cdr (cdr tree)))
|
|
283 child
|
|
284 subtree)
|
|
285 (while (and childs (not subtree))
|
|
286 (setq child (car childs))
|
|
287 (setq childs (cdr childs))
|
|
288 (when (and child (listp child))
|
|
289 (setq subtree (bw-find-tree-sub-1 child win get-parent))))
|
|
290 (if (integerp subtree)
|
|
291 (progn
|
|
292 (if (= 1 subtree)
|
|
293 tree
|
|
294 (1- subtree)))
|
|
295 subtree
|
|
296 ))))
|
|
297
|
|
298 ;;; Window or object edges
|
|
299
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
300 (defun bw-l (obj)
|
67478
|
301 "Left edge of OBJ."
|
|
302 (if (windowp obj) (nth 0 (window-edges obj)) (cdr (assq 'l obj))))
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
303 (defun bw-t (obj)
|
67478
|
304 "Top edge of OBJ."
|
|
305 (if (windowp obj) (nth 1 (window-edges obj)) (cdr (assq 't obj))))
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
306 (defun bw-r (obj)
|
67478
|
307 "Right edge of OBJ."
|
|
308 (if (windowp obj) (nth 2 (window-edges obj)) (cdr (assq 'r obj))))
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
309 (defun bw-b (obj)
|
67478
|
310 "Bottom edge of OBJ."
|
|
311 (if (windowp obj) (nth 3 (window-edges obj)) (cdr (assq 'b obj))))
|
|
312
|
|
313 ;;; Split directions
|
|
314
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
315 (defun bw-dir (obj)
|
67478
|
316 "Return window split tree direction if OBJ.
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
317 If OBJ is a window return 'both. If it is a window split tree
|
67478
|
318 then return its direction."
|
|
319 (if (symbolp obj)
|
|
320 obj
|
|
321 (if (windowp obj)
|
|
322 'both
|
|
323 (let ((dir (cdr (assq 'dir obj))))
|
|
324 (unless (memq dir '(hor ver both))
|
|
325 (error "Can't find dir in %s" obj))
|
|
326 dir))))
|
42307
|
327
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
328 (defun bw-eqdir (obj1 obj2)
|
67478
|
329 "Return t if window split tree directions are equal.
|
|
330 OBJ1 and OBJ2 should be either windows or window split trees in
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
331 our format. The directions returned by `bw-dir' are compared and
|
67478
|
332 t is returned if they are `eq' or one of them is 'both."
|
|
333 (let ((dir1 (bw-dir obj1))
|
|
334 (dir2 (bw-dir obj2)))
|
|
335 (or (eq dir1 dir2)
|
|
336 (eq dir1 'both)
|
|
337 (eq dir2 'both))))
|
|
338
|
|
339 ;;; Building split tree
|
|
340
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
341 (defun bw-refresh-edges (obj)
|
67478
|
342 "Refresh the edge information of OBJ and return OBJ."
|
|
343 (unless (windowp obj)
|
|
344 (let ((childs (cdr (assq 'childs obj)))
|
|
345 (ol 1000)
|
|
346 (ot 1000)
|
|
347 (or -1)
|
|
348 (ob -1))
|
|
349 (dolist (o childs)
|
|
350 (when (> ol (bw-l o)) (setq ol (bw-l o)))
|
|
351 (when (> ot (bw-t o)) (setq ot (bw-t o)))
|
|
352 (when (< or (bw-r o)) (setq or (bw-r o)))
|
|
353 (when (< ob (bw-b o)) (setq ob (bw-b o))))
|
|
354 (setq obj (delq 'l obj))
|
|
355 (setq obj (delq 't obj))
|
|
356 (setq obj (delq 'r obj))
|
|
357 (setq obj (delq 'b obj))
|
|
358 (add-to-list 'obj (cons 'l ol))
|
|
359 (add-to-list 'obj (cons 't ot))
|
|
360 (add-to-list 'obj (cons 'r or))
|
|
361 (add-to-list 'obj (cons 'b ob))
|
|
362 ))
|
|
363 obj)
|
|
364
|
|
365 ;;; Balance windows
|
|
366
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
367 (defun balance-windows (&optional window-or-frame)
|
67478
|
368 "Make windows the same heights or widths in window split subtrees.
|
|
369
|
|
370 When called non-interactively WINDOW-OR-FRAME may be either a
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
371 window or a frame. It then balances the windows on the implied
|
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
372 frame. If the parameter is a window only the corresponding window
|
67478
|
373 subtree is balanced."
|
|
374 (interactive)
|
|
375 (let (
|
|
376 (wt (bw-get-tree window-or-frame))
|
|
377 (w)
|
|
378 (h)
|
|
379 (tried-sizes)
|
|
380 (last-sizes)
|
|
381 (windows (window-list nil 0))
|
|
382 (counter 0))
|
|
383 (when wt
|
|
384 (while (not (member last-sizes tried-sizes))
|
|
385 (when last-sizes (setq tried-sizes (cons last-sizes tried-sizes)))
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
386 (setq last-sizes (mapcar (lambda (w)
|
67478
|
387 (window-edges w))
|
|
388 windows))
|
|
389 (when (eq 'hor (bw-dir wt))
|
|
390 (setq w (- (bw-r wt) (bw-l wt))))
|
|
391 (when (eq 'ver (bw-dir wt))
|
|
392 (setq h (- (bw-b wt) (bw-t wt))))
|
|
393 (bw-balance-sub wt w h)))))
|
|
394
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
395 (defun bw-adjust-window (window delta horizontal)
|
67478
|
396 "Wrapper around `adjust-window-trailing-edge' with error checking.
|
|
397 Arguments WINDOW, DELTA and HORIZONTAL are passed on to that function."
|
|
398 (condition-case err
|
|
399 (adjust-window-trailing-edge window delta horizontal)
|
|
400 (error
|
|
401 ;;(message "adjust: %s" (error-message-string err))
|
|
402 )))
|
|
403
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
404 (defun bw-balance-sub (wt w h)
|
67478
|
405 (setq wt (bw-refresh-edges wt))
|
|
406 (unless w (setq w (- (bw-r wt) (bw-l wt))))
|
|
407 (unless h (setq h (- (bw-b wt) (bw-t wt))))
|
|
408 (if (windowp wt)
|
|
409 (progn
|
|
410 (when w
|
|
411 (let ((dw (- w (- (bw-r wt) (bw-l wt)))))
|
|
412 (when (/= 0 dw)
|
|
413 (bw-adjust-window wt dw t))))
|
|
414 (when h
|
|
415 (let ((dh (- h (- (bw-b wt) (bw-t wt)))))
|
|
416 (when (/= 0 dh)
|
|
417 (bw-adjust-window wt dh nil)))))
|
|
418 (let* ((childs (cdr (assq 'childs wt)))
|
|
419 (lastchild (car (last childs)))
|
|
420 (cw (when w (/ w (if (bw-eqdir 'hor wt) (length childs) 1))))
|
|
421 (ch (when h (/ h (if (bw-eqdir 'ver wt) (length childs) 1)))))
|
|
422 (dolist (c childs)
|
|
423 (bw-balance-sub c cw ch)))))
|
|
424
|
|
425 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
11086
22693a280a42
(one-window-p, walk-windows, minibuffer-window-active-p): Functions moved here.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
426
|
46896
549bdeb52a93
(split-window-save-restore-data): Use push and with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
427 ;; I think this should be the default; I think people will prefer it--rms.
|
17665
|
428 (defcustom split-window-keep-point t
|
56391
|
429 "*If non-nil, \\[split-window-vertically] keeps the original point \
|
|
430 in both children.
|
3724
|
431 This is often more convenient for editing.
|
|
432 If nil, adjust point in each of the two windows to minimize redisplay.
|
56391
|
433 This is convenient on slow terminals, but point can move strangely.
|
|
434
|
|
435 This option applies only to `split-window-vertically' and
|
|
436 functions that call it. `split-window' always keeps the original
|
68487
bde0adf72ba8
(bw-dir, bw-eqdir, balance-windows, split-window-keep-point):
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
437 point in both children."
|
17665
|
438 :type 'boolean
|
|
439 :group 'windows)
|
382
|
440
|
36
|
441 (defun split-window-vertically (&optional arg)
|
|
442 "Split current window into two windows, one above the other.
|
108
|
443 The uppermost window gets ARG lines and the other gets the rest.
|
56391
|
444 Negative ARG means select the size of the lowermost window instead.
|
108
|
445 With no argument, split equally or close to it.
|
|
446 Both windows display the same buffer now current.
|
382
|
447
|
22216
|
448 If the variable `split-window-keep-point' is non-nil, both new windows
|
382
|
449 will get the same value of point as the current window. This is often
|
56391
|
450 more convenient for editing. The upper window is the selected window.
|
108
|
451
|
56391
|
452 Otherwise, we choose window starts so as to minimize the amount of
|
382
|
453 redisplay; this is convenient on slow terminals. The new selected
|
|
454 window is the one that the current value of point appears in. The
|
|
455 value of point can change if the text around point is hidden by the
|
56391
|
456 new mode line.
|
|
457
|
|
458 Regardless of the value of `split-window-keep-point', the upper
|
|
459 window is the original one and the return value is the new, lower
|
|
460 window."
|
36
|
461 (interactive "P")
|
|
462 (let ((old-w (selected-window))
|
108
|
463 (old-point (point))
|
6670
|
464 (size (and arg (prefix-numeric-value arg)))
|
13854
|
465 (window-full-p nil)
|
|
466 new-w bottom switch moved)
|
6670
|
467 (and size (< size 0) (setq size (+ (window-height) size)))
|
|
468 (setq new-w (split-window nil size))
|
419
|
469 (or split-window-keep-point
|
108
|
470 (progn
|
382
|
471 (save-excursion
|
|
472 (set-buffer (window-buffer))
|
|
473 (goto-char (window-start))
|
13854
|
474 (setq moved (vertical-motion (window-height)))
|
382
|
475 (set-window-start new-w (point))
|
|
476 (if (> (point) (window-point new-w))
|
|
477 (set-window-point new-w (point)))
|
13854
|
478 (and (= moved (window-height))
|
|
479 (progn
|
|
480 (setq window-full-p t)
|
|
481 (vertical-motion -1)))
|
|
482 (setq bottom (point)))
|
|
483 (and window-full-p
|
|
484 (<= bottom (point))
|
|
485 (set-window-point old-w (1- bottom)))
|
|
486 (and window-full-p
|
|
487 (<= (window-start new-w) old-point)
|
|
488 (progn
|
|
489 (set-window-point new-w old-point)
|
|
490 (select-window new-w)))))
|
18279
|
491 (split-window-save-restore-data new-w old-w)))
|
|
492
|
21118
|
493 ;; This is to avoid compiler warnings.
|
|
494 (defvar view-return-to-alist)
|
|
495
|
18279
|
496 (defun split-window-save-restore-data (new-w old-w)
|
46896
549bdeb52a93
(split-window-save-restore-data): Use push and with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
497 (with-current-buffer (window-buffer)
|
18279
|
498 (if view-mode
|
|
499 (let ((old-info (assq old-w view-return-to-alist)))
|
55015
|
500 (if old-info
|
|
501 (push (cons new-w (cons (car (cdr old-info)) t))
|
|
502 view-return-to-alist))))
|
3253
|
503 new-w))
|
36
|
504
|
|
505 (defun split-window-horizontally (&optional arg)
|
|
506 "Split current window into two windows side by side.
|
8565
2a2208286955
(split-window-horizontally): If size is negative, measure from the right.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
507 This window becomes the leftmost of the two, and gets ARG columns.
|
56391
|
508 Negative ARG means select the size of the rightmost window instead.
|
22924
|
509 The argument includes the width of the window's scroll bar; if there
|
|
510 are no scroll bars, it includes the width of the divider column
|
56391
|
511 to the window's right, if any. No ARG means split equally.
|
|
512
|
|
513 The original, leftmost window remains selected.
|
|
514 The return value is the new, rightmost window."
|
36
|
515 (interactive "P")
|
18279
|
516 (let ((old-w (selected-window))
|
|
517 (size (and arg (prefix-numeric-value arg))))
|
8565
2a2208286955
(split-window-horizontally): If size is negative, measure from the right.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
518 (and size (< size 0)
|
2a2208286955
(split-window-horizontally): If size is negative, measure from the right.
Karl Heuer <kwzh@gnu.org>
diff
changeset
|
519 (setq size (+ (window-width) size)))
|
18279
|
520 (split-window-save-restore-data (split-window nil size t) old-w)))
|
32689
|
521
|
|
522
|
|
523 (defun set-window-text-height (window height)
|
|
524 "Sets the height in lines of the text display area of WINDOW to HEIGHT.
|
|
525 This doesn't include the mode-line (or header-line if any) or any
|
|
526 partial-height lines in the text display area.
|
|
527
|
|
528 If WINDOW is nil, the selected window is used.
|
|
529
|
|
530 Note that the current implementation of this function cannot always set
|
|
531 the height exactly, but attempts to be conservative, by allocating more
|
|
532 lines than are actually needed in the case where some error may be present."
|
|
533 (let ((delta (- height (window-text-height window))))
|
|
534 (unless (zerop delta)
|
32695
|
535 (let ((window-min-height 1))
|
|
536 (if (and window (not (eq window (selected-window))))
|
|
537 (save-selected-window
|
|
538 (select-window window)
|
|
539 (enlarge-window delta))
|
|
540 (enlarge-window delta))))))
|
32689
|
541
|
32681
|
542
|
36
|
543 (defun enlarge-window-horizontally (arg)
|
|
544 "Make current window ARG columns wider."
|
|
545 (interactive "p")
|
|
546 (enlarge-window arg t))
|
|
547
|
|
548 (defun shrink-window-horizontally (arg)
|
|
549 "Make current window ARG columns narrower."
|
|
550 (interactive "p")
|
|
551 (shrink-window arg t))
|
|
552
|
23748
|
553 (defun window-buffer-height (window)
|
|
554 "Return the height (in screen lines) of the buffer that WINDOW is displaying."
|
61038
|
555 (with-current-buffer (window-buffer window)
|
|
556 (max 1
|
|
557 (count-screen-lines (point-min) (point-max)
|
|
558 ;; If buffer ends with a newline, ignore it when
|
|
559 ;; counting height unless point is after it.
|
|
560 (eobp)
|
|
561 window))))
|
23748
|
562
|
28655
|
563 (defun count-screen-lines (&optional beg end count-final-newline window)
|
|
564 "Return the number of screen lines in the region.
|
|
565 The number of screen lines may be different from the number of actual lines,
|
|
566 due to line breaking, display table, etc.
|
|
567
|
|
568 Optional arguments BEG and END default to `point-min' and `point-max'
|
|
569 respectively.
|
|
570
|
33708
|
571 If region ends with a newline, ignore it unless optional third argument
|
28655
|
572 COUNT-FINAL-NEWLINE is non-nil.
|
|
573
|
|
574 The optional fourth argument WINDOW specifies the window used for obtaining
|
33708
|
575 parameters such as width, horizontal scrolling, and so on. The default is
|
28655
|
576 to use the selected window's parameters.
|
|
577
|
|
578 Like `vertical-motion', `count-screen-lines' always uses the current buffer,
|
33708
|
579 regardless of which buffer is displayed in WINDOW. This makes possible to use
|
28655
|
580 `count-screen-lines' in any buffer, whether or not it is currently displayed
|
|
581 in some window."
|
|
582 (unless beg
|
|
583 (setq beg (point-min)))
|
|
584 (unless end
|
|
585 (setq end (point-max)))
|
|
586 (if (= beg end)
|
|
587 0
|
|
588 (save-excursion
|
|
589 (save-restriction
|
|
590 (widen)
|
|
591 (narrow-to-region (min beg end)
|
|
592 (if (and (not count-final-newline)
|
|
593 (= ?\n (char-before (max beg end))))
|
|
594 (1- (max beg end))
|
|
595 (max beg end)))
|
|
596 (goto-char (point-min))
|
|
597 (1+ (vertical-motion (buffer-size) window))))))
|
|
598
|
32705
|
599 (defun fit-window-to-buffer (&optional window max-height min-height)
|
|
600 "Make WINDOW the right size to display its contents exactly.
|
36366
|
601 If WINDOW is omitted or nil, it defaults to the selected window.
|
32705
|
602 If the optional argument MAX-HEIGHT is supplied, it is the maximum height
|
|
603 the window is allowed to be, defaulting to the frame height.
|
|
604 If the optional argument MIN-HEIGHT is supplied, it is the minimum
|
|
605 height the window is allowed to be, defaulting to `window-min-height'.
|
|
606
|
|
607 The heights in MAX-HEIGHT and MIN-HEIGHT include the mode-line and/or
|
|
608 header-line."
|
|
609 (interactive)
|
|
610
|
|
611 (when (null window)
|
|
612 (setq window (selected-window)))
|
32737
|
613 (when (null max-height)
|
|
614 (setq max-height (frame-height (window-frame window))))
|
32705
|
615
|
33478
|
616 (let* ((buf
|
|
617 ;; Buffer that is displayed in WINDOW
|
|
618 (window-buffer window))
|
|
619 (window-height
|
32705
|
620 ;; The current height of WINDOW
|
|
621 (window-height window))
|
33478
|
622 (desired-height
|
32705
|
623 ;; The height necessary to show the buffer displayed by WINDOW
|
|
624 ;; (`count-screen-lines' always works on the current buffer).
|
33478
|
625 (with-current-buffer buf
|
|
626 (+ (count-screen-lines)
|
33536
|
627 ;; If the buffer is empty, (count-screen-lines) is
|
|
628 ;; zero. But, even in that case, we need one text line
|
|
629 ;; for cursor.
|
|
630 (if (= (point-min) (point-max))
|
|
631 1 0)
|
33478
|
632 ;; For non-minibuffers, count the mode-line, if any
|
|
633 (if (and (not (window-minibuffer-p window))
|
|
634 mode-line-format)
|
|
635 1 0)
|
|
636 ;; Count the header-line, if any
|
|
637 (if header-line-format 1 0))))
|
32705
|
638 (delta
|
|
639 ;; Calculate how much the window height has to change to show
|
33478
|
640 ;; desired-height lines, constrained by MIN-HEIGHT and MAX-HEIGHT.
|
|
641 (- (max (min desired-height max-height)
|
32705
|
642 (or min-height window-min-height))
|
|
643 window-height))
|
|
644 ;; We do our own height checking, so avoid any restrictions due to
|
|
645 ;; window-min-height.
|
|
646 (window-min-height 1))
|
|
647
|
|
648 ;; Don't try to redisplay with the cursor at the end
|
|
649 ;; on its own line--that would force a scroll and spoil things.
|
33478
|
650 (when (with-current-buffer buf
|
|
651 (and (eobp) (bolp) (not (bobp))))
|
|
652 (set-window-point window (1- (window-point window))))
|
32705
|
653
|
33478
|
654 (save-selected-window
|
|
655 (select-window window)
|
|
656
|
|
657 ;; Adjust WINDOW to the nominally correct size (which may actually
|
|
658 ;; be slightly off because of variable height text, etc).
|
|
659 (unless (zerop delta)
|
|
660 (enlarge-window delta))
|
33475
|
661
|
33478
|
662 ;; Check if the last line is surely fully visible. If not,
|
|
663 ;; enlarge the window.
|
|
664 (let ((end (with-current-buffer buf
|
|
665 (save-excursion
|
|
666 (goto-char (point-max))
|
34079
|
667 (when (and (bolp) (not (bobp)))
|
|
668 ;; Don't include final newline
|
|
669 (backward-char 1))
|
|
670 (when truncate-lines
|
|
671 ;; If line-wrapping is turned off, test the
|
|
672 ;; beginning of the last line for visibility
|
|
673 ;; instead of the end, as the end of the line
|
|
674 ;; could be invisible by virtue of extending past
|
|
675 ;; the edge of the window.
|
|
676 (forward-line 0))
|
|
677 (point)))))
|
33478
|
678 (set-window-vscroll window 0)
|
|
679 (while (and (< desired-height max-height)
|
|
680 (= desired-height (window-height window))
|
34383
|
681 (not (pos-visible-in-window-p end window)))
|
33478
|
682 (enlarge-window 1)
|
33537
|
683 (setq desired-height (1+ desired-height)))))))
|
32705
|
684
|
2529
bb127c1081af
(shrink-window-if-larger-than-buffer): Moved from electric.el to windows.el,
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
685 (defun shrink-window-if-larger-than-buffer (&optional window)
|
3342
|
686 "Shrink the WINDOW to be as small as possible to display its contents.
|
36366
|
687 If WINDOW is omitted or nil, it defaults to the selected window.
|
8721
|
688 Do not shrink to less than `window-min-height' lines.
|
3342
|
689 Do nothing if the buffer contains more lines than the present window height,
|
4364
|
690 or if some of the window's contents are scrolled out of view,
|
63168
54196b74d427
(shrink-window-if-larger-than-buffer): Fix typo in docstring.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
691 or if shrinking this window would also shrink another window,
|
62671
bf8ebb1d0b0b
(quit-window, shrink-window-if-larger-than-buffer): Doc fixes.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
692 or if the window is the only window of its frame."
|
3342
|
693 (interactive)
|
32705
|
694 (when (null window)
|
|
695 (setq window (selected-window)))
|
|
696 (let* ((frame (window-frame window))
|
|
697 (mini (frame-parameter frame 'minibuffer))
|
|
698 (edges (window-edges window)))
|
|
699 (if (and (not (eq window (frame-root-window frame)))
|
33708
|
700 (window-safely-shrinkable-p)
|
32705
|
701 (pos-visible-in-window-p (point-min) window)
|
|
702 (not (eq mini 'only))
|
|
703 (or (not mini)
|
36666
|
704 (let ((mini-window (minibuffer-window frame)))
|
|
705 (or (null mini-window)
|
|
706 (not (eq frame (window-frame mini-window)))
|
|
707 (< (nth 3 edges)
|
|
708 (nth 1 (window-edges mini-window)))
|
49597
|
709 (> (nth 1 edges)
|
36666
|
710 (frame-parameter frame 'menu-bar-lines))))))
|
32705
|
711 (fit-window-to-buffer window (window-height window)))))
|
16469
|
712
|
|
713 (defun kill-buffer-and-window ()
|
|
714 "Kill the current buffer and delete the selected window."
|
|
715 (interactive)
|
52481
|
716 (let ((window-to-delete (selected-window))
|
|
717 (delete-window-hook (lambda ()
|
|
718 (condition-case nil
|
|
719 (delete-window)
|
|
720 (error nil)))))
|
|
721 (add-hook 'kill-buffer-hook delete-window-hook t t)
|
|
722 (if (kill-buffer (current-buffer))
|
|
723 ;; If `delete-window' failed before, we rerun it to regenerate
|
|
724 ;; the error so it can be seen in the minibuffer.
|
|
725 (when (eq (selected-window) window-to-delete)
|
|
726 (delete-window))
|
|
727 (remove-hook 'kill-buffer-hook delete-window-hook t))))
|
16469
|
728
|
21118
|
729 (defun quit-window (&optional kill window)
|
|
730 "Quit the current buffer. Bury it, and maybe delete the selected frame.
|
62671
bf8ebb1d0b0b
(quit-window, shrink-window-if-larger-than-buffer): Doc fixes.
Juanma Barranquero <lekktu@gmail.com>
diff
changeset
|
731 \(The frame is deleted if it contains a dedicated window for the buffer.)
|
21118
|
732 With a prefix argument, kill the buffer instead.
|
|
733
|
|
734 Noninteractively, if KILL is non-nil, then kill the current buffer,
|
|
735 otherwise bury it.
|
|
736
|
|
737 If WINDOW is non-nil, it specifies a window; we delete that window,
|
|
738 and the buffer that is killed or buried is the one in that window."
|
|
739 (interactive "P")
|
|
740 (let ((buffer (window-buffer window))
|
21970
|
741 (frame (window-frame (or window (selected-window))))
|
21118
|
742 (window-solitary
|
|
743 (save-selected-window
|
|
744 (if window
|
|
745 (select-window window))
|
|
746 (one-window-p t)))
|
|
747 window-handled)
|
|
748
|
|
749 (save-selected-window
|
|
750 (if window
|
|
751 (select-window window))
|
21860
|
752 (or (window-minibuffer-p)
|
|
753 (window-dedicated-p (selected-window))
|
|
754 (switch-to-buffer (other-buffer))))
|
21118
|
755
|
|
756 ;; Get rid of the frame, if it has just one dedicated window
|
|
757 ;; and other visible frames exist.
|
21860
|
758 (and (or (window-minibuffer-p) (window-dedicated-p window))
|
21118
|
759 (delq frame (visible-frame-list))
|
|
760 window-solitary
|
|
761 (if (and (eq default-minibuffer-frame frame)
|
|
762 (= 1 (length (minibuffer-frame-list))))
|
|
763 (setq window nil)
|
|
764 (delete-frame frame)
|
|
765 (setq window-handled t)))
|
|
766
|
|
767 ;; Deal with the buffer.
|
|
768 (if kill
|
|
769 (kill-buffer buffer)
|
|
770 (bury-buffer buffer))
|
|
771
|
|
772 ;; Maybe get rid of the window.
|
|
773 (and window (not window-handled) (not window-solitary)
|
|
774 (delete-window window))))
|
|
775
|
44296
|
776 (defun handle-select-window (event)
|
|
777 "Handle select-window events."
|
|
778 (interactive "e")
|
|
779 (let ((window (posn-window (event-start event))))
|
46896
549bdeb52a93
(split-window-save-restore-data): Use push and with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
780 (if (and (window-live-p window)
|
59652
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
781 ;; Don't switch if we're currently in the minibuffer.
|
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
782 ;; This tries to work around problems where the minibuffer gets
|
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
783 ;; unselected unexpectedly, and where you then have to move
|
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
784 ;; your mouse all the way down to the minibuffer to select it.
|
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
785 (not (window-minibuffer-p (selected-window)))
|
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
786 ;; Don't switch to a minibuffer window unless it's active.
|
46896
549bdeb52a93
(split-window-save-restore-data): Use push and with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
787 (or (not (window-minibuffer-p window))
|
549bdeb52a93
(split-window-save-restore-data): Use push and with-current-buffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
788 (minibuffer-window-active-p window)))
|
44296
|
789 (select-window window))))
|
|
790
|
36
|
791 (define-key ctl-x-map "2" 'split-window-vertically)
|
707
|
792 (define-key ctl-x-map "3" 'split-window-horizontally)
|
36
|
793 (define-key ctl-x-map "}" 'enlarge-window-horizontally)
|
|
794 (define-key ctl-x-map "{" 'shrink-window-horizontally)
|
2529
bb127c1081af
(shrink-window-if-larger-than-buffer): Moved from electric.el to windows.el,
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
795 (define-key ctl-x-map "-" 'shrink-window-if-larger-than-buffer)
|
bb127c1081af
(shrink-window-if-larger-than-buffer): Moved from electric.el to windows.el,
Eric S. Raymond <esr@snark.thyrsus.com>
diff
changeset
|
796 (define-key ctl-x-map "+" 'balance-windows)
|
16469
|
797 (define-key ctl-x-4-map "0" 'kill-buffer-and-window)
|
656
|
798
|
59652
9672303dbf4f
(handle-select-window): Don't switch window when we're in the minibuffer.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
799 ;; arch-tag: b508dfcc-c353-4c37-89fa-e773fe10cea9
|
33708
|
800 ;;; window.el ends here
|