aboutsummaryrefslogtreecommitdiffstats
path: root/src/textprop.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/textprop.c')
-rw-r--r--src/textprop.c189
1 files changed, 132 insertions, 57 deletions
diff --git a/src/textprop.c b/src/textprop.c
index e3eb3e2ae4c..ab058fa60aa 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -337,7 +337,6 @@ defaults to the current buffer.")
337 Lisp_Object pos, object; 337 Lisp_Object pos, object;
338{ 338{
339 register INTERVAL i; 339 register INTERVAL i;
340 register int p;
341 340
342 if (NILP (object)) 341 if (NILP (object))
343 XSET (object, Lisp_Buffer, current_buffer); 342 XSET (object, Lisp_Buffer, current_buffer);
@@ -349,16 +348,49 @@ defaults to the current buffer.")
349 return i->plist; 348 return i->plist;
350} 349}
351 350
351DEFUN ("get-text-property", Fget_text_property, Sget_text_property, 2, 3, 0,
352 "Return the value of position POS's property PROP, in OBJECT.
353OBJECT is optional and defaults to the current buffer.")
354 (pos, prop, object)
355 Lisp_Object sym, object;
356 register Lisp_Object prop;
357{
358 register INTERVAL i;
359 register Lisp_Object tail;
360
361 if (NILP (object))
362 XSET (object, Lisp_Buffer, current_buffer);
363
364 i = validate_interval_range (object, &pos, &pos, soft);
365 if (NULL_INTERVAL_P (i))
366 return Qnil;
367
368 for (tail = i->plist; !NILP (tail); tail = Fcdr (Fcdr (tail)))
369 {
370 register Lisp_Object tem;
371 tem = Fcar (tail);
372 if (EQ (prop, tem))
373 return Fcar (Fcdr (tail));
374 }
375 return Qnil;
376}
377
352DEFUN ("next-property-change", Fnext_property_change, 378DEFUN ("next-property-change", Fnext_property_change,
353 Snext_property_change, 2, 2, 0, 379 Snext_property_change, 1, 2, 0,
354 "Return the position after POSITION in OBJECT which has properties\n\ 380 "Return the position of next property change.\n\
355different from those at POSITION. OBJECT may be a string or buffer.\n\ 381Scans characters forward from POS in OBJECT till it finds\n\
356Returns nil if unsuccessful.") 382a change in some text property, then returns the position of the change.\n\
383The optional second argument OBJECT is the string or buffer to scan.\n\
384Return nil if the property is constant all the way to the end of OBJECT.\n\
385If the value is non-nil, it is a position greater than POS, never equal.")
357 (pos, object) 386 (pos, object)
358 Lisp_Object pos, object; 387 Lisp_Object pos, object;
359{ 388{
360 register INTERVAL i, next; 389 register INTERVAL i, next;
361 390
391 if (NILP (object))
392 XSET (object, Lisp_Buffer, current_buffer);
393
362 i = validate_interval_range (object, &pos, &pos, soft); 394 i = validate_interval_range (object, &pos, &pos, soft);
363 if (NULL_INTERVAL_P (i)) 395 if (NULL_INTERVAL_P (i))
364 return Qnil; 396 return Qnil;
@@ -374,15 +406,22 @@ Returns nil if unsuccessful.")
374} 406}
375 407
376DEFUN ("next-single-property-change", Fnext_single_property_change, 408DEFUN ("next-single-property-change", Fnext_single_property_change,
377 Snext_single_property_change, 3, 3, 0, 409 Snext_single_property_change, 1, 3, 0,
378 "Return the position after POSITION in OBJECT which has a different\n\ 410 "Return the position of next property change for a specific property.\n\
379value for PROPERTY than the text at POSITION. OBJECT may be a string or\n\ 411Scans characters forward from POS till it finds\n\
380buffer. Returns nil if unsuccessful.") 412a change in the PROP property, then returns the position of the change.\n\
381 (pos, object, prop) 413The optional third argument OBJECT is the string or buffer to scan.\n\
414Return nil if the property is constant all the way to the end of OBJECT.\n\
415If the value is non-nil, it is a position greater than POS, never equal.")
416 (pos, prop, object)
417 Lisp_Object pos, prop, object;
382{ 418{
383 register INTERVAL i, next; 419 register INTERVAL i, next;
384 register Lisp_Object here_val; 420 register Lisp_Object here_val;
385 421
422 if (NILP (object))
423 XSET (object, Lisp_Buffer, current_buffer);
424
386 i = validate_interval_range (object, &pos, &pos, soft); 425 i = validate_interval_range (object, &pos, &pos, soft);
387 if (NULL_INTERVAL_P (i)) 426 if (NULL_INTERVAL_P (i))
388 return Qnil; 427 return Qnil;
@@ -399,15 +438,21 @@ buffer. Returns nil if unsuccessful.")
399} 438}
400 439
401DEFUN ("previous-property-change", Fprevious_property_change, 440DEFUN ("previous-property-change", Fprevious_property_change,
402 Sprevious_property_change, 2, 2, 0, 441 Sprevious_property_change, 1, 2, 0,
403 "Return the position preceding POSITION in OBJECT which has properties\n\ 442 "Return the position of previous property change.\n\
404different from those at POSITION. OBJECT may be a string or buffer.\n\ 443Scans characters backwards from POS in OBJECT till it finds\n\
405Returns nil if unsuccessful.") 444a change in some text property, then returns the position of the change.\n\
445The optional second argument OBJECT is the string or buffer to scan.\n\
446Return nil if the property is constant all the way to the start of OBJECT.\n\
447If the value is non-nil, it is a position less than POS, never equal.")
406 (pos, object) 448 (pos, object)
407 Lisp_Object pos, object; 449 Lisp_Object pos, object;
408{ 450{
409 register INTERVAL i, previous; 451 register INTERVAL i, previous;
410 452
453 if (NILP (object))
454 XSET (object, Lisp_Buffer, current_buffer);
455
411 i = validate_interval_range (object, &pos, &pos, soft); 456 i = validate_interval_range (object, &pos, &pos, soft);
412 if (NULL_INTERVAL_P (i)) 457 if (NULL_INTERVAL_P (i))
413 return Qnil; 458 return Qnil;
@@ -422,15 +467,22 @@ Returns nil if unsuccessful.")
422} 467}
423 468
424DEFUN ("previous-single-property-change", Fprevious_single_property_change, 469DEFUN ("previous-single-property-change", Fprevious_single_property_change,
425 Sprevious_single_property_change, 3, 3, 0, 470 Sprevious_single_property_change, 2, 3, 0,
426 "Return the position preceding POSITION in OBJECT which has a\n\ 471 "Return the position of previous property change for a specific property.\n\
427different value for PROPERTY than the text at POSITION. OBJECT may be\n\ 472Scans characters backward from POS till it finds\n\
428a string or buffer. Returns nil if unsuccessful.") 473a change in the PROP property, then returns the position of the change.\n\
429 (pos, object, prop) 474The optional third argument OBJECT is the string or buffer to scan.\n\
475Return nil if the property is constant all the way to the start of OBJECT.\n\
476If the value is non-nil, it is a position less than POS, never equal.")
477 (pos, prop, object)
478 Lisp_Object pos, prop, object;
430{ 479{
431 register INTERVAL i, previous; 480 register INTERVAL i, previous;
432 register Lisp_Object here_val; 481 register Lisp_Object here_val;
433 482
483 if (NILP (object))
484 XSET (object, Lisp_Buffer, current_buffer);
485
434 i = validate_interval_range (object, &pos, &pos, soft); 486 i = validate_interval_range (object, &pos, &pos, soft);
435 if (NULL_INTERVAL_P (i)) 487 if (NULL_INTERVAL_P (i))
436 return Qnil; 488 return Qnil;
@@ -447,12 +499,15 @@ a string or buffer. Returns nil if unsuccessful.")
447} 499}
448 500
449DEFUN ("add-text-properties", Fadd_text_properties, 501DEFUN ("add-text-properties", Fadd_text_properties,
450 Sadd_text_properties, 4, 4, 0, 502 Sadd_text_properties, 3, 4, 0,
451 "Add the PROPERTIES, a property list, to the text of OBJECT,\n\ 503 "Add properties to the text from START to END.\n\
452a string or buffer, in the range START to END. Returns t if any change\n\ 504The third argument PROPS is a property list\n\
453was made, nil otherwise.") 505specifying the property values to add.\n\
454 (object, start, end, properties) 506The optional fourth argument, OBJECT,\n\
455 Lisp_Object object, start, end, properties; 507is the string or buffer containing the text.\n\
508Return t if any property value actually changed, nil otherwise.")
509 (start, end, properties, object)
510 Lisp_Object start, end, properties, object;
456{ 511{
457 register INTERVAL i, unchanged; 512 register INTERVAL i, unchanged;
458 register int s, len, modified; 513 register int s, len, modified;
@@ -461,6 +516,9 @@ was made, nil otherwise.")
461 if (NILP (properties)) 516 if (NILP (properties))
462 return Qnil; 517 return Qnil;
463 518
519 if (NILP (object))
520 XSET (object, Lisp_Buffer, current_buffer);
521
464 i = validate_interval_range (object, &start, &end, hard); 522 i = validate_interval_range (object, &start, &end, hard);
465 if (NULL_INTERVAL_P (i)) 523 if (NULL_INTERVAL_P (i))
466 return Qnil; 524 return Qnil;
@@ -530,23 +588,25 @@ was made, nil otherwise.")
530} 588}
531 589
532DEFUN ("set-text-properties", Fset_text_properties, 590DEFUN ("set-text-properties", Fset_text_properties,
533 Sset_text_properties, 4, 4, 0, 591 Sset_text_properties, 3, 4, 0,
534 "Make the text of OBJECT, a string or buffer, have precisely\n\ 592 "Completely replace properties of text from START to END.\n\
535PROPERTIES, a list of properties, in the range START to END.\n\ 593The third argument PROPS is the new property list.\n\
536\n\ 594The optional fourth argument, OBJECT,\n\
537If called with a valid property list, return t (text was changed).\n\ 595is the string or buffer containing the text.")
538Otherwise return nil.") 596 (start, end, props, object)
539 (object, start, end, properties) 597 Lisp_Object start, end, props, object;
540 Lisp_Object object, start, end, properties;
541{ 598{
542 register INTERVAL i, unchanged; 599 register INTERVAL i, unchanged;
543 register INTERVAL prev_changed = NULL_INTERVAL; 600 register INTERVAL prev_changed = NULL_INTERVAL;
544 register int s, len; 601 register int s, len;
545 602
546 properties = validate_plist (properties); 603 props = validate_plist (props);
547 if (NILP (properties)) 604 if (NILP (props))
548 return Qnil; 605 return Qnil;
549 606
607 if (NILP (object))
608 XSET (object, Lisp_Buffer, current_buffer);
609
550 i = validate_interval_range (object, &start, &end, hard); 610 i = validate_interval_range (object, &start, &end, hard);
551 if (NULL_INTERVAL_P (i)) 611 if (NULL_INTERVAL_P (i))
552 return Qnil; 612 return Qnil;
@@ -558,7 +618,7 @@ Otherwise return nil.")
558 { 618 {
559 unchanged = i; 619 unchanged = i;
560 i = split_interval_right (unchanged, s - unchanged->position + 1); 620 i = split_interval_right (unchanged, s - unchanged->position + 1);
561 set_properties (properties, i); 621 set_properties (props, i);
562 622
563 if (LENGTH (i) > len) 623 if (LENGTH (i) > len)
564 { 624 {
@@ -584,7 +644,7 @@ Otherwise return nil.")
584 i = split_interval_left (i, len + 1); 644 i = split_interval_left (i, len + 1);
585 645
586 if (NULL_INTERVAL_P (prev_changed)) 646 if (NULL_INTERVAL_P (prev_changed))
587 set_properties (properties, i); 647 set_properties (props, i);
588 else 648 else
589 merge_interval_left (i); 649 merge_interval_left (i);
590 return Qt; 650 return Qt;
@@ -593,7 +653,7 @@ Otherwise return nil.")
593 len -= LENGTH (i); 653 len -= LENGTH (i);
594 if (NULL_INTERVAL_P (prev_changed)) 654 if (NULL_INTERVAL_P (prev_changed))
595 { 655 {
596 set_properties (properties, i); 656 set_properties (props, i);
597 prev_changed = i; 657 prev_changed = i;
598 } 658 }
599 else 659 else
@@ -606,16 +666,23 @@ Otherwise return nil.")
606} 666}
607 667
608DEFUN ("remove-text-properties", Fremove_text_properties, 668DEFUN ("remove-text-properties", Fremove_text_properties,
609 Sremove_text_properties, 4, 4, 0, 669 Sremove_text_properties, 3, 4, 0,
610 "Remove the PROPERTIES, a property list, from the text of OBJECT,\n\ 670 "Remove some properties from text from START to END.\n\
611a string or buffer, in the range START to END. Returns t if any change\n\ 671The third argument PROPS is a property list\n\
612was made, nil otherwise.") 672whose property names specify the properties to remove.\n\
613 (object, start, end, properties) 673\(The values stored in PROPS are ignored.)\n\
614 Lisp_Object object, start, end, properties; 674The optional fourth argument, OBJECT,\n\
675is the string or buffer containing the text.\n\
676Return t if any property was actually removed, nil otherwise.")
677 (start, end, props, object)
678 Lisp_Object start, end, props, object;
615{ 679{
616 register INTERVAL i, unchanged; 680 register INTERVAL i, unchanged;
617 register int s, len, modified; 681 register int s, len, modified;
618 682
683 if (NILP (object))
684 XSET (object, Lisp_Buffer, current_buffer);
685
619 i = validate_interval_range (object, &start, &end, soft); 686 i = validate_interval_range (object, &start, &end, soft);
620 if (NULL_INTERVAL_P (i)) 687 if (NULL_INTERVAL_P (i))
621 return Qnil; 688 return Qnil;
@@ -627,7 +694,7 @@ was made, nil otherwise.")
627 { 694 {
628 /* No properties on this first interval -- return if 695 /* No properties on this first interval -- return if
629 it covers the entire region. */ 696 it covers the entire region. */
630 if (! interval_has_some_properties (properties, i)) 697 if (! interval_has_some_properties (props, i))
631 { 698 {
632 int got = (LENGTH (i) - (s - i->position)); 699 int got = (LENGTH (i) - (s - i->position));
633 if (got >= len) 700 if (got >= len)
@@ -645,11 +712,11 @@ was made, nil otherwise.")
645 { 712 {
646 i = split_interval_left (i, len + 1); 713 i = split_interval_left (i, len + 1);
647 copy_properties (unchanged, i); 714 copy_properties (unchanged, i);
648 remove_properties (properties, i); 715 remove_properties (props, i);
649 return Qt; 716 return Qt;
650 } 717 }
651 718
652 remove_properties (properties, i); 719 remove_properties (props, i);
653 modified = 1; 720 modified = 1;
654 len -= LENGTH (i); 721 len -= LENGTH (i);
655 i = next_interval (i); 722 i = next_interval (i);
@@ -661,39 +728,45 @@ was made, nil otherwise.")
661 { 728 {
662 if (LENGTH (i) >= len) 729 if (LENGTH (i) >= len)
663 { 730 {
664 if (! interval_has_some_properties (properties, i)) 731 if (! interval_has_some_properties (props, i))
665 return modified ? Qt : Qnil; 732 return modified ? Qt : Qnil;
666 733
667 if (LENGTH (i) == len) 734 if (LENGTH (i) == len)
668 { 735 {
669 remove_properties (properties, i); 736 remove_properties (props, i);
670 return Qt; 737 return Qt;
671 } 738 }
672 739
673 /* i has the properties, and goes past the change limit */ 740 /* i has the properties, and goes past the change limit */
674 unchanged = split_interval_right (i, len + 1); 741 unchanged = split_interval_right (i, len + 1);
675 copy_properties (unchanged, i); 742 copy_properties (unchanged, i);
676 remove_properties (properties, i); 743 remove_properties (props, i);
677 return Qt; 744 return Qt;
678 } 745 }
679 746
680 len -= LENGTH (i); 747 len -= LENGTH (i);
681 modified += remove_properties (properties, i); 748 modified += remove_properties (props, i);
682 i = next_interval (i); 749 i = next_interval (i);
683 } 750 }
684} 751}
685 752
753#if 0 /* You can use set-text-properties for this. */
754
686DEFUN ("erase-text-properties", Ferase_text_properties, 755DEFUN ("erase-text-properties", Ferase_text_properties,
687 Serase_text_properties, 3, 3, 0, 756 Serase_text_properties, 2, 3, 0,
688 "Remove all text properties from OBJECT (a string or buffer), in the\n\ 757 "Remove all properties from the text from START to END.\n\
689range START to END. Returns t if any change was made, nil otherwise.") 758The optional third argument, OBJECT,\n\
690 (object, start, end) 759is the string or buffer containing the text.")
691 Lisp_Object object, start, end; 760 (start, end, object)
761 Lisp_Object start, end, object;
692{ 762{
693 register INTERVAL i; 763 register INTERVAL i;
694 register INTERVAL prev_changed = NULL_INTERVAL; 764 register INTERVAL prev_changed = NULL_INTERVAL;
695 register int s, len, modified; 765 register int s, len, modified;
696 766
767 if (NILP (object))
768 XSET (object, Lisp_Buffer, current_buffer);
769
697 i = validate_interval_range (object, &start, &end, soft); 770 i = validate_interval_range (object, &start, &end, soft);
698 if (NULL_INTERVAL_P (i)) 771 if (NULL_INTERVAL_P (i))
699 return Qnil; 772 return Qnil;
@@ -783,6 +856,7 @@ range START to END. Returns t if any change was made, nil otherwise.")
783 856
784 return modified ? Qt : Qnil; 857 return modified ? Qt : Qnil;
785} 858}
859#endif /* 0 */
786 860
787void 861void
788syms_of_textprop () 862syms_of_textprop ()
@@ -823,6 +897,7 @@ percentage by which the left interval tree should not differ from the right.");
823 Qmodification = intern ("modification"); 897 Qmodification = intern ("modification");
824 898
825 defsubr (&Stext_properties_at); 899 defsubr (&Stext_properties_at);
900 defsubr (&Sget_text_property);
826 defsubr (&Snext_property_change); 901 defsubr (&Snext_property_change);
827 defsubr (&Snext_single_property_change); 902 defsubr (&Snext_single_property_change);
828 defsubr (&Sprevious_property_change); 903 defsubr (&Sprevious_property_change);
@@ -830,7 +905,7 @@ percentage by which the left interval tree should not differ from the right.");
830 defsubr (&Sadd_text_properties); 905 defsubr (&Sadd_text_properties);
831 defsubr (&Sset_text_properties); 906 defsubr (&Sset_text_properties);
832 defsubr (&Sremove_text_properties); 907 defsubr (&Sremove_text_properties);
833 defsubr (&Serase_text_properties); 908/* defsubr (&Serase_text_properties); */
834} 909}
835 910
836#else 911#else