aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKarl Heuer1998-06-03 14:45:03 +0000
committerKarl Heuer1998-06-03 14:45:03 +0000
commitad077db084860c8c8e3f94221c20dd3ce3dea97e (patch)
treef870f6fdf88ae503850c6e221f8ef60053fdb852 /src
parent944d4e4b401fa1dc1d04f74856406bf5a4a813bf (diff)
downloademacs-ad077db084860c8c8e3f94221c20dd3ce3dea97e.tar.gz
emacs-ad077db084860c8c8e3f94221c20dd3ce3dea97e.zip
Handle the new convention that `position' values
in a string's intervals start from zero. (validate_interval_range, interval_of, Fnext_property_change) (property_change_between_p, Fnext_single_property_change) (Fprevious_property_change, Fprevious_single_property_change): (Ftext_property_any, Ftext_property_not_all): Implement that. Undo previous change.
Diffstat (limited to 'src')
-rw-r--r--src/textprop.c167
1 files changed, 22 insertions, 145 deletions
diff --git a/src/textprop.c b/src/textprop.c
index 0309f8c2d9d..ce2c7530d89 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -150,11 +150,9 @@ validate_interval_range (object, begin, end, force)
150 if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end) 150 if (! (0 <= XINT (*begin) && XINT (*begin) <= XINT (*end)
151 && XINT (*end) <= s->size)) 151 && XINT (*end) <= s->size))
152 args_out_of_range (*begin, *end); 152 args_out_of_range (*begin, *end);
153 /* User-level Positions in strings start with 0, 153 XSETFASTINT (*begin, XFASTINT (*begin));
154 but the interval code always wants positions starting with 1. */
155 XSETFASTINT (*begin, XFASTINT (*begin) + 1);
156 if (begin != end) 154 if (begin != end)
157 XSETFASTINT (*end, XFASTINT (*end) + 1); 155 XSETFASTINT (*end, XFASTINT (*end));
158 i = s->intervals; 156 i = s->intervals;
159 157
160 if (s->size == 0) 158 if (s->size == 0)
@@ -479,7 +477,7 @@ erase_properties (i)
479} 477}
480#endif 478#endif
481 479
482/* Returns the interval of the POSITION in OBJECT. 480/* Returns the interval of POSITION in OBJECT.
483 POSITION is BEG-based. */ 481 POSITION is BEG-based. */
484 482
485INTERVAL 483INTERVAL
@@ -509,9 +507,8 @@ interval_of (position, object)
509 { 507 {
510 register struct Lisp_String *s = XSTRING (object); 508 register struct Lisp_String *s = XSTRING (object);
511 509
512 /* We expect position to be 1-based. */ 510 beg = 0;
513 beg = BEG; 511 end = s->size;
514 end = s->size + BEG;
515 i = s->intervals; 512 i = s->intervals;
516 } 513 }
517 514
@@ -716,7 +713,7 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
716 ? XSTRING (object)->size 713 ? XSTRING (object)->size
717 : BUF_ZV (XBUFFER (object)))); 714 : BUF_ZV (XBUFFER (object))));
718 else 715 else
719 XSETFASTINT (position, next->position - (STRINGP (object))); 716 XSETFASTINT (position, next->position);
720 return position; 717 return position;
721 } 718 }
722 719
@@ -726,17 +723,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
726 next = next_interval (i); 723 next = next_interval (i);
727 724
728 while (! NULL_INTERVAL_P (next) && intervals_equal (i, next) 725 while (! NULL_INTERVAL_P (next) && intervals_equal (i, next)
729 && (NILP (limit) 726 && (NILP (limit) || next->position < XFASTINT (limit)))
730 || next->position - (STRINGP (object)) < XFASTINT (limit)))
731 next = next_interval (next); 727 next = next_interval (next);
732 728
733 if (NULL_INTERVAL_P (next)) 729 if (NULL_INTERVAL_P (next))
734 return limit; 730 return limit;
735 if (! NILP (limit) 731 if (! NILP (limit) && !(next->position < XFASTINT (limit)))
736 && !(next->position - (STRINGP (object)) < XFASTINT (limit)))
737 return limit; 732 return limit;
738 733
739 XSETFASTINT (position, next->position - (STRINGP (object))); 734 XSETFASTINT (position, next->position);
740 return position; 735 return position;
741} 736}
742 737
@@ -762,7 +757,7 @@ property_change_between_p (beg, end)
762 next = next_interval (next); 757 next = next_interval (next);
763 if (NULL_INTERVAL_P (next)) 758 if (NULL_INTERVAL_P (next))
764 return 0; 759 return 0;
765 if (next->position - (STRINGP (object)) >= end) 760 if (next->position >= end)
766 return 0; 761 return 0;
767 } 762 }
768 763
@@ -803,17 +798,15 @@ past position LIMIT; return LIMIT if nothing is found before LIMIT.")
803 next = next_interval (i); 798 next = next_interval (i);
804 while (! NULL_INTERVAL_P (next) 799 while (! NULL_INTERVAL_P (next)
805 && EQ (here_val, textget (next->plist, prop)) 800 && EQ (here_val, textget (next->plist, prop))
806 && (NILP (limit) || next->position - (STRINGP (object)) < XFASTINT (limit))) 801 && (NILP (limit) || next->position < XFASTINT (limit)))
807 next = next_interval (next); 802 next = next_interval (next);
808 803
809 if (NULL_INTERVAL_P (next)) 804 if (NULL_INTERVAL_P (next))
810 return limit; 805 return limit;
811 if (! NILP (limit) 806 if (! NILP (limit) && !(next->position < XFASTINT (limit)))
812 && !(next->position - (STRINGP (object)) < XFASTINT (limit)))
813 return limit; 807 return limit;
814 808
815 XSETFASTINT (position, next->position - (STRINGP (object))); 809 return make_number (next->position);
816 return position;
817} 810}
818 811
819DEFUN ("previous-property-change", Fprevious_property_change, 812DEFUN ("previous-property-change", Fprevious_property_change,
@@ -848,19 +841,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.")
848 previous = previous_interval (i); 841 previous = previous_interval (i);
849 while (! NULL_INTERVAL_P (previous) && intervals_equal (previous, i) 842 while (! NULL_INTERVAL_P (previous) && intervals_equal (previous, i)
850 && (NILP (limit) 843 && (NILP (limit)
851 || (previous->position + LENGTH (previous) - (STRINGP (object)) 844 || (previous->position + LENGTH (previous) > XFASTINT (limit))))
852 > XFASTINT (limit))))
853 previous = previous_interval (previous); 845 previous = previous_interval (previous);
854 if (NULL_INTERVAL_P (previous)) 846 if (NULL_INTERVAL_P (previous))
855 return limit; 847 return limit;
856 if (!NILP (limit) 848 if (!NILP (limit)
857 && !(previous->position + LENGTH (previous) - (STRINGP (object)) 849 && !(previous->position + LENGTH (previous) > XFASTINT (limit)))
858 > XFASTINT (limit)))
859 return limit; 850 return limit;
860 851
861 XSETFASTINT (position, (previous->position + LENGTH (previous) 852 return make_number (previous->position + LENGTH (previous));
862 - (STRINGP (object))));
863 return position;
864} 853}
865 854
866DEFUN ("previous-single-property-change", Fprevious_single_property_change, 855DEFUN ("previous-single-property-change", Fprevious_single_property_change,
@@ -900,19 +889,15 @@ back past position LIMIT; return LIMIT if nothing is found until LIMIT.")
900 while (! NULL_INTERVAL_P (previous) 889 while (! NULL_INTERVAL_P (previous)
901 && EQ (here_val, textget (previous->plist, prop)) 890 && EQ (here_val, textget (previous->plist, prop))
902 && (NILP (limit) 891 && (NILP (limit)
903 || (previous->position + LENGTH (previous) - (STRINGP (object)) 892 || (previous->position + LENGTH (previous) > XFASTINT (limit))))
904 > XFASTINT (limit))))
905 previous = previous_interval (previous); 893 previous = previous_interval (previous);
906 if (NULL_INTERVAL_P (previous)) 894 if (NULL_INTERVAL_P (previous))
907 return limit; 895 return limit;
908 if (!NILP (limit) 896 if (!NILP (limit)
909 && !(previous->position + LENGTH (previous) - (STRINGP (object)) 897 && !(previous->position + LENGTH (previous) > XFASTINT (limit)))
910 > XFASTINT (limit)))
911 return limit; 898 return limit;
912 899
913 XSETFASTINT (position, (previous->position + LENGTH (previous) 900 return make_number (previous->position + LENGTH (previous));
914 - (STRINGP (object))));
915 return position;
916} 901}
917 902
918/* Callers note, this can GC when OBJECT is a buffer (or nil). */ 903/* Callers note, this can GC when OBJECT is a buffer (or nil). */
@@ -1294,7 +1279,7 @@ containing the text.")
1294 pos = i->position; 1279 pos = i->position;
1295 if (pos < XINT (start)) 1280 if (pos < XINT (start))
1296 pos = XINT (start); 1281 pos = XINT (start);
1297 return make_number (pos - (STRINGP (object))); 1282 return make_number (pos);
1298 } 1283 }
1299 i = next_interval (i); 1284 i = next_interval (i);
1300 } 1285 }
@@ -1330,121 +1315,13 @@ containing the text.")
1330 { 1315 {
1331 if (i->position > s) 1316 if (i->position > s)
1332 s = i->position; 1317 s = i->position;
1333 return make_number (s - (STRINGP (object))); 1318 return make_number (s);
1334 } 1319 }
1335 i = next_interval (i); 1320 i = next_interval (i);
1336 } 1321 }
1337 return Qnil; 1322 return Qnil;
1338} 1323}
1339 1324
1340#if 0 /* You can use set-text-properties for this. */
1341
1342DEFUN ("erase-text-properties", Ferase_text_properties,
1343 Serase_text_properties, 2, 3, 0,
1344 "Remove all properties from the text from START to END.\n\
1345The optional third argument, OBJECT,\n\
1346is the string or buffer containing the text.")
1347 (start, end, object)
1348 Lisp_Object start, end, object;
1349{
1350 register INTERVAL i;
1351 register INTERVAL prev_changed = NULL_INTERVAL;
1352 register int s, len, modified;
1353
1354 if (NILP (object))
1355 XSETBUFFER (object, current_buffer);
1356
1357 i = validate_interval_range (object, &start, &end, soft);
1358 if (NULL_INTERVAL_P (i))
1359 return Qnil;
1360
1361 s = XINT (start);
1362 len = XINT (end) - s;
1363
1364 if (i->position != s)
1365 {
1366 register int got;
1367 register INTERVAL unchanged = i;
1368
1369 /* If there are properties here, then this text will be modified. */
1370 if (! NILP (i->plist))
1371 {
1372 i = split_interval_right (unchanged, s - unchanged->position);
1373 i->plist = Qnil;
1374 modified++;
1375
1376 if (LENGTH (i) > len)
1377 {
1378 i = split_interval_right (i, len);
1379 copy_properties (unchanged, i);
1380 return Qt;
1381 }
1382
1383 if (LENGTH (i) == len)
1384 return Qt;
1385
1386 got = LENGTH (i);
1387 }
1388 /* If the text of I is without any properties, and contains
1389 LEN or more characters, then we may return without changing
1390 anything.*/
1391 else if (LENGTH (i) - (s - i->position) <= len)
1392 return Qnil;
1393 /* The amount of text to change extends past I, so just note
1394 how much we've gotten. */
1395 else
1396 got = LENGTH (i) - (s - i->position);
1397
1398 len -= got;
1399 prev_changed = i;
1400 i = next_interval (i);
1401 }
1402
1403 /* We are starting at the beginning of an interval, I. */
1404 while (len > 0)
1405 {
1406 if (LENGTH (i) >= len)
1407 {
1408 /* If I has no properties, simply merge it if possible. */
1409 if (NILP (i->plist))
1410 {
1411 if (! NULL_INTERVAL_P (prev_changed))
1412 merge_interval_left (i);
1413
1414 return modified ? Qt : Qnil;
1415 }
1416
1417 if (LENGTH (i) > len)
1418 i = split_interval_left (i, len);
1419 if (! NULL_INTERVAL_P (prev_changed))
1420 merge_interval_left (i);
1421 else
1422 i->plist = Qnil;
1423
1424 return Qt;
1425 }
1426
1427 /* Here if we still need to erase past the end of I */
1428 len -= LENGTH (i);
1429 if (NULL_INTERVAL_P (prev_changed))
1430 {
1431 modified += erase_properties (i);
1432 prev_changed = i;
1433 }
1434 else
1435 {
1436 modified += ! NILP (i->plist);
1437 /* Merging I will give it the properties of PREV_CHANGED. */
1438 prev_changed = i = merge_interval_left (i);
1439 }
1440
1441 i = next_interval (i);
1442 }
1443
1444 return modified ? Qt : Qnil;
1445}
1446#endif /* 0 */
1447
1448/* I don't think this is the right interface to export; how often do you 1325/* I don't think this is the right interface to export; how often do you
1449 want to do something like this, other than when you're copying objects 1326 want to do something like this, other than when you're copying objects
1450 around? 1327 around?
@@ -1460,7 +1337,7 @@ is the string or buffer containing the text.")
1460 Return t if any property value actually changed, nil otherwise. */ 1337 Return t if any property value actually changed, nil otherwise. */
1461 1338
1462/* Note this can GC when DEST is a buffer. */ 1339/* Note this can GC when DEST is a buffer. */
1463 1340
1464Lisp_Object 1341Lisp_Object
1465copy_text_properties (start, end, src, pos, dest, prop) 1342copy_text_properties (start, end, src, pos, dest, prop)
1466 Lisp_Object start, end, src, pos, dest, prop; 1343 Lisp_Object start, end, src, pos, dest, prop;