avoid recursive `require' when loading semantic
[bpt/emacs.git] / src / insdel.c
index 9f9fcbd..c6d89da 100644 (file)
@@ -701,7 +701,7 @@ count_combining_after (const unsigned char *string,
        (2) POS is the last of the current buffer.
        (3) A character at POS can't be a following byte of multibyte
            character.  */
-  if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
+  if (length > 0 && ASCII_CHAR_P (string[length - 1])) /* case (1) */
     return 0;
   if (pos_byte == Z_BYTE)      /* case (2) */
     return 0;
@@ -1804,6 +1804,9 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
   else
     base_buffer = current_buffer;
 
+  if (inhibit_modification_hooks)
+    return;
+
   if (!NILP (BVAR (base_buffer, file_truename))
       /* Make binding buffer-file-name to nil effective.  */
       && !NILP (BVAR (base_buffer, filename))
@@ -1813,7 +1816,6 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
   /* If `select-active-regions' is non-nil, save the region text.  */
   /* FIXME: Move this to Elisp (via before-change-functions).  */
   if (!NILP (BVAR (current_buffer, mark_active))
-      && !inhibit_modification_hooks
       && XMARKER (BVAR (current_buffer, mark))->buffer
       && NILP (Vsaved_region_selection)
       && (EQ (Vselect_active_regions, Qonly)
@@ -1847,6 +1849,38 @@ invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
      need to consider the caches of their base buffer.  */
   if (buf->base_buffer)
     buf = buf->base_buffer;
+  /* The bidi_paragraph_cache must be invalidated first, because doing
+     so might need to use the newline_cache (via find_newline_no_quit,
+     see below).  */
+  if (buf->bidi_paragraph_cache)
+    {
+      if (start != end
+         && start > BUF_BEG (buf))
+       {
+         /* If we are deleting or replacing characters, we could
+            create a paragraph start, because all of the characters
+            from START to the beginning of START's line are
+            whitespace.  Therefore, we must extend the region to be
+            invalidated up to the newline before START.  */
+         ptrdiff_t line_beg = start;
+         ptrdiff_t start_byte = buf_charpos_to_bytepos (buf, start);
+
+         if (BUF_FETCH_BYTE (buf, start_byte - 1) != '\n')
+           {
+             struct buffer *old = current_buffer;
+
+             set_buffer_internal (buf);
+
+             line_beg = find_newline_no_quit (start, start_byte, -1,
+                                              &start_byte);
+             set_buffer_internal (old);
+           }
+         start = line_beg - (line_beg > BUF_BEG (buf));
+       }
+      invalidate_region_cache (buf,
+                              buf->bidi_paragraph_cache,
+                              start - BUF_BEG (buf), BUF_Z (buf) - end);
+    }
   if (buf->newline_cache)
     invalidate_region_cache (buf,
                              buf->newline_cache,
@@ -1855,10 +1889,6 @@ invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
     invalidate_region_cache (buf,
                              buf->width_run_cache,
                              start - BUF_BEG (buf), BUF_Z (buf) - end);
-  if (buf->bidi_paragraph_cache)
-    invalidate_region_cache (buf,
-                             buf->bidi_paragraph_cache,
-                             start - BUF_BEG (buf), BUF_Z (buf) - end);
 }
 
 /* These macros work with an argument named `preserve_ptr'
@@ -1921,12 +1951,9 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
   Lisp_Object start_marker, end_marker;
   Lisp_Object preserve_marker;
   struct gcpro gcpro1, gcpro2, gcpro3;
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct rvoe_arg rvoe_arg;
 
-  if (inhibit_modification_hooks)
-    return;
-
   start = make_number (start_int);
   end = make_number (end_int);
   preserve_marker = Qnil;
@@ -1937,7 +1964,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
   specbind (Qinhibit_modification_hooks, Qt);
 
   /* If buffer is unmodified, run a special hook for that case.  The
-   check for Vfirst_change_hook is just a minor optimization. */
+   check for Vfirst_change_hook is just a minor optimization.  */
   if (SAVE_MODIFF >= MODIFF
       && !NILP (Vfirst_change_hook))
     {
@@ -1976,14 +2003,10 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
                                   FETCH_START, FETCH_END, Qnil);
     }
 
-  if (! NILP (start_marker))
-    free_marker (start_marker);
-  if (! NILP (end_marker))
-    free_marker (end_marker);
   RESTORE_VALUE;
   UNGCPRO;
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 /* Signal a change immediately after it happens.
@@ -1996,11 +2019,13 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int,
 void
 signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   struct rvoe_arg rvoe_arg;
 
-  if (inhibit_modification_hooks)
+  if (inhibit_modification_hooks) {
+    dynwind_end ();
     return;
+  }
 
   /* If we are deferring calls to the after-change functions
      and there are no before-change functions,
@@ -2021,6 +2046,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
        = Fcons (elt, combine_after_change_list);
       combine_after_change_buffer = Fcurrent_buffer ();
 
+      dynwind_end ();
       return;
     }
 
@@ -2063,7 +2089,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins)
     report_interval_modification (make_number (charpos),
                                  make_number (charpos + lenins));
 
-  unbind_to (count, Qnil);
+  dynwind_end ();
 }
 
 static void
@@ -2077,13 +2103,15 @@ DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
        doc: /* This function is for use internally in the function `combine-after-change-calls'.  */)
   (void)
 {
-  ptrdiff_t count = SPECPDL_INDEX ();
+  dynwind_begin ();
   ptrdiff_t beg, end, change;
   ptrdiff_t begpos, endpos;
   Lisp_Object tail;
 
-  if (NILP (combine_after_change_list))
+  if (NILP (combine_after_change_list)) {
+    dynwind_end ();
     return Qnil;
+  }
 
   /* It is rare for combine_after_change_buffer to be invalid, but
      possible.  It can happen when combine-after-change-calls is
@@ -2093,6 +2121,7 @@ DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
       || !BUFFER_LIVE_P (XBUFFER (combine_after_change_buffer)))
     {
       combine_after_change_list = Qnil;
+      dynwind_end ();
       return Qnil;
     }
 
@@ -2154,12 +2183,15 @@ DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
   signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
   update_compositions (begpos, endpos, CHECK_ALL);
 
-  return unbind_to (count, Qnil);
+  dynwind_end ();
+  return Qnil;
 }
 \f
 void
 syms_of_insdel (void)
 {
+#include "insdel.x"
+
   staticpro (&combine_after_change_list);
   staticpro (&combine_after_change_buffer);
   combine_after_change_list = Qnil;
@@ -2177,6 +2209,4 @@ as well as hooks attached to text properties and overlays.  */);
   DEFSYM (Qinhibit_modification_hooks, "inhibit-modification-hooks");
 
   DEFSYM (Qregion_extract_function, "region-extract-function");
-
-  defsubr (&Scombine_after_change_execute);
 }