aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-27 18:03:10 +0000
committerRichard M. Stallman1993-03-27 18:03:10 +0000
commit2eec3b4e0cf6001ba675f9e7d329a69184cd04f1 (patch)
tree4e9560f0ef8050350e8910721045cbee0786d91b /src
parente15765f5e2b9286dd02d47acde2a383a4ee6c25a (diff)
downloademacs-2eec3b4e0cf6001ba675f9e7d329a69184cd04f1.tar.gz
emacs-2eec3b4e0cf6001ba675f9e7d329a69184cd04f1.zip
(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.
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c494
1 files changed, 447 insertions, 47 deletions
diff --git a/src/buffer.c b/src/buffer.c
index e1e46445b1e..edf04aa2e64 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -273,7 +273,9 @@ reset_buffer (b)
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);
@@ -1180,65 +1182,453 @@ a non-nil `permanent-local' property are not eliminated by this function.")
1180 return Qnil; 1182 return Qnil;
1181} 1183}
1182 1184
1183DEFUN ("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.
1185The portion is specified by arguments START, END and BUFFER.\n\ 1187 Store in *LEN_PTR the size allocated for the vector.
1186BUFFER defaults to the current buffer.\n\ 1188 Store in *NEXT_PTR the next position after POS where an overlay starts.
1187Optional 4th arg ERROR-CHECK non nil means just report an error\n\ 1189
1188if 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
1193int
1194overlays_at (pos, vec_ptr, len_ptr, next_ptr)
1195 int pos;
1196 Lisp_Object **vec_ptr;
1197 int *len_ptr;
1198 int *next_ptr;
1191{ 1199{
1192 register int start_loc, end_loc; 1200 Lisp_Object tail, overlay, start, end, result;
1193 Lisp_Object fieldlist; 1201 int idx = 0;
1194 Lisp_Object collector; 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;
1195 1214
1196 if (NILP (buffer)) 1215 start = OVERLAY_START (overlay);
1197 fieldlist = current_buffer->fieldlist; 1216 end = OVERLAY_END (overlay);
1198 else 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)
1199 { 1237 {
1200 CHECK_BUFFER (buffer, 1); 1238 overlay = XCONS (tail)->car;
1201 fieldlist = XBUFFER (buffer)->fieldlist; 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 }
1202 } 1261 }
1203 1262
1204 CHECK_NUMBER_COERCE_MARKER (start, 2); 1263 *next_ptr = next;
1205 start_loc = XINT (start); 1264 return idx;
1265}
1266
1267/* Shift overlays in the current buffer's overlay lists,
1268 to center the lists at POS. */
1206 1269
1207 CHECK_NUMBER_COERCE_MARKER (end, 2); 1270void
1208 end_loc = XINT (end); 1271recenter_overlay_lists (pos)
1209 1272 int pos;
1210 collector = Qnil; 1273{
1211 1274 Lisp_Object overlay, tail, next, prev, beg, end;
1212 while (XTYPE (fieldlist) == Lisp_Cons) 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)
1213 { 1285 {
1214 register Lisp_Object field; 1286 next = XCONS (tail)->cdr;
1215 register int field_start, field_end; 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 }
1216 1300
1217 field = XCONS (fieldlist)->car; 1301 beg = OVERLAY_START (overlay);
1218 field_start = marker_position (FIELD_START_MARKER (field)) - 1; 1302 end = OVERLAY_END (overlay);
1219 field_end = marker_position (FIELD_END_MARKER (field));
1220 1303
1221 if ((start_loc < field_start && end_loc > field_start) 1304 if (OVERLAY_POSITION (end) > pos)
1222 || (start_loc >= field_start && start_loc < field_end))
1223 { 1305 {
1224 if (!NILP (error_check)) 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)
1225 { 1321 {
1226 if (!NILP (FIELD_PROTECTED_FLAG (field))) 1322 Lisp_Object otherbeg, otheroverlay, follower;
1227 { 1323 int win;
1228 struct gcpro gcpro1; 1324
1229 GCPRO1 (fieldlist); 1325 otheroverlay = XCONS (other)->car;
1230 Fsignal (Qprotected_field, Fcons (field, Qnil)); 1326 if (! OVERLAY_VALID (otheroverlay))
1231 UNGCPRO; 1327 continue;
1232 } 1328
1329 otherbeg = OVERLAY_START (otheroverlay);
1330 if (OVERLAY_POSITION (otherbeg) >= where)
1331 break;
1233 } 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;
1234 else 1338 else
1235 collector = Fcons (field, collector); 1339 current_buffer->overlays_after = tail;
1340 tail = prev;
1236 } 1341 }
1237 1342 else
1238 fieldlist = XCONS (fieldlist)->cdr; 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
1421DEFUN ("make-overlay", Fmake_overlay, Smake_overlay, 2, 2, 0,
1422 "Create a new overlay in the current buffer, with range BEG to END.\n\
1423BEG 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);
1441 else
1442 current_buffer->overlays_before
1443 = Fcons (overlay, current_buffer->overlays_before);
1444
1445 /* This puts it in the right list, and in the right order. */
1446 recenter_overlay_lists (XINT (current_buffer->overlay_center));
1447
1448 return overlay;
1449}
1450
1451DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 3, 0,
1452 "Set the endpoints of OVERLAY to BEG and END.")
1453 (overlay, beg, end)
1454 Lisp_Object overlay, beg, end;
1455{
1456 if (!OVERLAY_VALID (overlay))
1457 error ("Invalid overlay object");
1458
1459 current_buffer->overlays_before
1460 = Fdelq (overlay, current_buffer->overlays_before);
1461 current_buffer->overlays_after
1462 = Fdelq (overlay, current_buffer->overlays_after);
1463
1464 Fset_marker (OVERLAY_START (overlay), beg, Qnil);
1465 Fset_marker (OVERLAY_END (overlay), end, Qnil);
1466
1467 /* Put the overlay on the wrong list. */
1468 end = OVERLAY_END (overlay);
1469 if (OVERLAY_POSITION (end) < XINT (current_buffer->overlay_center))
1470 current_buffer->overlays_after
1471 = Fcons (overlay, current_buffer->overlays_after);
1472 else
1473 current_buffer->overlays_before
1474 = Fcons (overlay, current_buffer->overlays_before);
1475
1476 /* This puts it in the right list, and in the right order. */
1477 recenter_overlay_lists (XINT (current_buffer->overlay_center));
1478
1479 return overlay;
1480}
1481
1482DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
1483 "Delete the overlay OVERLAY from the current buffer.")
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
1493DEFUN ("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
1520DEFUN ("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;
1239 } 1554 }
1240 1555
1241 return collector; 1556 free (overlay_vec);
1557 return make_number (endpos);
1558}
1559
1560/* These functions are for debugging overlays. */
1561
1562DEFUN ("overlay-lists", Foverlay_lists, Soverlay_lists, 0, 0, 0,
1563 "Return a pair of lists giving all the overlays of the current buffer.\n\
1564The car has all the overlays before the overlay center;\n\
1565the cdr has all the overlays before the overlay center.\n\
1566Recentering overlays moves overlays between these lists.\n\
1567The lists you get are copies, so that changing them has no effect.\n\
1568However, 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
1582DEFUN ("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
1593DEFUN ("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
1608DEFUN ("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
@@ -1295,9 +1685,11 @@ init_buffer_once ()
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;
@@ -1343,7 +1735,6 @@ init_buffer_once ()
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;
@@ -1732,7 +2123,16 @@ Automatically local in all buffers.");
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
1738keys_of_buffer () 2138keys_of_buffer ()