diff options
| author | Paul Eggert | 2011-06-13 01:00:15 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-06-13 01:00:15 -0700 |
| commit | 01103c441a5c97c734c087fa074a941082fd0adb (patch) | |
| tree | 697132e71abee8762913d4c58015945439cd2c3c /src/buffer.c | |
| parent | 5efd304be978e2c0b3b1ac0c39b303b8d094ab66 (diff) | |
| parent | 873e858a931f3af4b318473e052fb7acd35f7b53 (diff) | |
| download | emacs-01103c441a5c97c734c087fa074a941082fd0adb.tar.gz emacs-01103c441a5c97c734c087fa074a941082fd0adb.zip | |
Merge from trunk.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 452 |
1 files changed, 195 insertions, 257 deletions
diff --git a/src/buffer.c b/src/buffer.c index 0c4cdb544a5..d7adf63c98b 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -131,12 +131,14 @@ static Lisp_Object Qprotected_field; | |||
| 131 | static Lisp_Object QSFundamental; /* A string "Fundamental" */ | 131 | static Lisp_Object QSFundamental; /* A string "Fundamental" */ |
| 132 | 132 | ||
| 133 | static Lisp_Object Qkill_buffer_hook; | 133 | static Lisp_Object Qkill_buffer_hook; |
| 134 | static Lisp_Object Qbuffer_list_update_hook; | ||
| 134 | 135 | ||
| 135 | static Lisp_Object Qget_file_buffer; | 136 | static Lisp_Object Qget_file_buffer; |
| 136 | 137 | ||
| 137 | static Lisp_Object Qoverlayp; | 138 | static Lisp_Object Qoverlayp; |
| 138 | 139 | ||
| 139 | Lisp_Object Qpriority, Qbefore_string, Qafter_string; | 140 | Lisp_Object Qpriority, Qbefore_string, Qafter_string; |
| 141 | |||
| 140 | static Lisp_Object Qevaporate; | 142 | static Lisp_Object Qevaporate; |
| 141 | 143 | ||
| 142 | Lisp_Object Qmodification_hooks; | 144 | Lisp_Object Qmodification_hooks; |
| @@ -171,9 +173,9 @@ Value is nil if OBJECT is not a buffer or if it has been killed. */) | |||
| 171 | 173 | ||
| 172 | DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0, | 174 | DEFUN ("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. |
| 174 | If the optional arg FRAME is a frame, we return the buffer list | 176 | If the optional arg FRAME is a frame, we return the buffer list in the |
| 175 | in the proper order for that frame: the buffers in FRAME's `buffer-list' | 177 | proper order for that frame: the buffers show in FRAME come first, |
| 176 | frame parameter come first, followed by the rest of the buffers. */) | 178 | followed 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 | ||
| 1269 | DEFUN ("other-buffer", Fother_buffer, Sother_buffer, 0, 3, 0, | 1283 | DEFUN ("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. |
| 1271 | Buffers not visible in windows are preferred to visible buffers, | 1285 | Buffers not visible in windows are preferred to visible buffers, unless |
| 1272 | unless optional second argument VISIBLE-OK is non-nil. | 1286 | optional second argument VISIBLE-OK is non-nil. Ignore the argument |
| 1273 | If the optional third argument FRAME is non-nil, use that frame's | 1287 | BUFFER unless it denotes a live buffer. If the optional third argument |
| 1274 | buffer list instead of the selected frame's buffer list. | 1288 | FRAME is non-nil, use that frame's buffer list instead of the selected |
| 1275 | If no other buffer exists, the buffer `*scratch*' is returned. | 1289 | frame's buffer list. |
| 1276 | If BUFFER is omitted or nil, some interesting buffer is returned. */) | 1290 | |
| 1291 | The buffer is found by scanning the selected or specified frame's buffer | ||
| 1292 | list first, followed by the list of all buffers. If no other buffer | ||
| 1293 | exists, 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)) | 1364 | Lisp_Object |
| 1365 | other_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,102 @@ 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 | ||
| 1600 | void | 1664 | void |
| 1601 | record_buffer (Lisp_Object buf) | 1665 | record_buffer (Lisp_Object buffer) |
| 1602 | { | 1666 | { |
| 1603 | register Lisp_Object list, prev; | 1667 | Lisp_Object aelt, aelt_cons, tem; |
| 1604 | Lisp_Object frame; | 1668 | register struct frame *f = XFRAME (selected_frame); |
| 1605 | frame = selected_frame; | ||
| 1606 | 1669 | ||
| 1607 | prev = Qnil; | 1670 | 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 | 1671 | ||
| 1615 | /* Effectively do Vbuffer_alist = Fdelq (list, Vbuffer_alist); | 1672 | /* Update Vbuffer_alist (we know that it has an entry for BUFFER). |
| 1616 | we cannot use Fdelq itself here because it allows quitting. */ | 1673 | Don't allow quitting since this might leave the buffer list in an |
| 1674 | inconsistent state. */ | ||
| 1675 | tem = Vinhibit_quit; | ||
| 1676 | Vinhibit_quit = Qt; | ||
| 1677 | aelt = Frassq (buffer, Vbuffer_alist); | ||
| 1678 | aelt_cons = Fmemq (aelt, Vbuffer_alist); | ||
| 1679 | Vbuffer_alist = Fdelq (aelt, Vbuffer_alist); | ||
| 1680 | XSETCDR (aelt_cons, Vbuffer_alist); | ||
| 1681 | Vbuffer_alist = aelt_cons; | ||
| 1682 | Vinhibit_quit = tem; | ||
| 1617 | 1683 | ||
| 1618 | if (NILP (prev)) | 1684 | /* Update buffer list of selected frame. */ |
| 1619 | Vbuffer_alist = XCDR (Vbuffer_alist); | 1685 | f->buffer_list = Fcons (buffer, Fdelq (buffer, f->buffer_list)); |
| 1620 | else | 1686 | f->buried_buffer_list = Fdelq (buffer, f->buried_buffer_list); |
| 1621 | XSETCDR (prev, XCDR (XCDR (prev))); | ||
| 1622 | 1687 | ||
| 1623 | XSETCDR (list, Vbuffer_alist); | 1688 | /* Run buffer-list-update-hook. */ |
| 1624 | Vbuffer_alist = list; | 1689 | if (!NILP (Vrun_hooks)) |
| 1690 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 1691 | } | ||
| 1625 | 1692 | ||
| 1626 | /* Effectively do a delq on buried_buffer_list. */ | 1693 | DEFUN ("record-buffer", Frecord_buffer, Srecord_buffer, 1, 1, 0, |
| 1694 | doc: /* Move BUFFER to the front of the buffer list. | ||
| 1695 | Return BUFFER. */) | ||
| 1696 | (Lisp_Object buffer) | ||
| 1697 | { | ||
| 1698 | CHECK_BUFFER (buffer); | ||
| 1627 | 1699 | ||
| 1628 | prev = Qnil; | 1700 | 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 | 1701 | ||
| 1643 | /* Now move this buffer to the front of frame_buffer_list also. */ | 1702 | return buffer; |
| 1703 | } | ||
| 1644 | 1704 | ||
| 1645 | prev = Qnil; | 1705 | /* Move BUFFER to the end of the buffer (a)lists. Do nothing if the |
| 1646 | for (list = frame_buffer_list (frame); CONSP (list); | 1706 | buffer is killed. For the selected frame's buffer list this moves |
| 1647 | list = XCDR (list)) | 1707 | BUFFER to its end even if it was never shown in that frame. If |
| 1648 | { | 1708 | this happens we have a feature, hence `unrecord-buffer' should be |
| 1649 | if (EQ (XCAR (list), buf)) | 1709 | called only when BUFFER was shown in the selected frame. */ |
| 1650 | break; | ||
| 1651 | prev = list; | ||
| 1652 | } | ||
| 1653 | 1710 | ||
| 1654 | /* Effectively do delq. */ | 1711 | DEFUN ("unrecord-buffer", Funrecord_buffer, Sunrecord_buffer, 1, 1, 0, |
| 1712 | doc: /* Move BUFFER to the end of the buffer list. | ||
| 1713 | Return BUFFER. */) | ||
| 1714 | (Lisp_Object buffer) | ||
| 1715 | { | ||
| 1716 | Lisp_Object aelt, aelt_cons, tem; | ||
| 1717 | register struct frame *f = XFRAME (selected_frame); | ||
| 1655 | 1718 | ||
| 1656 | if (CONSP (list)) | 1719 | 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 | 1720 | ||
| 1664 | XSETCDR (list, frame_buffer_list (frame)); | 1721 | /* Update Vbuffer_alist (we know that it has an entry for BUFFER). |
| 1665 | set_frame_buffer_list (frame, list); | 1722 | Don't allow quitting since this might leave the buffer list in an |
| 1666 | } | 1723 | inconsistent state. */ |
| 1667 | else | 1724 | tem = Vinhibit_quit; |
| 1668 | set_frame_buffer_list (frame, Fcons (buf, frame_buffer_list (frame))); | 1725 | Vinhibit_quit = Qt; |
| 1726 | aelt = Frassq (buffer, Vbuffer_alist); | ||
| 1727 | aelt_cons = Fmemq (aelt, Vbuffer_alist); | ||
| 1728 | Vbuffer_alist = Fdelq (aelt, Vbuffer_alist); | ||
| 1729 | XSETCDR (aelt_cons, Qnil); | ||
| 1730 | Vbuffer_alist = nconc2 (Vbuffer_alist, aelt_cons); | ||
| 1731 | Vinhibit_quit = tem; | ||
| 1732 | |||
| 1733 | /* Update buffer lists of selected frame. */ | ||
| 1734 | f->buffer_list = Fdelq (buffer, f->buffer_list); | ||
| 1735 | f->buried_buffer_list = Fcons (buffer, Fdelq (buffer, f->buried_buffer_list)); | ||
| 1736 | |||
| 1737 | /* Run buffer-list-update-hook. */ | ||
| 1738 | if (!NILP (Vrun_hooks)) | ||
| 1739 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | ||
| 1740 | |||
| 1741 | return buffer; | ||
| 1669 | } | 1742 | } |
| 1670 | 1743 | ||
| 1671 | DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0, | 1744 | DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0, |
| @@ -1708,86 +1781,6 @@ the current buffer's major mode. */) | |||
| 1708 | return unbind_to (count, Qnil); | 1781 | return unbind_to (count, Qnil); |
| 1709 | } | 1782 | } |
| 1710 | 1783 | ||
| 1711 | /* Switch to buffer BUFFER in the selected window. | ||
| 1712 | If NORECORD is non-nil, don't call record_buffer. */ | ||
| 1713 | |||
| 1714 | static Lisp_Object | ||
| 1715 | switch_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 | |||
| 1742 | DEFUN ("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. | ||
| 1745 | BUFFER-OR-NAME may be a buffer, a string \(a buffer name), or | ||
| 1746 | nil. Return the buffer switched to. | ||
| 1747 | |||
| 1748 | If BUFFER-OR-NAME is a string and does not identify an existing | ||
| 1749 | buffer, create a new buffer with that name. Interactively, if | ||
| 1750 | `confirm-nonexistent-file-or-buffer' is non-nil, request | ||
| 1751 | confirmation before creating a new buffer. If BUFFER-OR-NAME is | ||
| 1752 | nil, switch to buffer returned by `other-buffer'. | ||
| 1753 | |||
| 1754 | Optional second arg NORECORD non-nil means do not put this buffer | ||
| 1755 | at the front of the list of recently selected ones. This | ||
| 1756 | function returns the buffer it switched to as a Lisp object. | ||
| 1757 | |||
| 1758 | If the selected window is the minibuffer window or dedicated to | ||
| 1759 | its buffer, use `pop-to-buffer' for displaying the buffer. | ||
| 1760 | |||
| 1761 | WARNING: This is NOT the way to work on another buffer temporarily | ||
| 1762 | within a Lisp program! Use `set-buffer' instead. That avoids | ||
| 1763 | messing 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 | |||
| 1791 | DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, | 1784 | DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, |
| 1792 | doc: /* Return the current buffer as a Lisp object. */) | 1785 | doc: /* Return the current buffer as a Lisp object. */) |
| 1793 | (void) | 1786 | (void) |
| @@ -1937,70 +1930,6 @@ DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only, | |||
| 1937 | xsignal1 (Qbuffer_read_only, Fcurrent_buffer ()); | 1930 | xsignal1 (Qbuffer_read_only, Fcurrent_buffer ()); |
| 1938 | return Qnil; | 1931 | return Qnil; |
| 1939 | } | 1932 | } |
| 1940 | |||
| 1941 | extern Lisp_Object Qdelete_window; | ||
| 1942 | |||
| 1943 | DEFUN ("bury-buffer", Fbury_buffer, Sbury_buffer, 0, 1, "", | ||
| 1944 | doc: /* Put BUFFER-OR-NAME at the end of the list of all buffers. | ||
| 1945 | There it is the least likely candidate for `other-buffer' to return; | ||
| 1946 | thus, the least likely buffer for \\[switch-to-buffer] to select by | ||
| 1947 | default. | ||
| 1948 | |||
| 1949 | The argument may be a buffer name or an actual buffer object. If | ||
| 1950 | BUFFER-OR-NAME is nil or omitted, bury the current buffer and remove it | ||
| 1951 | from the selected window if it is displayed there. If the selected | ||
| 1952 | window is dedicated to its buffer, delete that window if there are other | ||
| 1953 | windows on the same frame. If the selected window is the only window on | ||
| 1954 | its 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 | 1933 | ||
| 2005 | DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*", | 1934 | DEFUN ("erase-buffer", Ferase_buffer, Serase_buffer, 0, 0, "*", |
| 2006 | doc: /* Delete the entire contents of the current buffer. | 1935 | doc: /* Delete the entire contents of the current buffer. |
| @@ -6101,6 +6030,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"); | 6030 | Qchange_major_mode_hook = intern_c_string ("change-major-mode-hook"); |
| 6102 | staticpro (&Qchange_major_mode_hook); | 6031 | staticpro (&Qchange_major_mode_hook); |
| 6103 | 6032 | ||
| 6033 | DEFVAR_LISP ("buffer-list-update-hook", Vbuffer_list_update_hook, | ||
| 6034 | doc: /* Hook run when the buffer list changes. | ||
| 6035 | Functions running this hook are `get-buffer-create', | ||
| 6036 | `make-indirect-buffer', `rename-buffer', `kill-buffer', | ||
| 6037 | `record-buffer' and `unrecord-buffer'. */); | ||
| 6038 | Vbuffer_list_update_hook = Qnil; | ||
| 6039 | Qbuffer_list_update_hook = intern_c_string ("buffer-list-update-hook"); | ||
| 6040 | staticpro (&Qbuffer_list_update_hook); | ||
| 6041 | |||
| 6104 | defsubr (&Sbuffer_live_p); | 6042 | defsubr (&Sbuffer_live_p); |
| 6105 | defsubr (&Sbuffer_list); | 6043 | defsubr (&Sbuffer_list); |
| 6106 | defsubr (&Sget_buffer); | 6044 | defsubr (&Sget_buffer); |
| @@ -6122,12 +6060,12 @@ The function `kill-all-local-variables' runs this before doing anything else. * | |||
| 6122 | defsubr (&Sother_buffer); | 6060 | defsubr (&Sother_buffer); |
| 6123 | defsubr (&Sbuffer_enable_undo); | 6061 | defsubr (&Sbuffer_enable_undo); |
| 6124 | defsubr (&Skill_buffer); | 6062 | defsubr (&Skill_buffer); |
| 6063 | defsubr (&Srecord_buffer); | ||
| 6064 | defsubr (&Sunrecord_buffer); | ||
| 6125 | defsubr (&Sset_buffer_major_mode); | 6065 | defsubr (&Sset_buffer_major_mode); |
| 6126 | defsubr (&Sswitch_to_buffer); | ||
| 6127 | defsubr (&Scurrent_buffer); | 6066 | defsubr (&Scurrent_buffer); |
| 6128 | defsubr (&Sset_buffer); | 6067 | defsubr (&Sset_buffer); |
| 6129 | defsubr (&Sbarf_if_buffer_read_only); | 6068 | defsubr (&Sbarf_if_buffer_read_only); |
| 6130 | defsubr (&Sbury_buffer); | ||
| 6131 | defsubr (&Serase_buffer); | 6069 | defsubr (&Serase_buffer); |
| 6132 | defsubr (&Sbuffer_swap_text); | 6070 | defsubr (&Sbuffer_swap_text); |
| 6133 | defsubr (&Sset_buffer_multibyte); | 6071 | defsubr (&Sset_buffer_multibyte); |