(mik, pt154): New coding systems.
[bpt/emacs.git] / src / intervals.c
index 1dfc901..09a9bc5 100644 (file)
@@ -45,14 +45,13 @@ Boston, MA 02111-1307, USA.  */
 #include "buffer.h"
 #include "puresize.h"
 #include "keyboard.h"
+#include "keymap.h"
 
 /* Test for membership, allowing for t (actually any non-cons) to mean the
    universal set.  */
 
 #define TMEM(sym, set) (CONSP (set) ? ! NILP (Fmemq (sym, set)) : ! NILP (set))
 
-#define min(x, y) ((x) < (y) ? (x) : (y))
-
 Lisp_Object merge_properties_sticky ();
 static INTERVAL reproduce_tree P_ ((INTERVAL, INTERVAL));
 static INTERVAL reproduce_tree_obj P_ ((INTERVAL, Lisp_Object));
@@ -189,24 +188,47 @@ intervals_equal (i0, i1)
 \f
 
 /* Traverse an interval tree TREE, performing FUNCTION on each node.
+   No guarantee is made about the order of traversal.
    Pass FUNCTION two args: an interval, and ARG.  */
 
 void
-traverse_intervals (tree, position, depth, function, arg)
+traverse_intervals_noorder (tree, function, arg)
      INTERVAL tree;
-     int position, depth;
      void (* function) P_ ((INTERVAL, Lisp_Object));
      Lisp_Object arg;
 {
-  if (NULL_INTERVAL_P (tree))
-    return;
+  /* Minimize stack usage.  */
+  while (!NULL_INTERVAL_P (tree))
+    {
+      (*function) (tree, arg);
+      if (NULL_INTERVAL_P (tree->right))
+       tree = tree->left;
+      else
+       {
+         traverse_intervals_noorder (tree->left, function, arg);
+         tree = tree->right;
+       }
+    }
+}
+
+/* Traverse an interval tree TREE, performing FUNCTION on each node.
+   Pass FUNCTION two args: an interval, and ARG.  */
 
-  traverse_intervals (tree->left, position, depth + 1, function, arg);
-  position += LEFT_TOTAL_LENGTH (tree);
-  tree->position = position;
-  (*function) (tree, arg);
-  position += LENGTH (tree);
-  traverse_intervals (tree->right, position, depth + 1,  function, arg);
+void
+traverse_intervals (tree, position, function, arg)
+     INTERVAL tree;
+     int position;
+     void (* function) P_ ((INTERVAL, Lisp_Object));
+     Lisp_Object arg;
+{
+  while (!NULL_INTERVAL_P (tree))
+    {
+      traverse_intervals (tree->left, position, function, arg);
+      position += LEFT_TOTAL_LENGTH (tree);
+      tree->position = position;
+      (*function) (tree, arg);
+      position += LENGTH (tree); tree = tree->right;
+    }
 }
 \f
 #if 0
@@ -237,7 +259,7 @@ search_for_interval (i, tree)
   icount = 0;
   search_interval = i;
   found_interval = NULL_INTERVAL;
-  traverse_intervals (tree, 1, 0, &check_for_interval, Qnil);
+  traverse_intervals_noorder (tree, &check_for_interval, Qnil);
   return found_interval;
 }
 
@@ -259,7 +281,7 @@ count_intervals (i)
   icount = 0;
   idepth = 0;
   zero_length = 0;
-  traverse_intervals (i, 1, 0, &inc_interval_count, Qnil);
+  traverse_intervals_noorder (i, &inc_interval_count, Qnil);
 
   return icount;
 }
@@ -286,7 +308,7 @@ root_interval (interval)
      c           c
 */
 
-static INTERVAL
+static INLINE INTERVAL
 rotate_right (interval)
      INTERVAL interval;
 {
@@ -332,7 +354,7 @@ rotate_right (interval)
     c               c
 */
 
-static INTERVAL
+static INLINE INTERVAL
 rotate_left (interval)
      INTERVAL interval;
 {
@@ -1113,7 +1135,7 @@ merge_properties_sticky (pleft, pright)
       tmp = Fassq (sym, Vtext_property_default_nonsticky);
       use_left = (lpresent
                  && ! (TMEM (sym, lrear)
-                       || CONSP (tmp) && ! NILP (XCDR (tmp))));
+                       || (CONSP (tmp) && ! NILP (XCDR (tmp)))));
       use_right = (TMEM (sym, rfront)
                   || (CONSP (tmp) && NILP (XCDR (tmp))));
       if (use_left && use_right)
@@ -1658,24 +1680,22 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
 {
   register INTERVAL under, over, this, prev;
   register INTERVAL tree;
-  int middle;
 
   tree = BUF_INTERVALS (buffer);
 
-  /* If the new text has no properties, it becomes part of whatever
-     interval it was inserted into.  */
+  /* If the new text has no properties, then with inheritance it
+     becomes part of whatever interval it was inserted into.
+     To prevent inheritance, we must clear out the properties
+     of the newly inserted text.  */
   if (NULL_INTERVAL_P (source))
     {
       Lisp_Object buf;
-      if (!inherit && ! NULL_INTERVAL_P (tree))
+      if (!inherit && !NULL_INTERVAL_P (tree) && length > 0)
        {
-         int saved_inhibit_modification_hooks = inhibit_modification_hooks;
          XSETBUFFER (buf, buffer);
-         inhibit_modification_hooks = 1;
-         Fset_text_properties (make_number (position),
-                               make_number (position + length),
-                               Qnil, buf);
-         inhibit_modification_hooks = saved_inhibit_modification_hooks;
+         set_text_properties_1 (make_number (position),
+                                make_number (position + length),
+                                Qnil, buf, 0);
        }
       if (! NULL_INTERVAL_P (BUF_INTERVALS (buffer)))
        BUF_INTERVALS (buffer) = balance_an_interval (BUF_INTERVALS (buffer));
@@ -1738,11 +1758,6 @@ graft_intervals_into_buffer (source, position, length, buffer, inherit)
        = split_interval_left (this, position - under->position);
       copy_properties (under, end_unchanged);
       under->position = position;
-#if 0
-      /* This code has no effect.  */
-      prev = 0;
-      middle = 1;
-#endif /* 0 */
     }
   else
     {
@@ -1960,38 +1975,69 @@ set_point_both (buffer, charpos, bytepos)
         or end of the buffer, so don't bother checking in that case.  */
       && charpos != BEGV && charpos != ZV)
     {
-      Lisp_Object intangible_propval;
+      Lisp_Object intangible_propval, invisible_propval;
       Lisp_Object pos;
+      int invis_p;
 
       XSETINT (pos, charpos);
 
       if (backwards)
        {
-         intangible_propval = Fget_char_property (make_number (charpos),
-                                                  Qintangible, Qnil);
+         /* If the preceding char is both invisible and intangible,
+            start backing up from just before that one.  */
+
+         intangible_propval
+           = Fget_char_property (make_number (charpos - 1),
+                                 Qintangible, Qnil);
+         invisible_propval
+           = Fget_char_property (make_number (charpos - 1), Qinvisible, Qnil);
+         invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible_propval);
+
+         if (! NILP (intangible_propval) && invis_p)
+           XSETINT (pos, --charpos);
 
          /* If following char is intangible,
             skip back over all chars with matching intangible property.  */
+
+         intangible_propval = Fget_char_property (pos, Qintangible, Qnil);
+
          if (! NILP (intangible_propval))
-           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);
+           {
+             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
        {
+         /* If preceding char is intangible,
+            skip forward over all chars with matching intangible property.  */
+
          intangible_propval = Fget_char_property (make_number (charpos - 1),
                                                   Qintangible, Qnil);
 
-         /* If following char is intangible,
-            skip forward over all chars with matching intangible property.  */
          if (! NILP (intangible_propval))
-           while (XINT (pos) < BUF_ZV (buffer)
-                  && EQ (Fget_char_property (pos, Qintangible, Qnil),
-                         intangible_propval))
-             pos = Fnext_char_property_change (pos, Qnil);
+           {
+             while (XINT (pos) < BUF_ZV (buffer)
+                    && EQ (Fget_char_property (pos, Qintangible, Qnil),
+                           intangible_propval))
+               pos = Fnext_char_property_change (pos, Qnil);
+
+             /* Is the last one invisible as well as intangible?  */
+
+             invisible_propval
+               = Fget_char_property (make_number (XINT (pos) - 1),
+                                     Qinvisible, Qnil);
+             invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible_propval);
 
+             /* If so, advance one character more:
+                don't stop after an invisible, intangible character.  */
+
+             if (invis_p && XINT (pos) < BUF_ZV (buffer))
+               XSETINT (pos, XINT (pos) + 1);
+           }
        }
 
       charpos = XINT (pos);