]> git.eshelyaron.com Git - emacs.git/commitdiff
(set_point): Check for intangible properties on overlays.
authorRichard M. Stallman <rms@gnu.org>
Sun, 15 Dec 1996 04:58:53 +0000 (04:58 +0000)
committerRichard M. Stallman <rms@gnu.org>
Sun, 15 Dec 1996 04:58:53 +0000 (04:58 +0000)
src/intervals.c

index 0cc28ac2751141674e5e8a5ad6df2b4159e387ad..cdfbc5a7e699171073409e7e0982cdef67cfb527 100644 (file)
@@ -1588,8 +1588,10 @@ set_point (position, buffer)
   register INTERVAL to, from, toprev, fromprev, target;
   int buffer_point;
   register Lisp_Object obj;
-  int backwards = (position < BUF_PT (buffer)) ? 1 : 0;
   int old_position = BUF_PT (buffer);
+  int backwards = (position < old_position ? 1 : 0);
+  int have_overlays;
+  int original_position;
 
   buffer->point_before_scroll = Qnil;
 
@@ -1602,9 +1604,13 @@ set_point (position, buffer)
   if (position > BUF_Z (buffer) || position < BUF_BEG (buffer))
     abort ();
 
-  if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
+  have_overlays = (! NILP (buffer->overlays_before)
+                  || ! NILP (buffer->overlays_after));
+
+  /* If we have no text properties and overlays,
+     then we can do it quickly.  */
+  if (NULL_INTERVAL_P (BUF_INTERVALS (buffer)) && ! have_overlays)
     {
-      
       BUF_PT (buffer) = position;
       return;
     }
@@ -1615,7 +1621,7 @@ set_point (position, buffer)
   to = find_interval (BUF_INTERVALS (buffer), position);
   if (position == BUF_BEGV (buffer))
     toprev = 0;
-  else if (to->position == position)
+  else if (to && to->position == position)
     toprev = previous_interval (to);
   else
     toprev = to;
@@ -1631,7 +1637,7 @@ set_point (position, buffer)
   from = find_interval (BUF_INTERVALS (buffer), buffer_point);
   if (buffer_point == BUF_BEGV (buffer))
     fromprev = 0;
-  else if (from->position == BUF_PT (buffer))
+  else if (from && from->position == BUF_PT (buffer))
     fromprev = previous_interval (from);
   else if (buffer_point != BUF_PT (buffer))
     fromprev = from, from = 0;
@@ -1639,64 +1645,71 @@ set_point (position, buffer)
     fromprev = from;
 
   /* Moving within an interval.  */
-  if (to == from && toprev == fromprev && INTERVAL_VISIBLE_P (to))
+  if (to == from && toprev == fromprev && INTERVAL_VISIBLE_P (to)
+      && ! have_overlays)
     {
       BUF_PT (buffer) = position;
       return;
     }
 
+  original_position = position;
+
   /* If the new position is between two intangible characters
      with the same intangible property value,
      move forward or backward until a change in that property.  */
-  if (NILP (Vinhibit_point_motion_hooks) && ! NULL_INTERVAL_P (to)
-      && ! NULL_INTERVAL_P (toprev))
+  if (NILP (Vinhibit_point_motion_hooks)
+      && ((! NULL_INTERVAL_P (to) && ! NULL_INTERVAL_P (toprev))
+         || have_overlays))
     {
+      Lisp_Object intangible_propval;
+      Lisp_Object pos;
+
+      XSETINT (pos, position);
+
       if (backwards)
        {
-         Lisp_Object intangible_propval;
-         intangible_propval = textget (to->plist, Qintangible);
+         intangible_propval = Fget_char_property (make_number (position),
+                                                  Qintangible, Qnil);
 
          /* If following char is intangible,
             skip back over all chars with matching intangible property.  */
          if (! NILP (intangible_propval))
-           while (to == toprev
-                  || ((! NULL_INTERVAL_P (toprev)
-                       && EQ (textget (toprev->plist, Qintangible),
-                              intangible_propval))))
-             {
-               to = toprev;
-               toprev = previous_interval (toprev);
-               if (NULL_INTERVAL_P (toprev))
-                 position = BUF_BEGV (buffer);
-               else
-                 /* This is the only line that's not
-                    dual to the following loop.
-                    That's because we want the position
-                    at the end of TOPREV.  */
-                 position = to->position;
-             }
+           while (XINT (pos) > BUF_BEGV (buffer)
+                  && EQ (Fget_char_property (make_number (XINT (pos) - 1),
+                                             Qintangible, Qnil),
+                         intangible_propval))
+             pos = Fprevious_char_property_change (pos, Qnil);
        }
       else
        {
-         Lisp_Object intangible_propval;
-         intangible_propval = textget (toprev->plist, Qintangible);
+         intangible_propval = Fget_char_property (make_number (position - 1),
+                                                  Qintangible, Qnil);
 
-         /* If previous char is intangible,
-            skip fwd over all chars with matching intangible property.  */
+         /* If following char is intangible,
+            skip back over all chars with matching intangible property.  */
          if (! NILP (intangible_propval))
-           while (to == toprev
-                  || ((! NULL_INTERVAL_P (to)
-                       && EQ (textget (to->plist, Qintangible),
-                              intangible_propval))))
-             {
-               toprev = to;
-               to = next_interval (to);
-               if (NULL_INTERVAL_P (to))
-                 position = BUF_ZV (buffer);
-               else
-                 position = to->position;
-             }
+           while (XINT (pos) < BUF_ZV (buffer)
+                  && EQ (Fget_char_property (pos, Qintangible, Qnil),
+                         intangible_propval))
+             pos = Fnext_char_property_change (pos, Qnil);
+
        }
+
+      position = XINT (pos);
+    }
+
+  if (position != original_position)
+    {
+      /* Set TO to the interval containing the char after POSITION,
+        and TOPREV to the interval containing the char before POSITION.
+        Either one may be null.  They may be equal.  */
+      to = find_interval (BUF_INTERVALS (buffer), position);
+      if (position == BUF_BEGV (buffer))
+       toprev = 0;
+      else if (to && to->position == position)
+       toprev = previous_interval (to);
+      else
+       toprev = to;
     }
 
   /* Here TO is the interval after the stopping point