* process.c (sigchld_handler): Change type of pid to pid_t.
[bpt/emacs.git] / src / insdel.c
index f5f56f0..7f15f7d 100644 (file)
@@ -1,6 +1,6 @@
 /* Buffer insertion/deletion and gap motion for GNU Emacs.
-   Copyright (C) 1985, 86,93,94,95,97,98, 1999, 2000, 01, 2003
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+                 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 #include <config.h>
@@ -749,9 +749,10 @@ insert (string, nbytes)
 {
   if (nbytes > 0)
     {
-      int opoint = PT;
-      insert_1 (string, nbytes, 0, 1, 0);
-      signal_after_change (opoint, 0, PT - opoint);
+      int len = chars_in_text (string, nbytes), opoint;
+      insert_1_both (string, len, nbytes, 0, 1, 0);
+      opoint = PT - len;
+      signal_after_change (opoint, 0, len);
       update_compositions (opoint, PT, CHECK_BORDER);
     }
 }
@@ -765,9 +766,10 @@ insert_and_inherit (string, nbytes)
 {
   if (nbytes > 0)
     {
-      int opoint = PT;
-      insert_1 (string, nbytes, 1, 1, 0);
-      signal_after_change (opoint, 0, PT - opoint);
+      int len = chars_in_text (string, nbytes), opoint;
+      insert_1_both (string, len, nbytes, 1, 1, 0);
+      opoint = PT - len;
+      signal_after_change (opoint, 0, len);
       update_compositions (opoint, PT, CHECK_BORDER);
     }
 }
@@ -813,10 +815,10 @@ insert_before_markers (string, nbytes)
 {
   if (nbytes > 0)
     {
-      int opoint = PT;
-
-      insert_1 (string, nbytes, 0, 1, 1);
-      signal_after_change (opoint, 0, PT - opoint);
+      int len = chars_in_text (string, nbytes), opoint;
+      insert_1_both (string, len, nbytes, 0, 1, 1);
+      opoint = PT - len;
+      signal_after_change (opoint, 0, len);
       update_compositions (opoint, PT, CHECK_BORDER);
     }
 }
@@ -830,10 +832,10 @@ insert_before_markers_and_inherit (string, nbytes)
 {
   if (nbytes > 0)
     {
-      int opoint = PT;
-
-      insert_1 (string, nbytes, 1, 1, 1);
-      signal_after_change (opoint, 0, PT - opoint);
+      int len = chars_in_text (string, nbytes), opoint;
+      insert_1_both (string, len, nbytes, 1, 1, 1);
+      opoint = PT - len;
+      signal_after_change (opoint, 0, len);
       update_compositions (opoint, PT, CHECK_BORDER);
     }
 }
@@ -1005,6 +1007,7 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
      will add up to the right stuff in the undo list.  */
   record_insert (PT, nchars);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 
   bcopy (string, GPT_ADDR, nbytes);
 
@@ -1057,6 +1060,10 @@ insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
      int inherit;
 {
   int opoint = PT;
+
+  if (SCHARS (string) == 0)
+    return;
+
   insert_from_string_1 (string, pos, pos_byte, length, length_byte,
                        inherit, 0);
   signal_after_change (opoint, 0, PT - opoint);
@@ -1074,6 +1081,10 @@ insert_from_string_before_markers (string, pos, pos_byte,
      int inherit;
 {
   int opoint = PT;
+
+  if (SCHARS (string) == 0)
+    return;
+
   insert_from_string_1 (string, pos, pos_byte, length, length_byte,
                        inherit, 1);
   signal_after_change (opoint, 0, PT - opoint);
@@ -1134,6 +1145,7 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
 
   record_insert (PT, nchars);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 
   GAP_SIZE -= outgoing_nbytes;
   GPT += nchars;
@@ -1285,6 +1297,7 @@ insert_from_buffer_1 (buf, from, nchars, inherit)
 
   record_insert (PT, nchars);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 
   GAP_SIZE -= outgoing_nbytes;
   GPT += nchars;
@@ -1393,6 +1406,7 @@ adjust_after_replace (from, from_byte, prev_text, len, len_byte)
   if (len == 0)
     evaporate_overlays (from);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 }
 
 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
@@ -1443,6 +1457,7 @@ adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del, len, len_b
   if (len == 0)
     evaporate_overlays (from);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 }
 
 /* Record undo information, adjust markers and position keepers for an
@@ -1635,6 +1650,7 @@ replace_range (from, to, new, prepare, inherit, markers)
   CHECK_MARKERS ();
 
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
   UNGCPRO;
 
   signal_after_change (from, nchars_del, GPT - from);
@@ -1737,17 +1753,21 @@ replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers)
 
   /* Adjust markers for the deletion and the insertion.  */
   if (markers
-      && ! (nchars_del == 1 && inschars == 1))
+      && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
     adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
                                inschars, insbytes);
 
   offset_intervals (current_buffer, from, inschars - nchars_del);
 
   /* Relocate point as if it were a marker.  */
-  if (from < PT && nchars_del != inschars)
-    adjust_point ((from + inschars - (PT < to ? PT : to)),
-                 (from_byte + insbytes
-                  - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
+  if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
+    {
+      if (PT < to)
+       /* PT was within the deleted text.  Move it to FROM.  */
+       adjust_point (from - PT, from_byte - PT_BYTE);
+      else
+       adjust_point (inschars - nchars_del, insbytes - nbytes_del);
+    }
 
   if (insbytes == 0)
     evaporate_overlays (from);
@@ -1755,6 +1775,7 @@ replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers)
   CHECK_MARKERS ();
 
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 }
 \f
 /* Delete characters in current buffer
@@ -1936,6 +1957,7 @@ del_range_2 (from, from_byte, to, to_byte, ret_string)
   if (! EQ (current_buffer->undo_list, Qt))
     record_delete (from, deletion);
   MODIFF++;
+  CHARS_MODIFF = MODIFF;
 
   /* Relocate point as if it were a marker.  */
   if (from < PT)
@@ -1976,12 +1998,15 @@ del_range_2 (from, from_byte, to, to_byte, ret_string)
    character positions START to END.  This checks the read-only
    properties of the region, calls the necessary modification hooks,
    and warns the next redisplay that it should pay attention to that
-   area.  */
+   area.
+
+   If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
+   Otherwise set CHARS_MODIFF to the new value of MODIFF.  */
 
 void
-modify_region (buffer, start, end)
+modify_region (buffer, start, end, preserve_chars_modiff)
      struct buffer *buffer;
-     int start, end;
+     int start, end, preserve_chars_modiff;
 {
   struct buffer *old_buffer = current_buffer;
 
@@ -1995,6 +2020,8 @@ modify_region (buffer, start, end)
   if (MODIFF <= SAVE_MODIFF)
     record_first_change ();
   MODIFF++;
+  if (! preserve_chars_modiff)
+    CHARS_MODIFF = MODIFF;
 
   buffer->point_before_scroll = Qnil;
 
@@ -2017,6 +2044,8 @@ prepare_to_modify_buffer (start, end, preserve_ptr)
      int start, end;
      int *preserve_ptr;
 {
+  struct buffer *base_buffer;
+
   if (!NILP (current_buffer->read_only))
     Fbarf_if_buffer_read_only ();
 
@@ -2042,20 +2071,26 @@ prepare_to_modify_buffer (start, end, preserve_ptr)
        verify_interval_modification (current_buffer, start, end);
     }
 
+  /* For indirect buffers, use the base buffer to check clashes.  */
+  if (current_buffer->base_buffer != 0)
+    base_buffer = current_buffer->base_buffer;
+  else
+    base_buffer = current_buffer;
+
 #ifdef CLASH_DETECTION
-  if (!NILP (current_buffer->file_truename)
+  if (!NILP (base_buffer->file_truename)
       /* Make binding buffer-file-name to nil effective.  */
-      && !NILP (current_buffer->filename)
+      && !NILP (base_buffer->filename)
       && SAVE_MODIFF >= MODIFF)
-    lock_file (current_buffer->file_truename);
+    lock_file (base_buffer->file_truename);
 #else
   /* At least warn if this file has changed on disk since it was visited.  */
-  if (!NILP (current_buffer->filename)
+  if (!NILP (base_buffer->filename)
       && SAVE_MODIFF >= MODIFF
       && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
-      && !NILP (Ffile_exists_p (current_buffer->filename)))
+      && !NILP (Ffile_exists_p (base_buffer->filename)))
     call1 (intern ("ask-user-about-supersession-threat"),
-          current_buffer->filename);
+          base_buffer->filename);
 #endif /* not CLASH_DETECTION */
 
   signal_before_change (start, end, preserve_ptr);
@@ -2316,6 +2351,17 @@ DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
   if (NILP (combine_after_change_list))
     return Qnil;
 
+  /* It is rare for combine_after_change_buffer to be invalid, but
+     possible.  It can happen when combine-after-change-calls is
+     non-nil, and insertion calls a file handler (e.g. through
+     lock_file) which scribbles into a temp file -- cyd  */
+  if (!BUFFERP (combine_after_change_buffer)
+      || NILP (XBUFFER (combine_after_change_buffer)->name))
+    {
+      combine_after_change_list = Qnil;
+      return Qnil;
+    }
+
   record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
 
   Fset_buffer (combine_after_change_buffer);
@@ -2381,6 +2427,7 @@ void
 syms_of_insdel ()
 {
   staticpro (&combine_after_change_list);
+  staticpro (&combine_after_change_buffer);
   combine_after_change_list = Qnil;
   combine_after_change_buffer = Qnil;