aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Rudalics2011-06-11 11:50:37 +0200
committerMartin Rudalics2011-06-11 11:50:37 +0200
commit9397e56f7424b87f0b52be1235b25a56002661f1 (patch)
tree076db90751a94af4790e661a5a9a2d5cbdc2975f /src
parentb50691aaafa255709b1117000ce6fb98d9772695 (diff)
downloademacs-9397e56f7424b87f0b52be1235b25a56002661f1.tar.gz
emacs-9397e56f7424b87f0b52be1235b25a56002661f1.zip
Move/add window-buffer-related functions to window.el.
* buffer.c: New Lisp objects Qbuffer_list_update_hook and Qclone_number. Remove external declaration of Qdelete_window. (Fbuffer_list): Rewrite doc-string. Minor restructuring of code. (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer): Run Qbuffer_list_update_hook if allowed. (Fother_buffer): Rewrite doc-string. Major rewrite for new buffer list implementation. (other_buffer_safely): New function. (Fkill_buffer): Replace call to replace_buffer_in_all_windows by calls to replace_buffer_in_windows and replace_buffer_in_windows_safely. Run Qbuffer_list_update_hook if allowed. (record_buffer): Inhibit quitting and rewrite using quittable functions. Run Qbuffer_list_update_hook if allowed. (Frecord_buffer, Funrecord_buffer): New functions. (switch_to_buffer_1, Fswitch_to_buffer): Remove. Move switch-to-buffer to window.el. (bury-buffer): Move to window.el. (Vbuffer_list_update_hook): New variable. * lisp.h (other_buffer_safely): Add prototype in buffer.c section. * window.h (resize_frame_windows): Move up in code. (Fwindow_frame): Remove EXFUN. (replace_buffer_in_all_windows): Remove prototype. (replace_buffer_in_windows_safely): Add prototype. * window.c: Declare Qdelete_window static again. Move down declaration of select_count. (Fnext_window, Fprevious_window): Rewrite doc-strings. (Fother_window): Move to window.el. (window_loop): Remove DELETE_BUFFER_WINDOWS and UNSHOW_BUFFER cases. Add REPLACE_BUFFER_IN_WINDOWS_SAFELY case. (Fdelete_windows_on, Freplace_buffer_in_windows): Move to window.el. (replace_buffer_in_windows): Implement by calling Qreplace_buffer_in_windows. (replace_buffer_in_all_windows): Remove with some functionality moved into replace_buffer_in_windows_safely. (replace_buffer_in_windows_safely): New function. (select_window_norecord, select_frame_norecord): Move in front of run_window_configuration_change_hook. Remove now obsolete declarations. (Fset_window_buffer): Rewrite doc-string. Call Qrecord_window_buffer. (keys_of_window): Move binding for other-window to window.el. * loadup.el (top-level): Load window before files for the sake of replace-buffer-in-windows. * files.el (read-buffer-to-switch) (switch-to-buffer-other-window) (switch-to-buffer-other-frame, display-buffer-other-frame): Move to window.el. * simple.el (get-next-valid-buffer, last-buffer, next-buffer) (previous-buffer): Move to window.el. * bindings.el (unbury-buffer): Move to window.el. * window.el (delete-other-windows-vertically): Move after definition of delete-other-windows. (other-window, delete-windows-on, replace-buffer-in-windows): Move here from window.c. (record-window-buffer, unrecord-window-buffer) (set-window-buffer-start-and-point, switch-to-prev-buffer) (switch-to-next-buffer): New functions. (get-next-valid-buffer, last-buffer, next-buffer): Move here from simple.el. Call switch-to-next-buffer. (previous-buffer): Move here from simple.el. Call switch-to-prev-buffer. (bury-buffer): Move here from buffer.c. Switch to previous buffer when window cannot be deleted. (unbury-buffer): Move here from bindings.el. (ctl-x-map): Move binding for other-window from window.c to here. (read-buffer-to-switch, switch-to-buffer-other-window) (switch-to-buffer-other-frame): Move here from files.el. (normalize-buffer-to-switch-to): New functions. (switch-to-buffer): Move here from buffer.c. Use read-buffer-to-switch and normalize-buffer-to-switch-to.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog51
-rw-r--r--src/buffer.c455
-rw-r--r--src/lisp.h1
-rw-r--r--src/window.c398
-rw-r--r--src/window.h6
5 files changed, 387 insertions, 524 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ed3ea6dfbb3..b53eea56a0d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,54 @@
12011-06-11 Martin Rudalics <rudalics@gmx.at>
2
3 * buffer.c: New Lisp objects Qbuffer_list_update_hook and
4 Qclone_number. Remove external declaration of Qdelete_window.
5 (Fbuffer_list): Rewrite doc-string. Minor restructuring of
6 code.
7 (Fget_buffer_create, Fmake_indirect_buffer, Frename_buffer): Run
8 Qbuffer_list_update_hook if allowed.
9 (Fother_buffer): Rewrite doc-string. Major rewrite for new
10 buffer list implementation.
11 (other_buffer_safely): New function.
12 (Fkill_buffer): Replace call to replace_buffer_in_all_windows by
13 calls to replace_buffer_in_windows and
14 replace_buffer_in_windows_safely. Run Qbuffer_list_update_hook
15 if allowed.
16 (record_buffer): Inhibit quitting and rewrite using quittable
17 functions. Run Qbuffer_list_update_hook if allowed.
18 (Frecord_buffer, Funrecord_buffer): New functions.
19 (switch_to_buffer_1, Fswitch_to_buffer): Remove. Move
20 switch-to-buffer to window.el.
21 (bury-buffer): Move to window.el.
22 (Vbuffer_list_update_hook): New variable.
23
24 * lisp.h (other_buffer_safely): Add prototype in buffer.c
25 section.
26
27 * window.h (resize_frame_windows): Move up in code.
28 (Fwindow_frame): Remove EXFUN.
29 (replace_buffer_in_all_windows): Remove prototype.
30 (replace_buffer_in_windows_safely): Add prototype.
31
32 * window.c: Declare Qdelete_window static again. Move down
33 declaration of select_count.
34 (Fnext_window, Fprevious_window): Rewrite doc-strings.
35 (Fother_window): Move to window.el.
36 (window_loop): Remove DELETE_BUFFER_WINDOWS and UNSHOW_BUFFER
37 cases. Add REPLACE_BUFFER_IN_WINDOWS_SAFELY case.
38 (Fdelete_windows_on, Freplace_buffer_in_windows): Move to
39 window.el.
40 (replace_buffer_in_windows): Implement by calling
41 Qreplace_buffer_in_windows.
42 (replace_buffer_in_all_windows): Remove with some functionality
43 moved into replace_buffer_in_windows_safely.
44 (replace_buffer_in_windows_safely): New function.
45 (select_window_norecord, select_frame_norecord): Move in front
46 of run_window_configuration_change_hook. Remove now obsolete
47 declarations.
48 (Fset_window_buffer): Rewrite doc-string. Call
49 Qrecord_window_buffer.
50 (keys_of_window): Move binding for other-window to window.el.
51
12011-06-11 Chong Yidong <cyd@stupidchicken.com> 522011-06-11 Chong Yidong <cyd@stupidchicken.com>
2 53
3 * dispextern.h (struct image): Replace data member, whose int_val 54 * dispextern.h (struct image): Replace data member, whose int_val
diff --git a/src/buffer.c b/src/buffer.c
index 0862de9baf7..bd059cdbe14 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -131,13 +131,15 @@ static Lisp_Object Qprotected_field;
131static Lisp_Object QSFundamental; /* A string "Fundamental" */ 131static Lisp_Object QSFundamental; /* A string "Fundamental" */
132 132
133static Lisp_Object Qkill_buffer_hook; 133static Lisp_Object Qkill_buffer_hook;
134static Lisp_Object Qbuffer_list_update_hook;
134 135
135static Lisp_Object Qget_file_buffer; 136static Lisp_Object Qget_file_buffer;
136 137
137static Lisp_Object Qoverlayp; 138static Lisp_Object Qoverlayp;
138 139
139Lisp_Object Qpriority, Qbefore_string, Qafter_string; 140Lisp_Object Qpriority, Qbefore_string, Qafter_string;
140static Lisp_Object Qevaporate; 141
142static Lisp_Object Qclone_number, Qevaporate;
141 143
142Lisp_Object Qmodification_hooks; 144Lisp_Object Qmodification_hooks;
143Lisp_Object Qinsert_in_front_hooks; 145Lisp_Object Qinsert_in_front_hooks;
@@ -171,9 +173,9 @@ Value is nil if OBJECT is not a buffer or if it has been killed. */)
171 173
172DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0, 174DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
173 doc: /* Return a list of all existing live buffers. 175 doc: /* Return a list of all existing live buffers.
174If the optional arg FRAME is a frame, we return the buffer list 176If the optional arg FRAME is a frame, we return the buffer list in the
175in the proper order for that frame: the buffers in FRAME's `buffer-list' 177proper order for that frame: the buffers show in FRAME come first,
176frame parameter come first, followed by the rest of the buffers. */) 178followed by the rest of the buffers. */)
177 (Lisp_Object frame) 179 (Lisp_Object frame)
178{ 180{
179 Lisp_Object general; 181 Lisp_Object general;
@@ -185,9 +187,9 @@ frame parameter come first, followed by the rest of the buffers. */)
185 Lisp_Object args[3]; 187 Lisp_Object args[3];
186 188
187 CHECK_FRAME (frame); 189 CHECK_FRAME (frame);
188
189 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list); 190 framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
190 prevlist = Fnreverse (Fcopy_sequence (XFRAME (frame)->buried_buffer_list)); 191 prevlist = Fnreverse (Fcopy_sequence
192 (XFRAME (frame)->buried_buffer_list));
191 193
192 /* Remove from GENERAL any buffer that duplicates one in 194 /* Remove from GENERAL any buffer that duplicates one in
193 FRAMELIST or PREVLIST. */ 195 FRAMELIST or PREVLIST. */
@@ -209,8 +211,8 @@ frame parameter come first, followed by the rest of the buffers. */)
209 args[2] = prevlist; 211 args[2] = prevlist;
210 return Fnconc (3, args); 212 return Fnconc (3, args);
211 } 213 }
212 214 else
213 return general; 215 return general;
214} 216}
215 217
216/* Like Fassoc, but use Fstring_equal to compare 218/* Like Fassoc, but use Fstring_equal to compare
@@ -384,6 +386,9 @@ even if it is dead. The return value is never nil. */)
384 /* Put this in the alist of all live buffers. */ 386 /* Put this in the alist of all live buffers. */
385 XSETBUFFER (buffer, b); 387 XSETBUFFER (buffer, b);
386 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil)); 388 Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buffer), Qnil));
389 /* And run buffer-list-update-hook. */
390 if (!NILP (Vrun_hooks))
391 call1 (Vrun_hooks, Qbuffer_list_update_hook);
387 392
388 /* An error in calling the function here (should someone redefine it) 393 /* An error in calling the function here (should someone redefine it)
389 can lead to infinite regress until you run out of stack. rms 394 can lead to infinite regress until you run out of stack. rms
@@ -659,6 +664,10 @@ CLONE nil means the indirect buffer's state is reset to default values. */)
659 set_buffer_internal_1 (old_b); 664 set_buffer_internal_1 (old_b);
660 } 665 }
661 666
667 /* Run buffer-list-update-hook. */
668 if (!NILP (Vrun_hooks))
669 call1 (Vrun_hooks, Qbuffer_list_update_hook);
670
662 return buf; 671 return buf;
663} 672}
664 673
@@ -1262,81 +1271,119 @@ This does not change the name of the visited file (if any). */)
1262 if (NILP (BVAR (current_buffer, filename)) 1271 if (NILP (BVAR (current_buffer, filename))
1263 && !NILP (BVAR (current_buffer, auto_save_file_name))) 1272 && !NILP (BVAR (current_buffer, auto_save_file_name)))
1264 call0 (intern ("rename-auto-save-file")); 1273 call0 (intern ("rename-auto-save-file"));
1274
1275 /* Run buffer-list-update-hook. */
1276 if (!NILP (Vrun_hooks))
1277 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1278
1265 /* Refetch since that last call may have done GC. */ 1279 /* Refetch since that last call may have done GC. */
1266 return BVAR (current_buffer, name); 1280 return BVAR (current_buffer, name);
1267} 1281}
1268 1282
1269DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, 1283DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0,
1270 doc: /* Return most recently selected buffer other than BUFFER. 1284 doc: /* Return most recently selected buffer other than BUFFER.
1271Buffers not visible in windows are preferred to visible buffers, 1285Buffers not visible in windows are preferred to visible buffers, unless
1272unless optional second argument VISIBLE-OK is non-nil. 1286optional second argument VISIBLE-OK is non-nil. Ignore the argument
1273If the optional third argument FRAME is non-nil, use that frame's 1287BUFFER unless it denotes a live buffer. If the optional third argument
1274buffer list instead of the selected frame's buffer list. 1288FRAME is non-nil, use that frame's buffer list instead of the selected
1275If no other buffer exists, the buffer `*scratch*' is returned. 1289frame's buffer list.
1276If BUFFER is omitted or nil, some interesting buffer is returned. */) 1290
1291The buffer is found by scanning the selected or specified frame's buffer
1292list first, followed by the list of all buffers. If no other buffer
1293exists, return the buffer `*scratch*' (creating it if necessary). */)
1277 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) 1294 (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame)
1278{ 1295{
1279 register Lisp_Object tail, buf, notsogood, tem, pred, add_ons; 1296 Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
1280 notsogood = Qnil; 1297 Lisp_Object tail, buf, pred;
1298 Lisp_Object notsogood = Qnil;
1281 1299
1282 if (NILP (frame)) 1300 if (NILP (frame))
1283 frame = selected_frame; 1301 frame = selected_frame;
1284 1302
1285 CHECK_FRAME (frame); 1303 CHECK_FRAME (frame);
1286 1304
1287 tail = Vbuffer_alist;
1288 pred = frame_buffer_predicate (frame); 1305 pred = frame_buffer_predicate (frame);
1289 1306 /* Consider buffers that have been seen in the frame first. */
1290 /* Consider buffers that have been seen in the selected frame 1307 tail = XFRAME (frame)->buffer_list;
1291 before other buffers. */ 1308 for (; CONSP (tail); tail = XCDR (tail))
1292
1293 tem = frame_buffer_list (frame);
1294 add_ons = Qnil;
1295 while (CONSP (tem))
1296 { 1309 {
1297 if (BUFFERP (XCAR (tem))) 1310 buf = XCAR (tail);
1298 add_ons = Fcons (Fcons (Qnil, XCAR (tem)), add_ons); 1311 if (BUFFERP (buf) && !EQ (buf, buffer)
1299 tem = XCDR (tem); 1312 && !NILP (BVAR (XBUFFER (buf), name))
1313 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
1314 /* If the frame has a buffer_predicate, disregard buffers that
1315 don't fit the predicate. */
1316 && (NILP (pred) || !NILP (call1 (pred, buf))))
1317 {
1318 if (!NILP (visible_ok)
1319 || NILP (Fget_buffer_window (buf, Qvisible)))
1320 return buf;
1321 else if (NILP (notsogood))
1322 notsogood = buf;
1323 }
1300 } 1324 }
1301 tail = nconc2 (Fnreverse (add_ons), tail);
1302 1325
1326 /* Consider alist of all buffers next. */
1327 tail = Vbuffer_alist;
1303 for (; CONSP (tail); tail = XCDR (tail)) 1328 for (; CONSP (tail); tail = XCDR (tail))
1304 { 1329 {
1305 buf = Fcdr (XCAR (tail)); 1330 buf = Fcdr (XCAR (tail));
1306 if (EQ (buf, buffer)) 1331 if (BUFFERP (buf) && !EQ (buf, buffer)
1307 continue; 1332 && !NILP (BVAR (XBUFFER (buf), name))
1333 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' ')
1334 /* If the frame has a buffer_predicate, disregard buffers that
1335 don't fit the predicate. */
1336 && (NILP (pred) || !NILP (call1 (pred, buf))))
1337 {
1338 if (!NILP (visible_ok)
1339 || NILP (Fget_buffer_window (buf, Qvisible)))
1340 return buf;
1341 else if (NILP (notsogood))
1342 notsogood = buf;
1343 }
1344 }
1345
1346 if (!NILP (notsogood))
1347 return notsogood;
1348 else
1349 {
1350 buf = Fget_buffer (build_string ("*scratch*"));
1308 if (NILP (buf)) 1351 if (NILP (buf))
1309 continue;
1310 if (NILP (BVAR (XBUFFER (buf), name)))
1311 continue;
1312 if (SREF (BVAR (XBUFFER (buf), name), 0) == ' ')
1313 continue;
1314 /* If the selected frame has a buffer_predicate,
1315 disregard buffers that don't fit the predicate. */
1316 if (!NILP (pred))
1317 { 1352 {
1318 tem = call1 (pred, buf); 1353 buf = Fget_buffer_create (build_string ("*scratch*"));
1319 if (NILP (tem)) 1354 Fset_buffer_major_mode (buf);
1320 continue;
1321 } 1355 }
1356 return buf;
1357 }
1358}
1322 1359
1323 if (NILP (visible_ok)) 1360/* The following function is a safe variant of Fother_buffer: It doesn't
1324 tem = Fget_buffer_window (buf, Qvisible); 1361 pay attention to any frame-local buffer lists, doesn't care about
1325 else 1362 visibility of buffers, and doesn't evaluate any frame predicates. */
1326 tem = Qnil; 1363
1327 if (NILP (tem)) 1364Lisp_Object
1365other_buffer_safely (Lisp_Object buffer)
1366{
1367 Lisp_Object Fset_buffer_major_mode (Lisp_Object buffer);
1368 Lisp_Object tail, buf;
1369
1370 tail = Vbuffer_alist;
1371 for (; CONSP (tail); tail = XCDR (tail))
1372 {
1373 buf = Fcdr (XCAR (tail));
1374 if (BUFFERP (buf) && !EQ (buf, buffer)
1375 && !NILP (BVAR (XBUFFER (buf), name))
1376 && (SREF (BVAR (XBUFFER (buf), name), 0) != ' '))
1328 return buf; 1377 return buf;
1329 if (NILP (notsogood))
1330 notsogood = buf;
1331 } 1378 }
1332 if (!NILP (notsogood)) 1379
1333 return notsogood;
1334 buf = Fget_buffer (build_string ("*scratch*")); 1380 buf = Fget_buffer (build_string ("*scratch*"));
1335 if (NILP (buf)) 1381 if (NILP (buf))
1336 { 1382 {
1337 buf = Fget_buffer_create (build_string ("*scratch*")); 1383 buf = Fget_buffer_create (build_string ("*scratch*"));
1338 Fset_buffer_major_mode (buf); 1384 Fset_buffer_major_mode (buf);
1339 } 1385 }
1386
1340 return buf; 1387 return buf;
1341} 1388}
1342 1389
@@ -1509,13 +1556,20 @@ with SIGHUP. */)
1509 if (NILP (BVAR (b, name))) 1556 if (NILP (BVAR (b, name)))
1510 return Qnil; 1557 return Qnil;
1511 1558
1559 /* These may run Lisp code and into infinite loops (if someone
1560 insisted on circular lists) so allow quitting here. */
1561 replace_buffer_in_windows (buffer);
1562 frames_discard_buffer (buffer);
1563
1512 clear_charpos_cache (b); 1564 clear_charpos_cache (b);
1513 1565
1514 tem = Vinhibit_quit; 1566 tem = Vinhibit_quit;
1515 Vinhibit_quit = Qt; 1567 Vinhibit_quit = Qt;
1516 replace_buffer_in_all_windows (buffer); 1568 /* Remove the buffer from the list of all buffers. */
1517 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist); 1569 Vbuffer_alist = Fdelq (Frassq (buffer, Vbuffer_alist), Vbuffer_alist);
1518 frames_discard_buffer (buffer); 1570 /* If replace_buffer_in_windows didn't do its job correctly fix that
1571 now. */
1572 replace_buffer_in_windows_safely (buffer);
1519 Vinhibit_quit = tem; 1573 Vinhibit_quit = tem;
1520 1574
1521 /* Delete any auto-save file, if we saved it in this session. 1575 /* Delete any auto-save file, if we saved it in this session.
@@ -1589,83 +1643,103 @@ with SIGHUP. */)
1589 UNBLOCK_INPUT; 1643 UNBLOCK_INPUT;
1590 BVAR (b, undo_list) = Qnil; 1644 BVAR (b, undo_list) = Qnil;
1591 1645
1646 /* Run buffer-list-update-hook. */
1647 if (!NILP (Vrun_hooks))
1648 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1649
1592 return Qt; 1650 return Qt;
1593} 1651}
1594 1652
1595/* Move the assoc for buffer BUF to the front of buffer-alist. Since 1653/* Move association for BUFFER to the front of buffer (a)lists. Since
1596 we do this each time BUF is selected visibly, the more recently 1654 we do this each time BUFFER is selected visibly, the more recently
1597 selected buffers are always closer to the front of the list. This 1655 selected buffers are always closer to the front of those lists. This
1598 means that other_buffer is more likely to choose a relevant buffer. */ 1656 means that other_buffer is more likely to choose a relevant buffer.
1657
1658 Note that this moves BUFFER to the front of the buffer lists of the
1659 selected frame even if BUFFER is not shown there. If BUFFER is not
1660 shown in the selected frame, consider the present behavior a feature.
1661 `select-window' gets this right since it shows BUFFER in the selected
1662 window when calling us. */
1599 1663
1600void 1664void
1601record_buffer (Lisp_Object buf) 1665record_buffer (Lisp_Object buffer)
1602{ 1666{
1603 register Lisp_Object list, prev; 1667 Lisp_Object aelt, link, tem;
1604 Lisp_Object frame; 1668 register struct frame *f = XFRAME (selected_frame);
1605 frame = selected_frame; 1669 register struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
1606 1670
1607 prev = Qnil; 1671 CHECK_BUFFER (buffer);
1608 for (list = Vbuffer_alist; CONSP (list); list = XCDR (list))
1609 {
1610 if (EQ (XCDR (XCAR (list)), buf))
1611 break;
1612 prev = list;
1613 }
1614 1672
1615 /* Effectively do Vbuffer_alist = Fdelq (list, Vbuffer_alist); 1673 /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
1616 we cannot use Fdelq itself here because it allows quitting. */ 1674 Don't allow quitting since this might leave the buffer list in an
1675 inconsistent state. */
1676 tem = Vinhibit_quit;
1677 Vinhibit_quit = Qt;
1678 aelt = Frassq (buffer, Vbuffer_alist);
1679 link = Fmemq (aelt, Vbuffer_alist);
1680 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
1681 XSETCDR (link, Vbuffer_alist);
1682 Vbuffer_alist = link;
1683 Vinhibit_quit = tem;
1617 1684
1618 if (NILP (prev)) 1685 /* Update buffer list of selected frame. */
1619 Vbuffer_alist = XCDR (Vbuffer_alist); 1686 f->buffer_list = Fcons (buffer, Fdelq (buffer, f->buffer_list));
1620 else 1687 f->buried_buffer_list = Fdelq (buffer, f->buried_buffer_list);
1621 XSETCDR (prev, XCDR (XCDR (prev)));
1622 1688
1623 XSETCDR (list, Vbuffer_alist); 1689 /* Run buffer-list-update-hook. */
1624 Vbuffer_alist = list; 1690 if (!NILP (Vrun_hooks))
1691 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1692}
1625 1693
1626 /* Effectively do a delq on buried_buffer_list. */ 1694DEFUN ("record-buffer", Frecord_buffer, Srecord_buffer, 1, 1, 0,
1695 doc: /* Move BUFFER to the front of the buffer list.
1696Return BUFFER. */)
1697 (Lisp_Object buffer)
1698{
1699 CHECK_BUFFER (buffer);
1627 1700
1628 prev = Qnil; 1701 record_buffer (buffer);
1629 for (list = XFRAME (frame)->buried_buffer_list; CONSP (list);
1630 list = XCDR (list))
1631 {
1632 if (EQ (XCAR (list), buf))
1633 {
1634 if (NILP (prev))
1635 XFRAME (frame)->buried_buffer_list = XCDR (list);
1636 else
1637 XSETCDR (prev, XCDR (XCDR (prev)));
1638 break;
1639 }
1640 prev = list;
1641 }
1642 1702
1643 /* Now move this buffer to the front of frame_buffer_list also. */ 1703 return buffer;
1704}
1644 1705
1645 prev = Qnil; 1706 /* Move BUFFER to the end of the buffer (a)lists. Do nothing if the
1646 for (list = frame_buffer_list (frame); CONSP (list); 1707 buffer is killed. For the selected frame's buffer list this moves
1647 list = XCDR (list)) 1708 BUFFER to its end even if it was never shown in that frame. If
1648 { 1709 this happens we have a feature, hence `unrecord-buffer' should be
1649 if (EQ (XCAR (list), buf)) 1710 called only when BUFFER was shown in the selected frame. */
1650 break;
1651 prev = list;
1652 }
1653 1711
1654 /* Effectively do delq. */ 1712DEFUN ("unrecord-buffer", Funrecord_buffer, Sunrecord_buffer, 1, 1, 0,
1713 doc: /* Move BUFFER to the end of the buffer list.
1714Return BUFFER. */)
1715 (Lisp_Object buffer)
1716{
1717 Lisp_Object aelt, link, tem;
1718 register struct frame *f = XFRAME (selected_frame);
1655 1719
1656 if (CONSP (list)) 1720 CHECK_BUFFER (buffer);
1657 {
1658 if (NILP (prev))
1659 set_frame_buffer_list (frame,
1660 XCDR (frame_buffer_list (frame)));
1661 else
1662 XSETCDR (prev, XCDR (XCDR (prev)));
1663 1721
1664 XSETCDR (list, frame_buffer_list (frame)); 1722 /* Update Vbuffer_alist (we know that it has an entry for BUFFER).
1665 set_frame_buffer_list (frame, list); 1723 Don't allow quitting since this might leave the buffer list in an
1666 } 1724 inconsistent state. */
1667 else 1725 tem = Vinhibit_quit;
1668 set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame))); 1726 Vinhibit_quit = Qt;
1727 aelt = Frassq (buffer, Vbuffer_alist);
1728 link = Fmemq (aelt, Vbuffer_alist);
1729 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
1730 XSETCDR (link, Qnil);
1731 Vbuffer_alist = nconc2 (Vbuffer_alist, link);
1732 Vinhibit_quit = tem;
1733
1734 /* Update buffer lists of selected frame. */
1735 f->buffer_list = Fdelq (buffer, f->buffer_list);
1736 f->buried_buffer_list = Fcons (buffer, Fdelq (buffer, f->buried_buffer_list));
1737
1738 /* Run buffer-list-update-hook. */
1739 if (!NILP (Vrun_hooks))
1740 call1 (Vrun_hooks, Qbuffer_list_update_hook);
1741
1742 return buffer;
1669} 1743}
1670 1744
1671DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0, 1745DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
@@ -1708,86 +1782,6 @@ the current buffer's major mode. */)
1708 return unbind_to (count, Qnil); 1782 return unbind_to (count, Qnil);
1709} 1783}
1710 1784
1711/* Switch to buffer BUFFER in the selected window.
1712 If NORECORD is non-nil, don't call record_buffer. */
1713
1714static Lisp_Object
1715switch_to_buffer_1 (Lisp_Object buffer_or_name, Lisp_Object norecord)
1716{
1717 register Lisp_Object buffer;
1718
1719 if (NILP (buffer_or_name))
1720 buffer = Fother_buffer (Fcurrent_buffer (), Qnil, Qnil);
1721 else
1722 {
1723 buffer = Fget_buffer (buffer_or_name);
1724 if (NILP (buffer))
1725 {
1726 buffer = Fget_buffer_create (buffer_or_name);
1727 Fset_buffer_major_mode (buffer);
1728 }
1729 }
1730 Fset_buffer (buffer);
1731 if (NILP (norecord))
1732 record_buffer (buffer);
1733
1734 Fset_window_buffer (EQ (selected_window, minibuf_window)
1735 ? Fnext_window (minibuf_window, Qnil, Qnil)
1736 : selected_window,
1737 buffer, Qnil);
1738
1739 return buffer;
1740}
1741
1742DEFUN ("switch-to-buffer", Fswitch_to_buffer, Sswitch_to_buffer, 1, 2,
1743 "(list (read-buffer-to-switch \"Switch to buffer: \"))",
1744 doc: /* Make BUFFER-OR-NAME current and display it in selected window.
1745BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or
1746nil. Return the buffer switched to.
1747
1748If BUFFER-OR-NAME is a string and does not identify an existing
1749buffer, create a new buffer with that name. Interactively, if
1750`confirm-nonexistent-file-or-buffer' is non-nil, request
1751confirmation before creating a new buffer. If BUFFER-OR-NAME is
1752nil, switch to buffer returned by `other-buffer'.
1753
1754Optional second arg NORECORD non-nil means do not put this buffer
1755at the front of the list of recently selected ones. This
1756function returns the buffer it switched to as a Lisp object.
1757
1758If the selected window is the minibuffer window or dedicated to
1759its buffer, use `pop-to-buffer' for displaying the buffer.
1760
1761WARNING: This is NOT the way to work on another buffer temporarily
1762within a Lisp program! Use `set-buffer' instead. That avoids
1763messing with the window-buffer correspondences. */)
1764 (Lisp_Object buffer_or_name, Lisp_Object norecord)
1765{
1766 if (EQ (buffer_or_name, Fwindow_buffer (selected_window)))
1767 {
1768 /* Basically a NOP. Avoid signalling an error in the case where
1769 the selected window is dedicated, or a minibuffer. */
1770
1771 /* But do put this buffer at the front of the buffer list, unless
1772 that has been inhibited. Note that even if BUFFER-OR-NAME is
1773 at the front of the main buffer-list already, we still want to
1774 move it to the front of the frame's buffer list. */
1775 if (NILP (norecord))
1776 record_buffer (buffer_or_name);
1777 return Fset_buffer (buffer_or_name);
1778 }
1779 else if (EQ (minibuf_window, selected_window)
1780 /* If `dedicated' is neither nil nor t, it means it's
1781 dedicatedness can be overridden by an explicit request
1782 such as a call to switch-to-buffer. */
1783 || EQ (Fwindow_dedicated_p (selected_window), Qt))
1784 /* We can't use the selected window so let `pop-to-buffer' try some
1785 other window. */
1786 return call3 (intern ("pop-to-buffer"), buffer_or_name, Qnil, norecord);
1787 else
1788 return switch_to_buffer_1 (buffer_or_name, norecord);
1789}
1790
1791DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, 1785DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
1792 doc: /* Return the current buffer as a Lisp object. */) 1786 doc: /* Return the current buffer as a Lisp object. */)
1793 (void) 1787 (void)
@@ -1937,70 +1931,6 @@ DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
1937 xsignal1 (Qbuffer_read_only, Fcurrent_buffer ()); 1931 xsignal1 (Qbuffer_read_only, Fcurrent_buffer ());
1938 return Qnil; 1932 return Qnil;
1939} 1933}
1940
1941extern Lisp_Object Qdelete_window;
1942
1943DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "",
1944 doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers.
1945There it is the least likely candidate for `other-buffer' to return;
1946thus, the least likely buffer for \\[switch-to-buffer] to select by
1947default.
1948
1949The argument may be a buffer name or an actual buffer object. If
1950BUFFER-OR-NAME is nil or omitted, bury the current buffer and remove it
1951from the selected window if it is displayed there. If the selected
1952window is dedicated to its buffer, delete that window if there are other
1953windows on the same frame. If the selected window is the only window on
1954its frame, iconify that frame. */)
1955 (register Lisp_Object buffer_or_name)
1956{
1957 Lisp_Object buffer;
1958
1959 /* Figure out what buffer we're going to bury. */
1960 if (NILP (buffer_or_name))
1961 {
1962 Lisp_Object tem;
1963 XSETBUFFER (buffer, current_buffer);
1964
1965 tem = Fwindow_buffer (selected_window);
1966 /* If we're burying the current buffer, unshow it. */
1967 if (EQ (buffer, tem))
1968 {
1969 if (NILP (Fwindow_dedicated_p (selected_window)))
1970 Fswitch_to_buffer (Fother_buffer (buffer, Qnil, Qnil), Qnil);
1971 else if (NILP (XWINDOW (selected_window)->parent))
1972 Ficonify_frame (Fwindow_frame (selected_window));
1973 else
1974 call1 (Qdelete_window, selected_window);
1975 }
1976 }
1977 else
1978 {
1979 buffer = Fget_buffer (buffer_or_name);
1980 if (NILP (buffer))
1981 nsberror (buffer_or_name);
1982 }
1983
1984 /* Move buffer to the end of the buffer list. Do nothing if the
1985 buffer is killed. */
1986 if (!NILP (BVAR (XBUFFER (buffer), name)))
1987 {
1988 Lisp_Object aelt, list;
1989
1990 aelt = Frassq (buffer, Vbuffer_alist);
1991 list = Fmemq (aelt, Vbuffer_alist);
1992 Vbuffer_alist = Fdelq (aelt, Vbuffer_alist);
1993 XSETCDR (list, Qnil);
1994 Vbuffer_alist = nconc2 (Vbuffer_alist, list);
1995
1996 XFRAME (selected_frame)->buffer_list
1997 = Fdelq (buffer, XFRAME (selected_frame)->buffer_list);
1998 XFRAME (selected_frame)->buried_buffer_list
1999 = Fcons (buffer, Fdelq (buffer, XFRAME (selected_frame)->buried_buffer_list));
2000 }
2001
2002 return Qnil;
2003}
2004 1934
2005DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*", 1935DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*",
2006 doc: /* Delete the entire contents of the current buffer. 1936 doc: /* Delete the entire contents of the current buffer.
@@ -6101,6 +6031,15 @@ The function `kill-all-local-variables' runs this before doing anything else. *
6101 Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook"); 6031 Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook");
6102 staticpro (&Qchange_major_mode_hook); 6032 staticpro (&Qchange_major_mode_hook);
6103 6033
6034 DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook,
6035 doc: /* Hook run when the buffer list changes.
6036Functions running this hook are `get-buffer-create',
6037`make-indirect-buffer', `rename-buffer', `kill-buffer',
6038`record-buffer' and `unrecord-buffer'. */);
6039 Vbuffer_list_update_hook = Qnil;
6040 Qbuffer_list_update_hook = intern_c_string ("buffer-list-update-hook");
6041 staticpro (&Qbuffer_list_update_hook);
6042
6104 defsubr (&Sbuffer_live_p); 6043 defsubr (&Sbuffer_live_p);
6105 defsubr (&Sbuffer_list); 6044 defsubr (&Sbuffer_list);
6106 defsubr (&Sget_buffer); 6045 defsubr (&Sget_buffer);
@@ -6122,12 +6061,12 @@ The function `kill-all-local-variables' runs this before doing anything else. *
6122 defsubr (&Sother_buffer); 6061 defsubr (&Sother_buffer);
6123 defsubr (&Sbuffer_enable_undo); 6062 defsubr (&Sbuffer_enable_undo);
6124 defsubr (&Skill_buffer); 6063 defsubr (&Skill_buffer);
6064 defsubr (&Srecord_buffer);
6065 defsubr (&Sunrecord_buffer);
6125 defsubr (&Sset_buffer_major_mode); 6066 defsubr (&Sset_buffer_major_mode);
6126 defsubr (&Sswitch_to_buffer);
6127 defsubr (&Scurrent_buffer); 6067 defsubr (&Scurrent_buffer);
6128 defsubr (&Sset_buffer); 6068 defsubr (&Sset_buffer);
6129 defsubr (&Sbarf_if_buffer_read_only); 6069 defsubr (&Sbarf_if_buffer_read_only);
6130 defsubr (&Sbury_buffer);
6131 defsubr (&Serase_buffer); 6070 defsubr (&Serase_buffer);
6132 defsubr (&Sbuffer_swap_text); 6071 defsubr (&Sbuffer_swap_text);
6133 defsubr (&Sset_buffer_multibyte); 6072 defsubr (&Sset_buffer_multibyte);
diff --git a/src/lisp.h b/src/lisp.h
index c5f810a0746..ae9296b4944 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3011,6 +3011,7 @@ extern Lisp_Object set_buffer_if_live (Lisp_Object);
3011EXFUN (Fbarf_if_buffer_read_only, 0); 3011EXFUN (Fbarf_if_buffer_read_only, 0);
3012EXFUN (Fcurrent_buffer, 0); 3012EXFUN (Fcurrent_buffer, 0);
3013EXFUN (Fother_buffer, 3); 3013EXFUN (Fother_buffer, 3);
3014extern Lisp_Object other_buffer_safely (Lisp_Object);
3014EXFUN (Foverlay_get, 2); 3015EXFUN (Foverlay_get, 2);
3015EXFUN (Fbuffer_modified_p, 1); 3016EXFUN (Fbuffer_modified_p, 1);
3016EXFUN (Fset_buffer_modified_p, 1); 3017EXFUN (Fset_buffer_modified_p, 1);
diff --git a/src/window.c b/src/window.c
index 7a026b3a1c7..959c1c31aa2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -50,9 +50,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
50#include "nsterm.h" 50#include "nsterm.h"
51#endif 51#endif
52 52
53Lisp_Object Qwindowp, Qwindow_live_p, Qdelete_window; 53Lisp_Object Qwindowp, Qwindow_live_p;
54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer; 54static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
55static Lisp_Object Qwindow_deletable_p, Qdisplay_buffer; 55static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window; 56static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically; 57static Lisp_Object Qresize_root_window, Qresize_root_window_vertically;
58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command; 58static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
@@ -310,6 +310,8 @@ selected windows appears and to which many commands apply. */)
310 return selected_window; 310 return selected_window;
311} 311}
312 312
313int window_select_count;
314
313/* If select_window is called with inhibit_point_swap non-zero it will 315/* If select_window is called with inhibit_point_swap non-zero it will
314 not store point of the old selected window's buffer back into that 316 not store point of the old selected window's buffer back into that
315 window's pointm slot. This is needed by Fset_window_configuration to 317 window's pointm slot. This is needed by Fset_window_configuration to
@@ -2210,35 +2212,32 @@ next_window (Lisp_Object window, Lisp_Object minibuf, Lisp_Object all_frames, in
2210 2212
2211DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0, 2213DEFUN ("next-window", Fnext_window, Snext_window, 0, 3, 0,
2212 doc: /* Return window following WINDOW in cyclic ordering of windows. 2214 doc: /* Return window following WINDOW in cyclic ordering of windows.
2213WINDOW defaults to the selected window. The optional arguments 2215WINDOW must be a live window and defaults to the selected one. The
2214MINIBUF and ALL-FRAMES specify the set of windows to consider. 2216optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2215 2217consider.
2216MINIBUF t means consider the minibuffer window even if the 2218
2217minibuffer is not active. MINIBUF nil or omitted means consider 2219MINIBUF nil or omitted means consider the minibuffer window only if the
2218the minibuffer window only if the minibuffer is active. Any 2220minibuffer is active. MINIBUF t means consider the minibuffer window
2219other value means do not consider the minibuffer window even if 2221even if the minibuffer is not active. Any other value means do not
2220the minibuffer is active. 2222consider the minibuffer window even if the minibuffer is active.
2221 2223
2222Several frames may share a single minibuffer; if the minibuffer 2224ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2223is active, all windows on all frames that share that minibuffer 2225plus the minibuffer window if specified by the MINIBUF argument. If the
2224are considered too. Therefore, if you are using a separate 2226minibuffer counts, consider all windows on all frames that share that
2225minibuffer frame and the minibuffer is active and MINIBUF says it 2227minibuffer too. The following non-nil values of ALL-FRAMES have special
2226counts, `next-window' considers the windows in the frame from 2228meanings:
2227which you entered the minibuffer, as well as the minibuffer 2229
2228window. 2230- t means consider all windows on all existing frames.
2231
2232- `visible' means consider all windows on all visible frames.
2233
2234- 0 (the number zero) means consider all windows on all visible and
2235 iconified frames.
2236
2237- A frame means consider all windows on that frame only.
2229 2238
2230ALL-FRAMES nil or omitted means consider all windows on WINDOW's
2231 frame, plus the minibuffer window if specified by the MINIBUF
2232 argument, see above. If the minibuffer counts, consider all
2233 windows on all frames that share that minibuffer too.
2234ALL-FRAMES t means consider all windows on all existing frames.
2235ALL-FRAMES `visible' means consider all windows on all visible
2236 frames on the current terminal.
2237ALL-FRAMES 0 means consider all windows on all visible and
2238 iconified frames on the current terminal.
2239ALL-FRAMES a frame means consider all windows on that frame only.
2240Anything else means consider all windows on WINDOW's frame and no 2239Anything else means consider all windows on WINDOW's frame and no
2241 others. 2240others.
2242 2241
2243If you use consistent values for MINIBUF and ALL-FRAMES, you can use 2242If you use consistent values for MINIBUF and ALL-FRAMES, you can use
2244`next-window' to iterate through the entire cycle of acceptable 2243`next-window' to iterate through the entire cycle of acceptable
@@ -2252,9 +2251,32 @@ windows, eventually ending up back at the window you started with.
2252 2251
2253DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0, 2252DEFUN ("previous-window", Fprevious_window, Sprevious_window, 0, 3, 0,
2254 doc: /* Return window preceding WINDOW in cyclic ordering of windows. 2253 doc: /* Return window preceding WINDOW in cyclic ordering of windows.
2255WINDOW defaults to the selected window. The optional arguments 2254WINDOW must be a live window and defaults to the selected one. The
2256MINIBUF and ALL-FRAMES specify the set of windows to consider. 2255optional arguments MINIBUF and ALL-FRAMES specify the set of windows to
2257For the precise meaning of these arguments see `next-window'. 2256consider.
2257
2258MINIBUF nil or omitted means consider the minibuffer window only if the
2259minibuffer is active. MINIBUF t means consider the minibuffer window
2260even if the minibuffer is not active. Any other value means do not
2261consider the minibuffer window even if the minibuffer is active.
2262
2263ALL-FRAMES nil or omitted means consider all windows on WINDOW's frame,
2264plus the minibuffer window if specified by the MINIBUF argument. If the
2265minibuffer counts, consider all windows on all frames that share that
2266minibuffer too. The following non-nil values of ALL-FRAMES have special
2267meanings:
2268
2269- t means consider all windows on all existing frames.
2270
2271- `visible' means consider all windows on all visible frames.
2272
2273- 0 (the number zero) means consider all windows on all visible and
2274 iconified frames.
2275
2276- A frame means consider all windows on that frame only.
2277
2278Anything else means consider all windows on WINDOW's frame and no
2279others.
2258 2280
2259If you use consistent values for MINIBUF and ALL-FRAMES, you can 2281If you use consistent values for MINIBUF and ALL-FRAMES, you can
2260use `previous-window' to iterate through the entire cycle of 2282use `previous-window' to iterate through the entire cycle of
@@ -2267,37 +2289,6 @@ reverse order. */)
2267} 2289}
2268 2290
2269 2291
2270DEFUN ("other-window", Fother_window, Sother_window, 1, 2, "p",
2271 doc: /* Select another window in cyclic ordering of windows.
2272COUNT specifies the number of windows to skip, starting with the
2273selected window, before making the selection. If COUNT is
2274positive, skip COUNT windows forwards. If COUNT is negative,
2275skip -COUNT windows backwards. COUNT zero means do not skip any
2276window, so select the selected window. In an interactive call,
2277COUNT is the numeric prefix argument. Return nil.
2278
2279This function uses `next-window' for finding the window to select.
2280The argument ALL-FRAMES has the same meaning as in `next-window',
2281but the MINIBUF argument of `next-window' is always effectively
2282nil. */)
2283 (Lisp_Object count, Lisp_Object all_frames)
2284{
2285 Lisp_Object window;
2286 int i;
2287
2288 CHECK_NUMBER (count);
2289 window = selected_window;
2290
2291 for (i = XINT (count); i > 0; --i)
2292 window = Fnext_window (window, Qnil, all_frames);
2293 for (; i < 0; ++i)
2294 window = Fprevious_window (window, Qnil, all_frames);
2295
2296 Fselect_window (window, Qnil);
2297 return Qnil;
2298}
2299
2300
2301/* Return a list of windows in cyclic ordering. Arguments are like 2292/* Return a list of windows in cyclic ordering. Arguments are like
2302 for `next-window'. */ 2293 for `next-window'. */
2303 2294
@@ -2397,10 +2388,9 @@ be listed first but no error is signalled. */)
2397enum window_loop 2388enum window_loop
2398{ 2389{
2399 WINDOW_LOOP_UNUSED, 2390 WINDOW_LOOP_UNUSED,
2400 GET_BUFFER_WINDOW, /* Arg is buffer */ 2391 GET_BUFFER_WINDOW, /* Arg is buffer */
2401 DELETE_BUFFER_WINDOWS, /* Arg is buffer */ 2392 REPLACE_BUFFER_IN_WINDOWS_SAFELY, /* Arg is buffer */
2402 UNSHOW_BUFFER, /* Arg is buffer */ 2393 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2403 REDISPLAY_BUFFER_WINDOWS, /* Arg is buffer */
2404 CHECK_ALL_WINDOWS 2394 CHECK_ALL_WINDOWS
2405}; 2395};
2406 2396
@@ -2408,6 +2398,7 @@ static Lisp_Object
2408window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames) 2398window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frames)
2409{ 2399{
2410 Lisp_Object window, windows, best_window, frame_arg; 2400 Lisp_Object window, windows, best_window, frame_arg;
2401 int frame_best_window_flag = 0;
2411 struct frame *f; 2402 struct frame *f;
2412 struct gcpro gcpro1; 2403 struct gcpro gcpro1;
2413 2404
@@ -2457,110 +2448,51 @@ window_loop (enum window_loop type, Lisp_Object obj, int mini, Lisp_Object frame
2457 is visible, since Fwindow_list skips non-visible frames if 2448 is visible, since Fwindow_list skips non-visible frames if
2458 that is desired, under the control of frame_arg. */ 2449 that is desired, under the control of frame_arg. */
2459 if (!MINI_WINDOW_P (w) 2450 if (!MINI_WINDOW_P (w)
2460 /* For UNSHOW_BUFFER, we must always consider all windows. */ 2451 /* For REPLACE_BUFFER_IN_WINDOWS_SAFELY, we must always
2461 || type == UNSHOW_BUFFER 2452 consider all windows. */
2453 || type == REPLACE_BUFFER_IN_WINDOWS_SAFELY
2462 || (mini && minibuf_level > 0)) 2454 || (mini && minibuf_level > 0))
2463 switch (type) 2455 switch (type)
2464 { 2456 {
2465 case GET_BUFFER_WINDOW: 2457 case GET_BUFFER_WINDOW:
2466 if (EQ (w->buffer, obj) 2458 if (EQ (w->buffer, obj)
2467 /* Don't find any minibuffer window 2459 /* Don't find any minibuffer window except the one that
2468 except the one that is currently in use. */ 2460 is currently in use. */
2469 && (MINI_WINDOW_P (w) 2461 && (MINI_WINDOW_P (w) ? EQ (window, minibuf_window) : 1))
2470 ? EQ (window, minibuf_window)
2471 : 1))
2472 { 2462 {
2473 if (NILP (best_window)) 2463 if (EQ (window, selected_window))
2474 best_window = window; 2464 /* Preferably return the selected window. */
2475 else if (EQ (window, selected_window))
2476 /* Prefer to return selected-window. */
2477 RETURN_UNGCPRO (window); 2465 RETURN_UNGCPRO (window);
2478 else if (EQ (Fwindow_frame (window), selected_frame)) 2466 else if (EQ (XWINDOW (window)->frame, selected_frame)
2479 /* Prefer windows on the current frame. */ 2467 && !frame_best_window_flag)
2480 best_window = window; 2468 /* Prefer windows on the current frame (but don't
2481 } 2469 choose another one if we have one already). */
2482 break;
2483
2484 case DELETE_BUFFER_WINDOWS:
2485 if (EQ (w->buffer, obj))
2486 {
2487 struct frame *fr = XFRAME (WINDOW_FRAME (w));
2488
2489 /* If this window is dedicated, and in a frame of its own,
2490 kill the frame. */
2491 if (EQ (window, FRAME_ROOT_WINDOW (fr))
2492 && !NILP (w->dedicated)
2493 && other_visible_frames (fr))
2494 {
2495 /* Skip the other windows on this frame.
2496 There might be one, the minibuffer! */
2497 while (CONSP (XCDR (windows))
2498 && EQ (XWINDOW (XCAR (windows))->frame,
2499 XWINDOW (XCAR (XCDR (windows)))->frame))
2500 windows = XCDR (windows);
2501
2502 /* Now we can safely delete the frame. */
2503 delete_frame (w->frame, Qnil);
2504 }
2505 else if (NILP (w->parent))
2506 { 2470 {
2507 /* If we're deleting the buffer displayed in the 2471 best_window = window;
2508 only window on the frame, find a new buffer to 2472 frame_best_window_flag = 1;
2509 display there. */
2510 Lisp_Object buffer;
2511 buffer = Fother_buffer (obj, Qnil, w->frame);
2512 /* Reset dedicated state of window. */
2513 w->dedicated = Qnil;
2514 Fset_window_buffer (window, buffer, Qnil);
2515 if (EQ (window, selected_window))
2516 Fset_buffer (w->buffer);
2517 } 2473 }
2518 else 2474 else if (NILP (best_window))
2519 call1 (Qdelete_window, window); 2475 best_window = window;
2520 } 2476 }
2521 break; 2477 break;
2522 2478
2523 case UNSHOW_BUFFER: 2479 case REPLACE_BUFFER_IN_WINDOWS_SAFELY:
2480 /* We could simply check whether the buffer shown by window
2481 is live, and show another buffer in case it isn't. */
2524 if (EQ (w->buffer, obj)) 2482 if (EQ (w->buffer, obj))
2525 { 2483 {
2526 Lisp_Object buffer; 2484 /* Undedicate WINDOW. */
2527 struct frame *fr = XFRAME (w->frame); 2485 w->dedicated = Qnil;
2528 2486 /* Make WINDOW show the buffer returned by
2529 /* Find another buffer to show in this window. */ 2487 other_buffer_safely, don't run any hooks. */
2530 buffer = Fother_buffer (obj, Qnil, w->frame); 2488 set_window_buffer
2531 2489 (window, other_buffer_safely (w->buffer), 0, 0);
2532 /* If this window is dedicated, and in a frame of its own, 2490 /* If WINDOW is the selected window, make its buffer
2533 kill the frame. */ 2491 current. But do so only if the window shows the
2534 if (EQ (window, FRAME_ROOT_WINDOW (fr)) 2492 current buffer (Bug#6454). */
2535 && !NILP (w->dedicated) 2493 if (EQ (window, selected_window)
2536 && other_visible_frames (fr)) 2494 && XBUFFER (w->buffer) == current_buffer)
2537 { 2495 Fset_buffer (w->buffer);
2538 /* Skip the other windows on this frame.
2539 There might be one, the minibuffer! */
2540 while (CONSP (XCDR (windows))
2541 && EQ (XWINDOW (XCAR (windows))->frame,
2542 XWINDOW (XCAR (XCDR (windows)))->frame))
2543 windows = XCDR (windows);
2544
2545 /* Now we can safely delete the frame. */
2546 delete_frame (w->frame, Qnil);
2547 }
2548 else if (!NILP (w->dedicated) && !NILP (w->parent))
2549 {
2550 Lisp_Object window_to_delete;
2551 XSETWINDOW (window_to_delete, w);
2552 /* If this window is dedicated and not the only window
2553 in its frame, then kill it. */
2554 call1 (Qdelete_window, window_to_delete);
2555 }
2556 else
2557 {
2558 /* Otherwise show a different buffer in the window. */
2559 w->dedicated = Qnil;
2560 Fset_window_buffer (window, buffer, Qnil);
2561 if (EQ (window, selected_window))
2562 Fset_buffer (w->buffer);
2563 }
2564 } 2496 }
2565 break; 2497 break;
2566 2498
@@ -2875,85 +2807,26 @@ window-start value is reasonable when this function is called. */)
2875} 2807}
2876 2808
2877 2809
2878DEFUN ("delete-windows-on", Fdelete_windows_on, Sdelete_windows_on, 2810void
2879 0, 2, "bDelete windows on (buffer): ", 2811replace_buffer_in_windows (Lisp_Object buffer)
2880 doc: /* Delete all windows showing BUFFER-OR-NAME.
2881BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2882defaults to the current buffer.
2883
2884Optional second argument FRAME controls which frames are affected.
2885If optional argument FRAME is `visible', search all visible frames.
2886If FRAME is 0, search all visible and iconified frames.
2887If FRAME is nil, search all frames.
2888If FRAME is t, search only the selected frame.
2889If FRAME is a frame, search only that frame.
2890When a window showing BUFFER-OR-NAME is dedicated and the only window of
2891its frame, that frame is deleted when there are other frames left. */)
2892 (Lisp_Object buffer_or_name, Lisp_Object frame)
2893{ 2812{
2894 Lisp_Object buffer; 2813 call1 (Qreplace_buffer_in_windows, buffer);
2895
2896 /* FRAME uses t and nil to mean the opposite of what window_loop
2897 expects. */
2898 if (NILP (frame))
2899 frame = Qt;
2900 else if (EQ (frame, Qt))
2901 frame = Qnil;
2902
2903 if (NILP (buffer_or_name))
2904 buffer = Fcurrent_buffer ();
2905 else
2906 {
2907 buffer = Fget_buffer (buffer_or_name);
2908 CHECK_BUFFER (buffer);
2909 }
2910
2911 window_loop (DELETE_BUFFER_WINDOWS, buffer, 0, frame);
2912
2913 return Qnil;
2914} 2814}
2915 2815
2916DEFUN ("replace-buffer-in-windows", Freplace_buffer_in_windows,
2917 Sreplace_buffer_in_windows,
2918 0, 1, "bReplace buffer in windows: ",
2919 doc: /* Replace BUFFER-OR-NAME with some other buffer in all windows showing it.
2920BUFFER-OR-NAME may be a buffer or the name of an existing buffer and
2921defaults to the current buffer.
2922
2923When a window showing BUFFER-OR-NAME is dedicated that window is
2924deleted. If that window is the only window on its frame, that frame is
2925deleted too when there are other frames left. If there are no other
2926frames left, some other buffer is displayed in that window. */)
2927 (Lisp_Object buffer_or_name)
2928{
2929 Lisp_Object buffer;
2930
2931 if (NILP (buffer_or_name))
2932 buffer = Fcurrent_buffer ();
2933 else
2934 {
2935 buffer = Fget_buffer (buffer_or_name);
2936 CHECK_BUFFER (buffer);
2937 }
2938
2939 window_loop (UNSHOW_BUFFER, buffer, 0, Qt);
2940
2941 return Qnil;
2942}
2943 2816
2944/* Replace BUFFER with some other buffer in all windows 2817/* Safely replace BUFFER with some other buffer in all windows of all
2945 of all frames, even those on other keyboards. */ 2818 frames, even those on other keyboards. */
2946 2819
2947void 2820void
2948replace_buffer_in_all_windows (Lisp_Object buffer) 2821replace_buffer_in_windows_safely (Lisp_Object buffer)
2949{ 2822{
2950 Lisp_Object tail, frame; 2823 Lisp_Object tail, frame;
2951 2824
2952 /* A single call to window_loop won't do the job 2825 /* A single call to window_loop won't do the job because it only
2953 because it only considers frames on the current keyboard. 2826 considers frames on the current keyboard. So loop manually over
2954 So loop manually over frames, and handle each one. */ 2827 frames, and handle each one. */
2955 FOR_EACH_FRAME (tail, frame) 2828 FOR_EACH_FRAME (tail, frame)
2956 window_loop (UNSHOW_BUFFER, buffer, 1, frame); 2829 window_loop (REPLACE_BUFFER_IN_WINDOWS_SAFELY, buffer, 1, frame);
2957} 2830}
2958 2831
2959/* If *ROWS or *COLS are too small a size for FRAME, set them to the 2832/* If *ROWS or *COLS are too small a size for FRAME, set them to the
@@ -3014,8 +2887,6 @@ adjust_window_margins (struct window *w)
3014 return 1; 2887 return 1;
3015} 2888}
3016 2889
3017int window_select_count;
3018
3019static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object); 2890static Lisp_Object Fset_window_margins (Lisp_Object, Lisp_Object, Lisp_Object);
3020static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object, 2891static Lisp_Object Fset_window_fringes (Lisp_Object, Lisp_Object, Lisp_Object,
3021 Lisp_Object); 2892 Lisp_Object);
@@ -3023,6 +2894,8 @@ static Lisp_Object Fset_window_scroll_bars (Lisp_Object, Lisp_Object,
3023 Lisp_Object, Lisp_Object); 2894 Lisp_Object, Lisp_Object);
3024static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object); 2895static Lisp_Object Fset_window_vscroll (Lisp_Object, Lisp_Object, Lisp_Object);
3025 2896
2897/* The following three routines are needed for running a window's
2898 configuration change hook. */
3026static void 2899static void
3027run_funs (Lisp_Object funs) 2900run_funs (Lisp_Object funs)
3028{ 2901{
@@ -3031,8 +2904,19 @@ run_funs (Lisp_Object funs)
3031 call0 (XCAR (funs)); 2904 call0 (XCAR (funs));
3032} 2905}
3033 2906
3034static Lisp_Object select_window_norecord (Lisp_Object window); 2907static Lisp_Object
3035static Lisp_Object select_frame_norecord (Lisp_Object frame); 2908select_window_norecord (Lisp_Object window)
2909{
2910 return WINDOW_LIVE_P (window)
2911 ? Fselect_window (window, Qt) : selected_window;
2912}
2913
2914static Lisp_Object
2915select_frame_norecord (Lisp_Object frame)
2916{
2917 return FRAME_LIVE_P (XFRAME (frame))
2918 ? Fselect_frame (frame, Qt) : selected_frame;
2919}
3036 2920
3037void 2921void
3038run_window_configuration_change_hook (struct frame *f) 2922run_window_configuration_change_hook (struct frame *f)
@@ -3209,11 +3093,13 @@ WINDOW can be any window and defaults to the selected one. */)
3209 3093
3210DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0, 3094DEFUN ("set-window-buffer", Fset_window_buffer, Sset_window_buffer, 2, 3, 0,
3211 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents. 3095 doc: /* Make WINDOW display BUFFER-OR-NAME as its contents.
3212WINDOW defaults to the selected window. BUFFER-OR-NAME must be a buffer 3096WINDOW has to be a live window and defaults to the selected one.
3213or the name of an existing buffer. Optional third argument KEEP-MARGINS 3097BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
3214non-nil means that WINDOW's current display margins, fringe widths, and 3098
3215scroll bar settings are preserved; the default is to reset these from 3099Optional third argument KEEP-MARGINS non-nil means that WINDOW's current
3216the local settings for BUFFER-OR-NAME or the frame defaults. Return nil. 3100display margins, fringe widths, and scroll bar settings are preserved;
3101the default is to reset these from the local settings for BUFFER-OR-NAME
3102or the frame defaults. Return nil.
3217 3103
3218This function throws an error when WINDOW is strongly dedicated to its 3104This function throws an error when WINDOW is strongly dedicated to its
3219buffer (that is `window-dedicated-p' returns t for WINDOW) and does not 3105buffer (that is `window-dedicated-p' returns t for WINDOW) and does not
@@ -3238,32 +3124,26 @@ This function runs `window-scroll-functions' before running
3238 else if (!EQ (tem, Qt)) 3124 else if (!EQ (tem, Qt))
3239 /* w->buffer is t when the window is first being set up. */ 3125 /* w->buffer is t when the window is first being set up. */
3240 { 3126 {
3241 if (EQ (tem, buffer)) 3127 if (!EQ (tem, buffer))
3242 return Qnil; 3128 {
3243 else if (EQ (w->dedicated, Qt)) 3129 if (EQ (w->dedicated, Qt))
3244 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name))); 3130 /* WINDOW is strongly dedicated to its buffer, signal an
3245 else 3131 error. */
3246 w->dedicated = Qnil; 3132 error ("Window is dedicated to `%s'", SDATA (BVAR (XBUFFER (tem), name)));
3133 else
3134 /* WINDOW is weakly dedicated to its buffer, reset
3135 dedicatedness. */
3136 w->dedicated = Qnil;
3137
3138 call1 (Qrecord_window_buffer, window);
3139 }
3247 3140
3248 unshow_buffer (w); 3141 unshow_buffer (w);
3249 } 3142 }
3250 3143
3251 set_window_buffer (window, buffer, 1, !NILP (keep_margins)); 3144 set_window_buffer (window, buffer, 1, !NILP (keep_margins));
3252 return Qnil;
3253}
3254 3145
3255static Lisp_Object 3146 return Qnil;
3256select_window_norecord (Lisp_Object window)
3257{
3258 return WINDOW_LIVE_P (window)
3259 ? Fselect_window (window, Qt) : selected_window;
3260}
3261
3262static Lisp_Object
3263select_frame_norecord (Lisp_Object frame)
3264{
3265 return FRAME_LIVE_P (XFRAME (frame))
3266 ? Fselect_frame (frame, Qt) : selected_frame;
3267} 3147}
3268 3148
3269static Lisp_Object 3149static Lisp_Object
@@ -3799,7 +3679,7 @@ resize_frame_windows (struct frame *f, int size, int horflag)
3799DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0, 3679DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
3800 doc: /* Split window OLD. 3680 doc: /* Split window OLD.
3801Second argument TOTAL-SIZE specifies the number of lines or columns of the 3681Second argument TOTAL-SIZE specifies the number of lines or columns of the
3802new window. In any case TOTAL-SIZE must be a positive integer 3682new window. In any case TOTAL-SIZE must be a positive integer.
3803 3683
3804Third argument SIDE nil (or `below') specifies that the new window shall 3684Third argument SIDE nil (or `below') specifies that the new window shall
3805be located below WINDOW. SIDE `above' means the new window shall be 3685be located below WINDOW. SIDE `above' means the new window shall be
@@ -4280,7 +4160,6 @@ DEFUN ("resize-mini-window-internal", Fresize_mini_window_internal, Sresize_mini
4280 else error ("Failed to resize minibuffer window"); 4160 else error ("Failed to resize minibuffer window");
4281} 4161}
4282 4162
4283
4284/* Mark window cursors off for all windows in the window tree rooted 4163/* Mark window cursors off for all windows in the window tree rooted
4285 at W by setting their phys_cursor_on_p flag to zero. Called from 4164 at W by setting their phys_cursor_on_p flag to zero. Called from
4286 xterm.c, e.g. when a frame is cleared and thereby all cursors on 4165 xterm.c, e.g. when a frame is cleared and thereby all cursors on
@@ -5337,7 +5216,6 @@ and redisplay normally--don't erase and redraw the frame. */)
5337 return Qnil; 5216 return Qnil;
5338} 5217}
5339 5218
5340
5341DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height, 5219DEFUN ("window-text-height", Fwindow_text_height, Swindow_text_height,
5342 0, 1, 0, 5220 0, 1, 0,
5343 doc: /* Return the height in lines of the text display area of WINDOW. 5221 doc: /* Return the height in lines of the text display area of WINDOW.
@@ -6865,10 +6743,7 @@ function `window-nest' and altered by the function `set-window-nest'. */);
6865 defsubr (&Sset_window_display_table); 6743 defsubr (&Sset_window_display_table);
6866 defsubr (&Snext_window); 6744 defsubr (&Snext_window);
6867 defsubr (&Sprevious_window); 6745 defsubr (&Sprevious_window);
6868 defsubr (&Sother_window);
6869 defsubr (&Sget_buffer_window); 6746 defsubr (&Sget_buffer_window);
6870 defsubr (&Sdelete_windows_on);
6871 defsubr (&Sreplace_buffer_in_windows);
6872 defsubr (&Sdelete_other_windows_internal); 6747 defsubr (&Sdelete_other_windows_internal);
6873 defsubr (&Sdelete_window_internal); 6748 defsubr (&Sdelete_window_internal);
6874 defsubr (&Sresize_mini_window_internal); 6749 defsubr (&Sresize_mini_window_internal);
@@ -6917,7 +6792,6 @@ function `window-nest' and altered by the function `set-window-nest'. */);
6917void 6792void
6918keys_of_window (void) 6793keys_of_window (void)
6919{ 6794{
6920 initial_define_key (control_x_map, 'o', "other-window");
6921 initial_define_key (control_x_map, '<', "scroll-left"); 6795 initial_define_key (control_x_map, '<', "scroll-left");
6922 initial_define_key (control_x_map, '>', "scroll-right"); 6796 initial_define_key (control_x_map, '>', "scroll-right");
6923 6797
diff --git a/src/window.h b/src/window.h
index 1ebc99055a5..52fecbf2e56 100644
--- a/src/window.h
+++ b/src/window.h
@@ -827,6 +827,7 @@ extern Lisp_Object make_window (void);
827extern Lisp_Object window_from_coordinates (struct frame *, int, int, 827extern Lisp_Object window_from_coordinates (struct frame *, int, int,
828 enum window_part *, int); 828 enum window_part *, int);
829EXFUN (Fwindow_dedicated_p, 1); 829EXFUN (Fwindow_dedicated_p, 1);
830extern void resize_frame_windows (struct frame *, int, int);
830extern void delete_all_subwindows (Lisp_Object); 831extern void delete_all_subwindows (Lisp_Object);
831extern void freeze_window_starts (struct frame *, int); 832extern void freeze_window_starts (struct frame *, int);
832extern void grow_mini_window (struct window *, int); 833extern void grow_mini_window (struct window *, int);
@@ -902,7 +903,6 @@ extern Lisp_Object Qwindowp, Qwindow_live_p;
902extern Lisp_Object Vwindow_list; 903extern Lisp_Object Vwindow_list;
903 904
904EXFUN (Fwindow_buffer, 1); 905EXFUN (Fwindow_buffer, 1);
905EXFUN (Fwindow_frame, 1);
906EXFUN (Fget_buffer_window, 2); 906EXFUN (Fget_buffer_window, 2);
907EXFUN (Fwindow_minibuffer_p, 1); 907EXFUN (Fwindow_minibuffer_p, 1);
908EXFUN (Fselected_window, 0); 908EXFUN (Fselected_window, 0);
@@ -918,12 +918,10 @@ extern int window_internal_height (struct window *);
918extern int window_body_cols (struct window *w); 918extern int window_body_cols (struct window *w);
919EXFUN (Frecenter, 1); 919EXFUN (Frecenter, 1);
920extern void temp_output_buffer_show (Lisp_Object); 920extern void temp_output_buffer_show (Lisp_Object);
921extern void replace_buffer_in_all_windows (Lisp_Object); 921extern void replace_buffer_in_windows_safely (Lisp_Object);
922extern void init_window_once (void); 922extern void init_window_once (void);
923extern void init_window (void); 923extern void init_window (void);
924extern void syms_of_window (void); 924extern void syms_of_window (void);
925extern void keys_of_window (void); 925extern void keys_of_window (void);
926extern void resize_frame_windows (struct frame *, int, int);
927
928 926
929#endif /* not WINDOW_H_INCLUDED */ 927#endif /* not WINDOW_H_INCLUDED */