/[emacs]/emacs/src/textprop.c
ViewVC logotype

Diff of /emacs/src/textprop.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.124 by miles, Thu Mar 14 08:10:35 2002 UTC revision 1.125 by rms, Fri Apr 19 00:14:14 2002 UTC
# Line 268  interval_has_some_properties (plist, i) Line 268  interval_has_some_properties (plist, i)
268    
269    return 0;    return 0;
270  }  }
271    
272    /* Return nonzero if the plist of interval I has any of the
273       property names in LIST, regardless of their values.  */
274    
275    static INLINE int
276    interval_has_some_properties_list (list, i)
277         Lisp_Object list;
278         INTERVAL i;
279    {
280      register Lisp_Object tail1, tail2, sym;
281    
282      /* Go through each element of LIST.  */
283      for (tail1 = list; ! NILP (tail1); tail1 = XCDR (tail1))
284        {
285          sym = Fcar (tail1);
286    
287          /* Go through i's plist, looking for tail1 */
288          for (tail2 = i->plist; ! NILP (tail2); tail2 = XCDR (XCDR (tail2)))
289            if (EQ (sym, XCAR (tail2)))
290              return 1;
291        }
292    
293      return 0;
294    }
295    
296  /* Changing the plists of individual intervals.  */  /* Changing the plists of individual intervals.  */
297    
# Line 414  add_properties (plist, i, object) Line 438  add_properties (plist, i, object)
438    return changed;    return changed;
439  }  }
440    
441  /* For any members of PLIST which are properties of I, remove them  /* For any members of PLIST, or LIST,
442     from I's plist.     which are properties of I, remove them from I's plist.
443       (If PLIST is non-nil, use that, otherwise use LIST.)
444     OBJECT is the string or buffer containing I.  */     OBJECT is the string or buffer containing I.  */
445    
446  static int  static int
447  remove_properties (plist, i, object)  remove_properties (plist, list, i, object)
448       Lisp_Object plist;       Lisp_Object plist, list;
449       INTERVAL i;       INTERVAL i;
450       Lisp_Object object;       Lisp_Object object;
451  {  {
452    register Lisp_Object tail1, tail2, sym, current_plist;    register Lisp_Object tail1, tail2, sym, current_plist;
453    register int changed = 0;    register int changed = 0;
454    
455      /* Nonzero means tail1 is a list, otherwise it is a plist.  */
456      int use_list;
457    
458    current_plist = i->plist;    current_plist = i->plist;
459    /* Go through each element of plist.  */  
460    for (tail1 = plist; ! NILP (tail1); tail1 = Fcdr (Fcdr (tail1)))    if (! NILP (plist))
461        tail1 = plist, use_list = 0;
462      else
463        tail1 = list, use_list = 1;
464    
465      /* Go through each element of LIST or PLIST.  */
466      while (! NILP (tail1))
467      {      {
468        sym = Fcar (tail1);        sym = XCAR (tail1);
469    
470        /* First, remove the symbol if its at the head of the list */        /* First, remove the symbol if it's at the head of the list */
471        while (! NILP (current_plist) && EQ (sym, Fcar (current_plist)))        while (! NILP (current_plist) && EQ (sym, XCAR (current_plist)))
472          {          {
473            if (BUFFERP (object))            if (BUFFERP (object))
474              {              record_property_change (i->position, LENGTH (i),
475                record_property_change (i->position, LENGTH (i),                                      sym, XCAR (XCDR (current_plist)),
476                                        sym, Fcar (Fcdr (current_plist)),                                      object);
                                       object);  
             }  
477    
478            current_plist = Fcdr (Fcdr (current_plist));            current_plist = XCDR (XCDR (current_plist));
479            changed++;            changed++;
480          }          }
481    
482        /* Go through i's plist, looking for sym */        /* Go through I's plist, looking for SYM.  */
483        tail2 = current_plist;        tail2 = current_plist;
484        while (! NILP (tail2))        while (! NILP (tail2))
485          {          {
486            register Lisp_Object this;            register Lisp_Object this;
487            this = Fcdr (Fcdr (tail2));            this = XCDR (XCDR (tail2));
488            if (EQ (sym, Fcar (this)))            if (EQ (sym, XCAR (this)))
489              {              {
490                if (BUFFERP (object))                if (BUFFERP (object))
491                  {                  record_property_change (i->position, LENGTH (i),
492                    record_property_change (i->position, LENGTH (i),                                          sym, XCAR (XCDR (this)), object);
                                           sym, Fcar (Fcdr (this)), object);  
                 }  
493    
494                Fsetcdr (Fcdr (tail2), Fcdr (Fcdr (this)));                Fsetcdr (XCDR (tail2), XCDR (XCDR (this)));
495                changed++;                changed++;
496              }              }
497            tail2 = this;            tail2 = this;
498          }          }
499    
500          /* Advance thru TAIL1 one way or the other.  */
501          if (use_list)
502            tail1 = XCDR (tail1);
503          else
504            tail1 = XCDR (XCDR (tail1));
505      }      }
506    
507    if (changed)    if (changed)
# Line 1459  Return t if any property was actually re Line 1495  Return t if any property was actually re
1495    
1496            if (LENGTH (i) == len)            if (LENGTH (i) == len)
1497              {              {
1498                remove_properties (properties, i, object);                remove_properties (properties, Qnil, i, object);
1499                  if (BUFFERP (object))
1500                    signal_after_change (XINT (start), XINT (end) - XINT (start),
1501                                         XINT (end) - XINT (start));
1502                  return Qt;
1503                }
1504    
1505              /* i has the properties, and goes past the change limit */
1506              unchanged = i;
1507              i = split_interval_left (i, len);
1508              copy_properties (unchanged, i);
1509              remove_properties (properties, Qnil, i, object);
1510              if (BUFFERP (object))
1511                signal_after_change (XINT (start), XINT (end) - XINT (start),
1512                                     XINT (end) - XINT (start));
1513              return Qt;
1514            }
1515    
1516          len -= LENGTH (i);
1517          modified += remove_properties (properties, Qnil, i, object);
1518          i = next_interval (i);
1519        }
1520    }
1521    
1522    DEFUN ("remove-list-of-text-properties", Fremove_list_of_text_properties,
1523           Sremove_list_of_text_properties, 3, 4, 0,
1524           doc: /* Remove some properties from text from START to END.
1525    The third argument LIST-OF-PROPERTIES is a list of property names to remove.
1526    The optional fourth argument, OBJECT,
1527    is the string or buffer containing the text, defaulting to the current buffer.
1528    Return t if any property was actually removed, nil otherwise.  */)
1529         (start, end, list_of_properties, object)
1530         Lisp_Object start, end, list_of_properties, object;
1531    {
1532      register INTERVAL i, unchanged;
1533      register int s, len, modified = 0;
1534      Lisp_Object properties;
1535      properties = list_of_properties;
1536    
1537      if (NILP (object))
1538        XSETBUFFER (object, current_buffer);
1539    
1540      i = validate_interval_range (object, &start, &end, soft);
1541      if (NULL_INTERVAL_P (i))
1542        return Qnil;
1543    
1544      s = XINT (start);
1545      len = XINT (end) - s;
1546    
1547      if (i->position != s)
1548        {
1549          /* No properties on this first interval -- return if
1550             it covers the entire region.  */
1551          if (! interval_has_some_properties_list (properties, i))
1552            {
1553              int got = (LENGTH (i) - (s - i->position));
1554              if (got >= len)
1555                return Qnil;
1556              len -= got;
1557              i = next_interval (i);
1558            }
1559          /* Split away the beginning of this interval; what we don't
1560             want to modify.  */
1561          else
1562            {
1563              unchanged = i;
1564              i = split_interval_right (unchanged, s - unchanged->position);
1565              copy_properties (unchanged, i);
1566            }
1567        }
1568    
1569      if (BUFFERP (object))
1570        modify_region (XBUFFER (object), XINT (start), XINT (end));
1571    
1572      /* We are at the beginning of an interval, with len to scan */
1573      for (;;)
1574        {
1575          if (i == 0)
1576            abort ();
1577    
1578          if (LENGTH (i) >= len)
1579            {
1580              if (! interval_has_some_properties_list (properties, i))
1581                return modified ? Qt : Qnil;
1582    
1583              if (LENGTH (i) == len)
1584                {
1585                  remove_properties (Qnil, properties, i, object);
1586                if (BUFFERP (object))                if (BUFFERP (object))
1587                  signal_after_change (XINT (start), XINT (end) - XINT (start),                  signal_after_change (XINT (start), XINT (end) - XINT (start),
1588                                       XINT (end) - XINT (start));                                       XINT (end) - XINT (start));
# Line 1470  Return t if any property was actually re Line 1593  Return t if any property was actually re
1593            unchanged = i;            unchanged = i;
1594            i = split_interval_left (i, len);            i = split_interval_left (i, len);
1595            copy_properties (unchanged, i);            copy_properties (unchanged, i);
1596            remove_properties (properties, i, object);            remove_properties (Qnil, properties, i, object);
1597            if (BUFFERP (object))            if (BUFFERP (object))
1598              signal_after_change (XINT (start), XINT (end) - XINT (start),              signal_after_change (XINT (start), XINT (end) - XINT (start),
1599                                   XINT (end) - XINT (start));                                   XINT (end) - XINT (start));
# Line 1478  Return t if any property was actually re Line 1601  Return t if any property was actually re
1601          }          }
1602    
1603        len -= LENGTH (i);        len -= LENGTH (i);
1604        modified += remove_properties (properties, i, object);        modified += remove_properties (Qnil, properties, i, object);
1605        i = next_interval (i);        i = next_interval (i);
1606      }      }
1607  }  }
# Line 2132  rear-nonsticky properties of the charact Line 2255  rear-nonsticky properties of the charact
2255    defsubr (&Sput_text_property);    defsubr (&Sput_text_property);
2256    defsubr (&Sset_text_properties);    defsubr (&Sset_text_properties);
2257    defsubr (&Sremove_text_properties);    defsubr (&Sremove_text_properties);
2258      defsubr (&Sremove_list_of_text_properties);
2259    defsubr (&Stext_property_any);    defsubr (&Stext_property_any);
2260    defsubr (&Stext_property_not_all);    defsubr (&Stext_property_not_all);
2261  /*  defsubr (&Serase_text_properties); */  /*  defsubr (&Serase_text_properties); */

Legend:
Removed from v.1.124  
changed lines
  Added in v.1.125

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26