aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Rudalics2011-06-08 11:13:43 +0200
committerMartin Rudalics2011-06-08 11:13:43 +0200
commit387522b285a49a3c598694ce4cd1cdb90071bf5f (patch)
tree932fe1f64dcfb853405728ab500758c01de4e00b
parent496e208ef95f8c691f4fe36d6ad6adbe3dedcd15 (diff)
downloademacs-387522b285a49a3c598694ce4cd1cdb90071bf5f.tar.gz
emacs-387522b285a49a3c598694ce4cd1cdb90071bf5f.zip
A few new functions and rewrites in window.el.
* window.el (one-window-p): Move down in code. Rewrite doc-string. (window-current-scroll-bars): Rewrite doc-string. Normalize live window argument. (walk-windows, get-window-with-predicate, count-windows): Rewrite doc-string. Use window-list-1. (window-in-direction-2, window-in-direction, get-mru-window): New functions.
-rw-r--r--lisp/ChangeLog11
-rw-r--r--lisp/window.el297
2 files changed, 233 insertions, 75 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 00dd3ea11e5..2341c0c973a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,14 @@
12011-06-08 Martin Rudalics <rudalics@gmx.at>
2
3 * window.el (one-window-p): Move down in code. Rewrite
4 doc-string.
5 (window-current-scroll-bars): Rewrite doc-string. Normalize
6 live window argument.
7 (walk-windows, get-window-with-predicate, count-windows):
8 Rewrite doc-string. Use window-list-1.
9 (window-in-direction-2, window-in-direction, get-mru-window):
10 New functions.
11
12011-06-08 Reuben Thomas <rrt@sc3d.org> 122011-06-08 Reuben Thomas <rrt@sc3d.org>
2 13
3 * progmodes/flymake.el (flymake-compilation-prevents-syntax-check): 14 * progmodes/flymake.el (flymake-compilation-prevents-syntax-check):
diff --git a/lisp/window.el b/lisp/window.el
index 98c49faaf28..eafa8a4764a 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -957,28 +957,9 @@ display margins either."
957;; Eventually we should make `window-height' obsolete. 957;; Eventually we should make `window-height' obsolete.
958(defalias 'window-width 'window-body-width) 958(defalias 'window-width 'window-body-width)
959 959
960(defun one-window-p (&optional nomini all-frames)
961 "Return non-nil if the selected window is the only window.
962Optional arg NOMINI non-nil means don't count the minibuffer
963even if it is active. Otherwise, the minibuffer is counted
964when it is active.
965
966The optional arg ALL-FRAMES t means count windows on all frames.
967If it is `visible', count windows on all visible frames on the
968current terminal. ALL-FRAMES nil or omitted means count only the
969selected frame, plus the minibuffer it uses (which may be on
970another frame). ALL-FRAMES 0 means count all windows in all
971visible or iconified frames on the current terminal. If
972ALL-FRAMES is anything else, count only the selected frame."
973 (let ((base-window (selected-window)))
974 (if (and nomini (eq base-window (minibuffer-window)))
975 (setq base-window (next-window base-window)))
976 (eq base-window
977 (next-window base-window (if nomini 'arg) all-frames))))
978
979(defun window-current-scroll-bars (&optional window) 960(defun window-current-scroll-bars (&optional window)
980 "Return the current scroll bar settings for WINDOW. 961 "Return the current scroll bar settings for WINDOW.
981WINDOW defaults to the selected window. 962WINDOW must be a live window and defaults to the selected one.
982 963
983The return value is a cons cell (VERTICAL . HORIZONTAL) where 964The return value is a cons cell (VERTICAL . HORIZONTAL) where
984VERTICAL specifies the current location of the vertical scroll 965VERTICAL specifies the current location of the vertical scroll
@@ -989,11 +970,11 @@ or nil).
989Unlike `window-scroll-bars', this function reports the scroll bar 970Unlike `window-scroll-bars', this function reports the scroll bar
990type actually used, once frame defaults and `scroll-bar-mode' are 971type actually used, once frame defaults and `scroll-bar-mode' are
991taken into account." 972taken into account."
973 (setq window (normalize-live-window window))
992 (let ((vert (nth 2 (window-scroll-bars window))) 974 (let ((vert (nth 2 (window-scroll-bars window)))
993 (hor nil)) 975 (hor nil))
994 (when (or (eq vert t) (eq hor t)) 976 (when (or (eq vert t) (eq hor t))
995 (let ((fcsb (frame-current-scroll-bars 977 (let ((fcsb (frame-current-scroll-bars (window-frame window))))
996 (window-frame (or window (selected-window))))))
997 (if (eq vert t) 978 (if (eq vert t)
998 (setq vert (car fcsb))) 979 (setq vert (car fcsb)))
999 (if (eq hor t) 980 (if (eq hor t)
@@ -1001,10 +982,10 @@ taken into account."
1001 (cons vert hor))) 982 (cons vert hor)))
1002 983
1003(defun walk-windows (proc &optional minibuf all-frames) 984(defun walk-windows (proc &optional minibuf all-frames)
1004 "Cycle through all windows, calling PROC for each one. 985 "Cycle through all live windows, calling PROC for each one.
1005PROC must specify a function with a window as its sole argument. 986PROC must specify a function with a window as its sole argument.
1006The optional arguments MINIBUF and ALL-FRAMES specify the set of 987The optional arguments MINIBUF and ALL-FRAMES specify the set of
1007windows to include in the walk, see also `next-window'. 988windows to include in the walk.
1008 989
1009MINIBUF t means include the minibuffer window even if the 990MINIBUF t means include the minibuffer window even if the
1010minibuffer is not active. MINIBUF nil or omitted means include 991minibuffer is not active. MINIBUF nil or omitted means include
@@ -1012,29 +993,24 @@ the minibuffer window only if the minibuffer is active. Any
1012other value means do not include the minibuffer window even if 993other value means do not include the minibuffer window even if
1013the minibuffer is active. 994the minibuffer is active.
1014 995
1015Several frames may share a single minibuffer; if the minibuffer 996ALL-FRAMES nil or omitted means consider all windows on the
1016is active, all windows on all frames that share that minibuffer 997selected frame, plus the minibuffer window if specified by the
1017are included too. Therefore, if you are using a separate 998MINIBUF argument. If the minibuffer counts, consider all windows
1018minibuffer frame and the minibuffer is active and MINIBUF says it 999on all frames that share that minibuffer too. The following
1019counts, `walk-windows' includes the windows in the frame from 1000non-nil values of ALL-FRAMES have special meanings:
1020which you entered the minibuffer, as well as the minibuffer 1001
1021window. 1002- t means consider all windows on all existing frames.
1022 1003
1023ALL-FRAMES nil or omitted means cycle through all windows on the 1004- `visible' means consider all windows on all visible frames on
1024 selected frame, plus the minibuffer window if specified by the 1005 the current terminal.
1025 MINIBUF argument, see above. If the minibuffer counts, cycle 1006
1026 through all windows on all frames that share that minibuffer 1007- 0 (the number zero) means consider all windows on all visible
1027 too. 1008 and iconified frames on the current terminal.
1028ALL-FRAMES t means cycle through all windows on all existing 1009
1029 frames. 1010- A frame means consider all windows on that frame only.
1030ALL-FRAMES `visible' means cycle through all windows on all 1011
1031 visible frames on the current terminal. 1012Anything else means consider all windows on the selected frame
1032ALL-FRAMES 0 means cycle through all windows on all visible and 1013and no others.
1033 iconified frames on the current terminal.
1034ALL-FRAMES a frame means cycle through all windows on that frame
1035 only.
1036Anything else means cycle through all windows on the selected
1037 frame and no others.
1038 1014
1039This function changes neither the order of recently selected 1015This function changes neither the order of recently selected
1040windows nor the buffer list." 1016windows nor the buffer list."
@@ -1048,33 +1024,146 @@ windows nor the buffer list."
1048 (save-selected-window 1024 (save-selected-window
1049 (when (framep all-frames) 1025 (when (framep all-frames)
1050 (select-window (frame-first-window all-frames) 'norecord)) 1026 (select-window (frame-first-window all-frames) 'norecord))
1051 (let* (walk-windows-already-seen 1027 (dolist (walk-windows-window (window-list-1 nil minibuf all-frames))
1052 (walk-windows-current (selected-window))) 1028 (funcall proc walk-windows-window))))
1053 (while (progn 1029
1054 (setq walk-windows-current 1030(defun window-in-direction-2 (window posn &optional horizontal)
1055 (next-window walk-windows-current minibuf all-frames)) 1031 "Support function for `window-in-direction'."
1056 (not (memq walk-windows-current walk-windows-already-seen))) 1032 (if horizontal
1057 (setq walk-windows-already-seen 1033 (let ((top (window-top-line window)))
1058 (cons walk-windows-current walk-windows-already-seen)) 1034 (if (> top posn)
1059 (funcall proc walk-windows-current))))) 1035 (- top posn)
1036 (- posn top (window-total-height window))))
1037 (let ((left (window-left-column window)))
1038 (if (> left posn)
1039 (- left posn)
1040 (- posn left (window-total-width window))))))
1041
1042(defun window-in-direction (direction &optional window ignore)
1043 "Return window in DIRECTION as seen from WINDOW.
1044DIRECTION must be one of `above', `below', `left' or `right'.
1045WINDOW must be a live window and defaults to the selected one.
1046IGNORE, when non-nil means a window can be returned even if its
1047`no-other-window' parameter is non-nil."
1048 (setq window (normalize-live-window window))
1049 (unless (memq direction '(above below left right))
1050 (error "Wrong direction %s" direction))
1051 (let* ((frame (window-frame window))
1052 (hor (memq direction '(left right)))
1053 (first (if hor
1054 (window-left-column window)
1055 (window-top-line window)))
1056 (last (+ first (if hor
1057 (window-total-width window)
1058 (window-total-height window))))
1059 (posn-cons (nth 6 (posn-at-point (window-point window) window)))
1060 ;; The column / row value of `posn-at-point' can be nil for the
1061 ;; mini-window, guard against that.
1062 (posn (if hor
1063 (+ (or (cdr posn-cons) 1) (window-top-line window))
1064 (+ (or (car posn-cons) 1) (window-left-column window))))
1065 (best-edge
1066 (cond
1067 ((eq direction 'below) (frame-height frame))
1068 ((eq direction 'right) (frame-width frame))
1069 (t -1)))
1070 (best-edge-2 best-edge)
1071 (best-diff-2 (if hor (frame-height frame) (frame-width frame)))
1072 best best-2 best-diff-2-new)
1073 (walk-window-tree
1074 (lambda (w)
1075 (let* ((w-top (window-top-line w))
1076 (w-left (window-left-column w)))
1077 (cond
1078 ((or (eq window w)
1079 ;; Ignore ourselves.
1080 (and (window-parameter w 'no-other-window)
1081 ;; Ignore W unless IGNORE is non-nil.
1082 (not ignore))))
1083 (hor
1084 (cond
1085 ((and (<= w-top posn)
1086 (< posn (+ w-top (window-total-height w))))
1087 ;; W is to the left or right of WINDOW and covers POSN.
1088 (when (or (and (eq direction 'left)
1089 (<= w-left first) (> w-left best-edge))
1090 (and (eq direction 'right)
1091 (>= w-left last) (< w-left best-edge)))
1092 (setq best-edge w-left)
1093 (setq best w)))
1094 ((and (or (and (eq direction 'left)
1095 (<= (+ w-left (window-total-width w)) first))
1096 (and (eq direction 'right) (<= last w-left)))
1097 ;; W is to the left or right of WINDOW but does not
1098 ;; cover POSN.
1099 (setq best-diff-2-new
1100 (window-in-direction-2 w posn hor))
1101 (or (< best-diff-2-new best-diff-2)
1102 (and (= best-diff-2-new best-diff-2)
1103 (if (eq direction 'left)
1104 (> w-left best-edge-2)
1105 (< w-left best-edge-2)))))
1106 (setq best-edge-2 w-left)
1107 (setq best-diff-2 best-diff-2-new)
1108 (setq best-2 w))))
1109 (t
1110 (cond
1111 ((and (<= w-left posn)
1112 (< posn (+ w-left (window-total-width w))))
1113 ;; W is above or below WINDOW and covers POSN.
1114 (when (or (and (eq direction 'above)
1115 (<= w-top first) (> w-top best-edge))
1116 (and (eq direction 'below)
1117 (>= w-top first) (< w-top best-edge)))
1118 (setq best-edge w-top)
1119 (setq best w)))
1120 ((and (or (and (eq direction 'above)
1121 (<= (+ w-top (window-total-height w)) first))
1122 (and (eq direction 'below) (<= last w-top)))
1123 ;; W is above or below WINDOW but does not cover POSN.
1124 (setq best-diff-2-new
1125 (window-in-direction-2 w posn hor))
1126 (or (< best-diff-2-new best-diff-2)
1127 (and (= best-diff-2-new best-diff-2)
1128 (if (eq direction 'above)
1129 (> w-top best-edge-2)
1130 (< w-top best-edge-2)))))
1131 (setq best-edge-2 w-top)
1132 (setq best-diff-2 best-diff-2-new)
1133 (setq best-2 w)))))))
1134 (window-frame window))
1135 (or best best-2)))
1060 1136
1061(defun get-window-with-predicate (predicate &optional minibuf 1137(defun get-window-with-predicate (predicate &optional minibuf
1062 all-frames default) 1138 all-frames default)
1063 "Return a window satisfying PREDICATE. 1139 "Return a live window satisfying PREDICATE.
1064More precisely, cycle through all windows using `walk-windows', 1140More precisely, cycle through all windows calling the function
1065calling the function PREDICATE on each one of them with the 1141PREDICATE on each one of them with the window as its sole
1066window as its sole argument. Return the first window for which 1142argument. Return the first window for which PREDICATE returns
1067PREDICATE returns non-nil. If no window satisfies PREDICATE, 1143non-nil. If no window satisfies PREDICATE, return DEFAULT.
1068return DEFAULT. 1144
1145ALL-FRAMES nil or omitted means consider all windows on the selected
1146frame, plus the minibuffer window if specified by the MINIBUF
1147argument. If the minibuffer counts, consider all windows on all
1148frames that share that minibuffer too. The following non-nil
1149values of ALL-FRAMES have special meanings:
1069 1150
1070The optional arguments MINIBUF and ALL-FRAMES specify the set of 1151- t means consider all windows on all existing frames.
1071windows to include. See `walk-windows' for the meaning of these 1152
1072arguments." 1153- `visible' means consider all windows on all visible frames on
1154 the current terminal.
1155
1156- 0 (the number zero) means consider all windows on all visible
1157 and iconified frames on the current terminal.
1158
1159- A frame means consider all windows on that frame only.
1160
1161Anything else means consider all windows on the selected frame
1162and no others."
1073 (catch 'found 1163 (catch 'found
1074 (walk-windows #'(lambda (window) 1164 (dolist (window (window-list-1 nil minibuf all-frames))
1075 (when (funcall predicate window) 1165 (when (funcall predicate window)
1076 (throw 'found window))) 1166 (throw 'found window)))
1077 minibuf all-frames)
1078 default)) 1167 default))
1079 1168
1080(defalias 'some-window 'get-window-with-predicate) 1169(defalias 'some-window 'get-window-with-predicate)
@@ -1115,6 +1204,33 @@ selected frame and no others."
1115 (setq best-window window))))) 1204 (setq best-window window)))))
1116 (or best-window second-best-window))) 1205 (or best-window second-best-window)))
1117 1206
1207(defun get-mru-window (&optional all-frames)
1208 "Return the most recently used window on frames specified by ALL-FRAMES.
1209Do not return a minibuffer window.
1210
1211The following non-nil values of the optional argument ALL-FRAMES
1212have special meanings:
1213
1214- t means consider all windows on all existing frames.
1215
1216- `visible' means consider all windows on all visible frames on
1217 the current terminal.
1218
1219- 0 (the number zero) means consider all windows on all visible
1220 and iconified frames on the current terminal.
1221
1222- A frame means consider all windows on that frame only.
1223
1224Any other value of ALL-FRAMES means consider all windows on the
1225selected frame and no others."
1226 (let (best-window best-time time)
1227 (dolist (window (window-list-1 nil nil all-frames))
1228 (setq time (window-use-time window))
1229 (when (or (not best-time) (> time best-time))
1230 (setq best-time time)
1231 (setq best-window window)))
1232 best-window))
1233
1118(defun get-largest-window (&optional all-frames dedicated) 1234(defun get-largest-window (&optional all-frames dedicated)
1119 "Return the largest window on frames specified by ALL-FRAMES. 1235 "Return the largest window on frames specified by ALL-FRAMES.
1120A minibuffer window is never a candidate. A dedicated window is 1236A minibuffer window is never a candidate. A dedicated window is
@@ -1189,16 +1305,47 @@ and no others."
1189(defun minibuffer-window-active-p (window) 1305(defun minibuffer-window-active-p (window)
1190 "Return t if WINDOW is the currently active minibuffer window." 1306 "Return t if WINDOW is the currently active minibuffer window."
1191 (eq window (active-minibuffer-window))) 1307 (eq window (active-minibuffer-window)))
1192 1308
1193(defun count-windows (&optional minibuf) 1309(defun count-windows (&optional minibuf)
1194 "Return the number of visible windows. 1310 "Return the number of live windows on the selected frame.
1195The optional argument MINIBUF specifies whether the minibuffer 1311The optional argument MINIBUF specifies whether the minibuffer
1196window shall be counted. See `walk-windows' for the precise 1312window shall be counted. See `walk-windows' for the precise
1197meaning of this argument." 1313meaning of this argument."
1198 (let ((count 0)) 1314 (length (window-list-1 nil minibuf)))
1199 (walk-windows (lambda (_w) (setq count (+ count 1))) 1315
1200 minibuf) 1316;; This should probably return non-nil when the selected window is part
1201 count)) 1317;; of an atomic window whose root is the frame's root window.
1318(defun one-window-p (&optional nomini all-frames)
1319 "Return non-nil if the selected window is the only window.
1320Optional arg NOMINI non-nil means don't count the minibuffer
1321even if it is active. Otherwise, the minibuffer is counted
1322when it is active.
1323
1324Optional argument ALL-FRAMES specifies the set of frames to
1325consider, see also `next-window'. ALL-FRAMES nil or omitted
1326means consider windows on the selected frame only, plus the
1327minibuffer window if specified by the NOMINI argument. If the
1328minibuffer counts, consider all windows on all frames that share
1329that minibuffer too. The remaining non-nil values of ALL-FRAMES
1330with a special meaning are:
1331
1332- t means consider all windows on all existing frames.
1333
1334- `visible' means consider all windows on all visible frames on
1335 the current terminal.
1336
1337- 0 (the number zero) means consider all windows on all visible
1338 and iconified frames on the current terminal.
1339
1340- A frame means consider all windows on that frame only.
1341
1342Anything else means consider all windows on the selected frame
1343and no others."
1344 (let ((base-window (selected-window)))
1345 (if (and nomini (eq base-window (minibuffer-window)))
1346 (setq base-window (next-window base-window)))
1347 (eq base-window
1348 (next-window base-window (if nomini 'arg) all-frames))))
1202 1349
1203;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1350;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1204;;; `balance-windows' subroutines using `window-tree' 1351;;; `balance-windows' subroutines using `window-tree'