comparison src/buffer.c @ 2389:6048be0eedcd

(init_buffer_once, reset_buffer): Delete last vestige of fieldlist slot. (Fregion_fields): Finally deleted. (overlays_at, recenter_overlay_lists): New functions. (Fmake_overlay, Fdelete_overlay, Foverlay_get, Foverlay_put): Likewise. (Fmove_overlay, Foverlays_at, Fnext_overlay_change): Likewise. (Foverlay_lists, Foverlay_recenter): Likewise.
author Richard M. Stallman <rms@gnu.org>
date Sat, 27 Mar 1993 18:03:10 +0000
parents f650efceb0fb
children b6c62e4abf59
comparison
equal deleted inserted replaced
2388:3f27c886f375 2389:6048be0eedcd
271 b->last_window_start = 1; 271 b->last_window_start = 1;
272 b->backed_up = Qnil; 272 b->backed_up = Qnil;
273 b->auto_save_modified = 0; 273 b->auto_save_modified = 0;
274 b->auto_save_file_name = Qnil; 274 b->auto_save_file_name = Qnil;
275 b->read_only = Qnil; 275 b->read_only = Qnil;
276 b->fieldlist = Qnil; 276 b->overlays_before = Qnil;
277 b->overlays_after = Qnil;
278 XFASTINT (b->overlay_center) = 1;
277 279
278 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ 280 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
279 INITIALIZE_INTERVAL (b, NULL_INTERVAL); 281 INITIALIZE_INTERVAL (b, NULL_INTERVAL);
280 282
281 reset_buffer_local_variables(b); 283 reset_buffer_local_variables(b);
1178 update_mode_lines++; 1180 update_mode_lines++;
1179 1181
1180 return Qnil; 1182 return Qnil;
1181 } 1183 }
1182 1184
1183 DEFUN ("region-fields", Fregion_fields, Sregion_fields, 2, 4, "", 1185 /* Find all the overlays in the current buffer that contain position POS.
1184 "Return list of fields overlapping a given portion of a buffer.\n\ 1186 Return the number found, and store them in a vector in *VEC_PTR.
1185 The portion is specified by arguments START, END and BUFFER.\n\ 1187 Store in *LEN_PTR the size allocated for the vector.
1186 BUFFER defaults to the current buffer.\n\ 1188 Store in *NEXT_PTR the next position after POS where an overlay starts.
1187 Optional 4th arg ERROR-CHECK non nil means just report an error\n\ 1189
1188 if any protected fields overlap this portion.") 1190 *VEC_PTR and *LEN_PTR should contain a valid vector and size
1189 (start, end, buffer, error_check) 1191 when this function is called. */
1190 Lisp_Object start, end, buffer, error_check; 1192
1191 { 1193 int
1192 register int start_loc, end_loc; 1194 overlays_at (pos, vec_ptr, len_ptr, next_ptr)
1193 Lisp_Object fieldlist; 1195 int pos;
1194 Lisp_Object collector; 1196 Lisp_Object **vec_ptr;
1195 1197 int *len_ptr;
1196 if (NILP (buffer)) 1198 int *next_ptr;
1197 fieldlist = current_buffer->fieldlist; 1199 {
1200 Lisp_Object tail, overlay, start, end, result;
1201 int idx = 0;
1202 int len = *len_ptr;
1203 Lisp_Object *vec = *vec_ptr;
1204 int next = ZV;
1205 int startpos;
1206
1207 for (tail = current_buffer->overlays_before;
1208 CONSP (tail);
1209 tail = XCONS (tail)->cdr)
1210 {
1211 overlay = XCONS (tail)->car;
1212 if (! OVERLAY_VALID (overlay))
1213 continue;
1214
1215 start = OVERLAY_START (overlay);
1216 end = OVERLAY_END (overlay);
1217 if (OVERLAY_POSITION (end) <= pos)
1218 break;
1219 startpos = OVERLAY_POSITION (start);
1220 if (startpos <= pos)
1221 {
1222 if (idx == len)
1223 {
1224 *len_ptr = len *= 2;
1225 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1226 *vec_ptr = vec;
1227 }
1228 vec[idx++] = overlay;
1229 }
1230 else if (startpos < next)
1231 next = startpos;
1232 }
1233
1234 for (tail = current_buffer->overlays_after;
1235 CONSP (tail);
1236 tail = XCONS (tail)->cdr)
1237 {
1238 overlay = XCONS (tail)->car;
1239 if (! OVERLAY_VALID (overlay))
1240 continue;
1241
1242 start = OVERLAY_START (overlay);
1243 end = OVERLAY_END (overlay);
1244 startpos = OVERLAY_POSITION (start);
1245 if (startpos > pos)
1246 {
1247 if (startpos < next)
1248 next = startpos;
1249 break;
1250 }
1251 if (OVERLAY_POSITION (end) > pos)
1252 {
1253 if (idx == len)
1254 {
1255 *len_ptr = len *= 2;
1256 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
1257 *vec_ptr = vec;
1258 }
1259 vec[idx++] = overlay;
1260 }
1261 }
1262
1263 *next_ptr = next;
1264 return idx;
1265 }
1266
1267 /* Shift overlays in the current buffer's overlay lists,
1268 to center the lists at POS. */
1269
1270 void
1271 recenter_overlay_lists (pos)
1272 int pos;
1273 {
1274 Lisp_Object overlay, tail, next, prev, beg, end;
1275
1276 /* See if anything in overlays_before should move to overlays_after. */
1277
1278 /* We don't strictly need prev in this loop; it should always be nil.
1279 But we use it for symmetry and in case that should cease to be true
1280 with some future change. */
1281 prev = Qnil;
1282 for (tail = current_buffer->overlays_before;
1283 CONSP (tail);
1284 prev = tail, tail = next)
1285 {
1286 next = XCONS (tail)->cdr;
1287 overlay = XCONS (tail)->car;
1288
1289 /* If the overlay is not valid, get rid of it. */
1290 if (!OVERLAY_VALID (overlay))
1291 {
1292 /* Splice the cons cell TAIL out of overlays_before. */
1293 if (!NILP (prev))
1294 XCONS (prev)->cdr = next;
1295 else
1296 current_buffer->overlays_before = next;
1297 tail = prev;
1298 continue;
1299 }
1300
1301 beg = OVERLAY_START (overlay);
1302 end = OVERLAY_END (overlay);
1303
1304 if (OVERLAY_POSITION (end) > pos)
1305 {
1306 /* OVERLAY needs to be moved. */
1307 int where = OVERLAY_POSITION (beg);
1308 Lisp_Object other, other_prev;
1309
1310 /* Splice the cons cell TAIL out of overlays_before. */
1311 if (!NILP (prev))
1312 XCONS (prev)->cdr = next;
1313 else
1314 current_buffer->overlays_before = next;
1315
1316 /* Search thru overlays_after for where to put it. */
1317 other_prev = Qnil;
1318 for (other = current_buffer->overlays_after;
1319 CONSP (other);
1320 other_prev = other, other = XCONS (other)->cdr)
1321 {
1322 Lisp_Object otherbeg, otheroverlay, follower;
1323 int win;
1324
1325 otheroverlay = XCONS (other)->car;
1326 if (! OVERLAY_VALID (otheroverlay))
1327 continue;
1328
1329 otherbeg = OVERLAY_START (otheroverlay);
1330 if (OVERLAY_POSITION (otherbeg) >= where)
1331 break;
1332 }
1333
1334 /* Add TAIL to overlays_after before OTHER. */
1335 XCONS (tail)->cdr = other;
1336 if (!NILP (other_prev))
1337 XCONS (other_prev)->cdr = tail;
1338 else
1339 current_buffer->overlays_after = tail;
1340 tail = prev;
1341 }
1342 else
1343 /* We've reached the things that should stay in overlays_before.
1344 All the rest of overlays_before must end even earlier,
1345 so stop now. */
1346 break;
1347 }
1348
1349 /* See if anything in overlays_after should be in overlays_before. */
1350 prev = Qnil;
1351 for (tail = current_buffer->overlays_after;
1352 CONSP (tail);
1353 prev = tail, tail = next)
1354 {
1355 next = XCONS (tail)->cdr;
1356 overlay = XCONS (tail)->car;
1357
1358 /* If the overlay is not valid, get rid of it. */
1359 if (!OVERLAY_VALID (overlay))
1360 {
1361 /* Splice the cons cell TAIL out of overlays_after. */
1362 if (!NILP (prev))
1363 XCONS (prev)->cdr = next;
1364 else
1365 current_buffer->overlays_after = next;
1366 tail = prev;
1367 continue;
1368 }
1369
1370 beg = OVERLAY_START (overlay);
1371 end = OVERLAY_END (overlay);
1372
1373 /* Stop looking, when we know that nothing further
1374 can possibly end before POS. */
1375 if (OVERLAY_POSITION (beg) > pos)
1376 break;
1377
1378 if (OVERLAY_POSITION (end) <= pos)
1379 {
1380 /* OVERLAY needs to be moved. */
1381 int where = OVERLAY_POSITION (end);
1382 Lisp_Object other, other_prev;
1383
1384 /* Splice the cons cell TAIL out of overlays_after. */
1385 if (!NILP (prev))
1386 XCONS (prev)->cdr = next;
1387 else
1388 current_buffer->overlays_after = next;
1389
1390 /* Search thru overlays_before for where to put it. */
1391 other_prev = Qnil;
1392 for (other = current_buffer->overlays_before;
1393 CONSP (other);
1394 other_prev = other, other = XCONS (other)->cdr)
1395 {
1396 Lisp_Object otherend, otheroverlay;
1397 int win;
1398
1399 otheroverlay = XCONS (other)->car;
1400 if (! OVERLAY_VALID (otheroverlay))
1401 continue;
1402
1403 otherend = OVERLAY_END (otheroverlay);
1404 if (OVERLAY_POSITION (otherend) <= where)
1405 break;
1406 }
1407
1408 /* Add TAIL to overlays_before before OTHER. */
1409 XCONS (tail)->cdr = other;
1410 if (!NILP (other_prev))
1411 XCONS (other_prev)->cdr = tail;
1412 else
1413 current_buffer->overlays_before = tail;
1414 tail = prev;
1415 }
1416 }
1417
1418 XFASTINT (current_buffer->overlay_center) = pos;
1419 }
1420
1421 DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 2, 0,
1422 "Create a new overlay in the current buffer, with range BEG to END.\n\
1423 BEG and END may be integers or markers.")
1424 (beg, end)
1425 Lisp_Object beg, end;
1426 {
1427 Lisp_Object overlay;
1428
1429 if (MARKERP (beg) && XBUFFER (Fmarker_buffer (beg)) != current_buffer)
1430 error ("Marker points into wrong buffer");
1431 if (MARKERP (end) && XBUFFER (Fmarker_buffer (end)) != current_buffer)
1432 error ("Marker points into wrong buffer");
1433
1434 overlay = Fcons (Fcons (Fcopy_marker (beg), Fcopy_marker (end)), Qnil);
1435
1436 /* Put the new overlay on the wrong list. */
1437 end = OVERLAY_END (overlay);
1438 if (OVERLAY_POSITION (end) < XINT (current_buffer->overlay_center))
1439 current_buffer->overlays_after
1440 = Fcons (overlay, current_buffer->overlays_after);
1198 else 1441 else
1199 { 1442 current_buffer->overlays_before
1200 CHECK_BUFFER (buffer, 1); 1443 = Fcons (overlay, current_buffer->overlays_before);
1201 fieldlist = XBUFFER (buffer)->fieldlist; 1444
1202 } 1445 /* This puts it in the right list, and in the right order. */
1203 1446 recenter_overlay_lists (XINT (current_buffer->overlay_center));
1204 CHECK_NUMBER_COERCE_MARKER (start, 2); 1447
1205 start_loc = XINT (start); 1448 return overlay;
1206 1449 }
1207 CHECK_NUMBER_COERCE_MARKER (end, 2); 1450
1208 end_loc = XINT (end); 1451 DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 3, 0,
1209 1452 "Set the endpoints of OVERLAY to BEG and END.")
1210 collector = Qnil; 1453 (overlay, beg, end)
1211 1454 Lisp_Object overlay, beg, end;
1212 while (XTYPE (fieldlist) == Lisp_Cons) 1455 {
1213 { 1456 if (!OVERLAY_VALID (overlay))
1214 register Lisp_Object field; 1457 error ("Invalid overlay object");
1215 register int field_start, field_end; 1458
1216 1459 current_buffer->overlays_before
1217 field = XCONS (fieldlist)->car; 1460 = Fdelq (overlay, current_buffer->overlays_before);
1218 field_start = marker_position (FIELD_START_MARKER (field)) - 1; 1461 current_buffer->overlays_after
1219 field_end = marker_position (FIELD_END_MARKER (field)); 1462 = Fdelq (overlay, current_buffer->overlays_after);
1220 1463
1221 if ((start_loc < field_start && end_loc > field_start) 1464 Fset_marker (OVERLAY_START (overlay), beg, Qnil);
1222 || (start_loc >= field_start && start_loc < field_end)) 1465 Fset_marker (OVERLAY_END (overlay), end, Qnil);
1223 { 1466
1224 if (!NILP (error_check)) 1467 /* Put the overlay on the wrong list. */
1225 { 1468 end = OVERLAY_END (overlay);
1226 if (!NILP (FIELD_PROTECTED_FLAG (field))) 1469 if (OVERLAY_POSITION (end) < XINT (current_buffer->overlay_center))
1227 { 1470 current_buffer->overlays_after
1228 struct gcpro gcpro1; 1471 = Fcons (overlay, current_buffer->overlays_after);
1229 GCPRO1 (fieldlist); 1472 else
1230 Fsignal (Qprotected_field, Fcons (field, Qnil)); 1473 current_buffer->overlays_before
1231 UNGCPRO; 1474 = Fcons (overlay, current_buffer->overlays_before);
1232 } 1475
1233 } 1476 /* This puts it in the right list, and in the right order. */
1234 else 1477 recenter_overlay_lists (XINT (current_buffer->overlay_center));
1235 collector = Fcons (field, collector); 1478
1236 } 1479 return overlay;
1237 1480 }
1238 fieldlist = XCONS (fieldlist)->cdr; 1481
1239 } 1482 DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
1240 1483 "Delete the overlay OVERLAY from the current buffer.")
1241 return collector; 1484 (overlay)
1485 {
1486 current_buffer->overlays_before
1487 = Fdelq (overlay, current_buffer->overlays_before);
1488 current_buffer->overlays_after
1489 = Fdelq (overlay, current_buffer->overlays_after);
1490 return Qnil;
1491 }
1492
1493 DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
1494 "Return a list of the overays that contain position POS.")
1495 (pos)
1496 Lisp_Object pos;
1497 {
1498 int noverlays;
1499 int endpos;
1500 Lisp_Object *overlay_vec;
1501 int len;
1502 Lisp_Object result;
1503
1504 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1505
1506 len = 10;
1507 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
1508
1509 /* Put all the overlays we want in a vector in overlay_vec.
1510 Store the length in len. */
1511 noverlays = overlays_at (XINT (pos), &overlay_vec, &len, &endpos);
1512
1513 /* Make a list of them all. */
1514 result = Flist (noverlays, overlay_vec);
1515
1516 free (overlay_vec);
1517 return result;
1518 }
1519
1520 DEFUN ("next-overlay-change", Fnext_overlay_change, Snext_overlay_change,
1521 1, 1, 0,
1522 "Return the next position after POS where an overlay starts or ends.")
1523 (pos)
1524 Lisp_Object pos;
1525 {
1526 int noverlays;
1527 int endpos;
1528 Lisp_Object *overlay_vec;
1529 int len;
1530 Lisp_Object result;
1531 int i;
1532
1533 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1534
1535 len = 10;
1536 overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
1537
1538 /* Put all the overlays we want in a vector in overlay_vec.
1539 Store the length in len.
1540 endpos gets the position where the next overlay starts. */
1541 noverlays = overlays_at (XINT (pos), &overlay_vec, &len, &endpos);
1542
1543 /* If any of these overlays ends before endpos,
1544 use its ending point instead. */
1545 for (i = 0; i < noverlays; i++)
1546 {
1547 Lisp_Object oend;
1548 int oendpos;
1549
1550 oend = OVERLAY_END (overlay_vec[i]);
1551 oendpos = OVERLAY_POSITION (oend);
1552 if (oendpos < endpos)
1553 endpos = oendpos;
1554 }
1555
1556 free (overlay_vec);
1557 return make_number (endpos);
1558 }
1559
1560 /* These functions are for debugging overlays. */
1561
1562 DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
1563 "Return a pair of lists giving all the overlays of the current buffer.\n\
1564 The car has all the overlays before the overlay center;\n\
1565 the cdr has all the overlays before the overlay center.\n\
1566 Recentering overlays moves overlays between these lists.\n\
1567 The lists you get are copies, so that changing them has no effect.\n\
1568 However, the overlays you get are the real objects that the buffer uses.")
1569 ()
1570 {
1571 Lisp_Object before, after;
1572 before = current_buffer->overlays_before;
1573 if (CONSP (before))
1574 before = Fcopy_sequence (before);
1575 after = current_buffer->overlays_after;
1576 if (CONSP (after))
1577 after = Fcopy_sequence (after);
1578
1579 return Fcons (before, after);
1580 }
1581
1582 DEFUN ("overlay-recenter", Foverlay_recenter, Soverlay_recenter, 1, 1, 0,
1583 "Recenter the overlays of the current buffer around position POS.")
1584 (pos)
1585 Lisp_Object pos;
1586 {
1587 CHECK_NUMBER_COERCE_MARKER (pos, 0);
1588
1589 recenter_overlay_lists (XINT (pos));
1590 return Qnil;
1591 }
1592
1593 DEFUN ("overlay-get", Foverlay_get, Soverlay_get, 2, 2, 0,
1594 "Get the property of overlay OVERLAY with property name NAME.")
1595 (overlay, prop)
1596 Lisp_Object overlay, prop;
1597 {
1598 Lisp_Object plist;
1599 for (plist = Fcdr_safe (Fcdr_safe (overlay));
1600 CONSP (plist) && CONSP (XCONS (plist)->cdr);
1601 plist = XCONS (XCONS (plist)->cdr)->cdr)
1602 {
1603 if (EQ (XCONS (plist)->car, prop))
1604 return XCONS (XCONS (plist)->cdr)->car;
1605 }
1606 }
1607
1608 DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
1609 "Set one property of overlay OVERLAY: give property PROP value VALUE.")
1610 (overlay, prop, value)
1611 Lisp_Object overlay, prop, value;
1612 {
1613 Lisp_Object plist, tail;
1614
1615 plist = Fcdr_safe (Fcdr_safe (overlay));
1616
1617 for (tail = plist;
1618 CONSP (tail) && CONSP (XCONS (tail)->cdr);
1619 tail = XCONS (XCONS (tail)->cdr)->cdr)
1620 {
1621 if (EQ (XCONS (tail)->car, prop))
1622 return XCONS (XCONS (tail)->cdr)->car = value;
1623 }
1624
1625 if (! CONSP (XCONS (overlay)->cdr))
1626 XCONS (overlay)->cdr = Fcons (Qnil, Qnil);
1627
1628 XCONS (XCONS (overlay)->cdr)->cdr
1629 = Fcons (prop, Fcons (value, plist));
1630
1631 return value;
1242 } 1632 }
1243 1633
1244 /* Somebody has tried to store NEWVAL into the buffer-local slot with 1634 /* Somebody has tried to store NEWVAL into the buffer-local slot with
1245 offset XUINT (valcontents), and NEWVAL has an unacceptable type. */ 1635 offset XUINT (valcontents), and NEWVAL has an unacceptable type. */
1246 void 1636 void
1293 #ifndef old 1683 #ifndef old
1294 buffer_defaults.selective_display_ellipses = Qt; 1684 buffer_defaults.selective_display_ellipses = Qt;
1295 #endif 1685 #endif
1296 buffer_defaults.abbrev_table = Qnil; 1686 buffer_defaults.abbrev_table = Qnil;
1297 buffer_defaults.display_table = Qnil; 1687 buffer_defaults.display_table = Qnil;
1298 buffer_defaults.fieldlist = Qnil;
1299 buffer_defaults.undo_list = Qnil; 1688 buffer_defaults.undo_list = Qnil;
1300 buffer_defaults.mark_active = Qnil; 1689 buffer_defaults.mark_active = Qnil;
1690 buffer_defaults.overlays_before = Qnil;
1691 buffer_defaults.overlays_after = Qnil;
1692 XFASTINT (buffer_defaults.overlay_center) = 1;
1301 1693
1302 XFASTINT (buffer_defaults.tab_width) = 8; 1694 XFASTINT (buffer_defaults.tab_width) = 8;
1303 buffer_defaults.truncate_lines = Qnil; 1695 buffer_defaults.truncate_lines = Qnil;
1304 buffer_defaults.ctl_arrow = Qt; 1696 buffer_defaults.ctl_arrow = Qt;
1305 1697
1341 XFASTINT (buffer_local_flags.ctl_arrow) = 0x200; 1733 XFASTINT (buffer_local_flags.ctl_arrow) = 0x200;
1342 XFASTINT (buffer_local_flags.fill_column) = 0x400; 1734 XFASTINT (buffer_local_flags.fill_column) = 0x400;
1343 XFASTINT (buffer_local_flags.left_margin) = 0x800; 1735 XFASTINT (buffer_local_flags.left_margin) = 0x800;
1344 XFASTINT (buffer_local_flags.abbrev_table) = 0x1000; 1736 XFASTINT (buffer_local_flags.abbrev_table) = 0x1000;
1345 XFASTINT (buffer_local_flags.display_table) = 0x2000; 1737 XFASTINT (buffer_local_flags.display_table) = 0x2000;
1346 XFASTINT (buffer_local_flags.fieldlist) = 0x4000;
1347 XFASTINT (buffer_local_flags.syntax_table) = 0x8000; 1738 XFASTINT (buffer_local_flags.syntax_table) = 0x8000;
1348 1739
1349 Vbuffer_alist = Qnil; 1740 Vbuffer_alist = Qnil;
1350 current_buffer = 0; 1741 current_buffer = 0;
1351 all_buffers = 0; 1742 all_buffers = 0;
1730 defsubr (&Sset_buffer); 2121 defsubr (&Sset_buffer);
1731 defsubr (&Sbarf_if_buffer_read_only); 2122 defsubr (&Sbarf_if_buffer_read_only);
1732 defsubr (&Sbury_buffer); 2123 defsubr (&Sbury_buffer);
1733 defsubr (&Slist_buffers); 2124 defsubr (&Slist_buffers);
1734 defsubr (&Skill_all_local_variables); 2125 defsubr (&Skill_all_local_variables);
1735 defsubr (&Sregion_fields); 2126
2127 defsubr (&Smake_overlay);
2128 defsubr (&Sdelete_overlay);
2129 defsubr (&Smove_overlay);
2130 defsubr (&Soverlays_at);
2131 defsubr (&Snext_overlay_change);
2132 defsubr (&Soverlay_recenter);
2133 defsubr (&Soverlay_lists);
2134 defsubr (&Soverlay_get);
2135 defsubr (&Soverlay_put);
1736 } 2136 }
1737 2137
1738 keys_of_buffer () 2138 keys_of_buffer ()
1739 { 2139 {
1740 initial_define_key (control_x_map, 'b', "switch-to-buffer"); 2140 initial_define_key (control_x_map, 'b', "switch-to-buffer");