]> code.delx.au - gnu-emacs/blobdiff - src/insdel.c
(nnmail-extra-headers): Add defvar.
[gnu-emacs] / src / insdel.c
index ffe7006a45b3e349c7637ce987522c0bba4dd7aa..fd416037241cc46bbb076d1da9d759e7356803f6 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 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>
@@ -1057,6 +1057,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 +1078,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);
@@ -1464,7 +1472,7 @@ adjust_after_insert (from, from_byte, to, to_byte, newlen)
   Z -= len; Z_BYTE -= len_byte;
   adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
 }
-
+\f
 /* Replace the text from character positions FROM to TO with NEW,
    If PREPARE is nonzero, call prepare_to_modify_buffer.
    If INHERIT, the newly inserted text should inherit text properties
@@ -1641,6 +1649,126 @@ replace_range (from, to, new, prepare, inherit, markers)
   update_compositions (from, GPT, CHECK_BORDER);
 }
 \f
+/* Replace the text from character positions FROM to TO with
+   the text in INS of length INSCHARS.
+   Keep the text properties that applied to the old characters
+   (extending them to all the new chars if there are more new chars).
+
+   Note that this does not yet handle markers quite right.
+
+   If MARKERS is nonzero, relocate markers.
+
+   Unlike most functions at this level, never call
+   prepare_to_modify_buffer and never call signal_after_change.  */
+
+void
+replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers)
+     int from, from_byte, to, to_byte;
+     char *ins;
+     int inschars, insbytes, markers;
+{
+  int nbytes_del, nchars_del;
+  Lisp_Object temp;
+
+  CHECK_MARKERS ();
+
+  nchars_del = to - from;
+  nbytes_del = to_byte - from_byte;
+
+  if (nbytes_del <= 0 && insbytes == 0)
+    return;
+
+  /* Make sure point-max won't overflow after this insertion.  */
+  XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
+  if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
+    error ("Maximum buffer size exceeded");
+
+  /* Make sure the gap is somewhere in or next to what we are deleting.  */
+  if (from > GPT)
+    gap_right (from, from_byte);
+  if (to < GPT)
+    gap_left (to, to_byte, 0);
+
+  GAP_SIZE += nbytes_del;
+  ZV -= nchars_del;
+  Z -= nchars_del;
+  ZV_BYTE -= nbytes_del;
+  Z_BYTE -= nbytes_del;
+  GPT = from;
+  GPT_BYTE = from_byte;
+  if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor.  */
+
+  if (GPT_BYTE < GPT)
+    abort ();
+
+  if (GPT - BEG < BEG_UNCHANGED)
+    BEG_UNCHANGED = GPT - BEG;
+  if (Z - GPT < END_UNCHANGED)
+    END_UNCHANGED = Z - GPT;
+
+  if (GAP_SIZE < insbytes)
+    make_gap (insbytes - GAP_SIZE);
+
+  /* Copy the replacement text into the buffer.  */
+  bcopy (ins, GPT_ADDR, insbytes);
+
+#ifdef BYTE_COMBINING_DEBUG
+  /* We have copied text into the gap, but we have not marked
+     it as part of the buffer.  So we can use the old FROM and FROM_BYTE
+     here, for both the previous text and the following text.
+     Meanwhile, GPT_ADDR does point to
+     the text that has been stored by copy_text.  */
+  if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
+      || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
+    abort ();
+#endif
+
+  GAP_SIZE -= insbytes;
+  GPT += inschars;
+  ZV += inschars;
+  Z += inschars;
+  GPT_BYTE += insbytes;
+  ZV_BYTE += insbytes;
+  Z_BYTE += insbytes;
+  if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor.  */
+
+  if (GPT_BYTE < GPT)
+    abort ();
+
+  /* Adjust the overlay center as needed.  This must be done after
+     adjusting the markers that bound the overlays.  */
+  if (nchars_del != inschars)
+    {
+      adjust_overlays_for_insert (from, inschars);
+      adjust_overlays_for_delete (from + inschars, nchars_del);
+    }
+
+  /* Adjust markers for the deletion and the insertion.  */
+  if (markers
+      && ! (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 || 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);
+
+  CHECK_MARKERS ();
+
+  MODIFF++;
+}
+\f
 /* Delete characters in current buffer
    from FROM up to (but not including) TO.
    If TO comes before FROM, we delete nothing.  */
@@ -2265,6 +2393,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;