changeset 18830:ac0f5f1912c0

(replace_range): New function.
author Richard M. Stallman <rms@gnu.org>
date Thu, 17 Jul 1997 06:51:28 +0000
parents efc598630ee9
children e6f6c2712a5f
files src/insdel.c
diffstat 1 files changed, 116 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/insdel.c	Thu Jul 17 06:29:36 1997 +0000
+++ b/src/insdel.c	Thu Jul 17 06:51:28 1997 +0000
@@ -695,6 +695,122 @@
     }
 }
 
+/* Replace the text from FROM to TO with NEW,
+   If PREPARE is nonzero, call prepare_to_modify_buffer.
+   If INHERIT, the newly inserted text should inherit text properties
+   from the surrounding non-deleted text.  */
+
+/* Note that this does not yet handle markers quite right.
+   Also it needs to record a single undo-entry that does a replacement
+   rather than a separate delete and insert.
+   That way, undo will also handle markers properly.  */
+
+void
+replace_range (from, to, new, prepare, inherit)
+     Lisp_Object new;
+     int from, to, prepare, inherit;
+{
+  int numdel;
+  int inslen = XSTRING (new)->size;
+  register Lisp_Object temp;
+  struct gcpro gcpro1;
+
+  GCPRO1 (new);
+
+  if (prepare)
+    {
+      int range_length = to - from;
+      prepare_to_modify_buffer (from, to, &from);
+      to = from + range_length;
+    }
+
+  /* Make args be valid */
+  if (from < BEGV)
+    from = BEGV;
+  if (to > ZV)
+    to = ZV;
+
+  UNGCPRO;
+
+  numdel = to - from;
+
+  /* Make sure point-max won't overflow after this insertion.  */
+  XSETINT (temp, Z - numdel + inslen);
+  if (Z - numdel + inslen != XINT (temp))
+    error ("maximum buffer size exceeded");
+
+  if (numdel <= 0 && inslen == 0)
+    return;
+
+  GCPRO1 (new);
+
+  /* Make sure the gap is somewhere in or next to what we are deleting.  */
+  if (from > GPT)
+    gap_right (from);
+  if (to < GPT)
+    gap_left (to, 0);
+
+  /* Relocate all markers pointing into the new, larger gap
+     to point at the end of the text before the gap.
+     This has to be done before recording the deletion,
+     so undo handles this after reinserting the text.  */
+  adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
+
+  record_delete (from, numdel);
+
+  GAP_SIZE += numdel;
+  ZV -= numdel;
+  Z -= numdel;
+  GPT = from;
+  *(GPT_ADDR) = 0;		/* Put an anchor.  */
+
+  if (GPT - BEG < beg_unchanged)
+    beg_unchanged = GPT - BEG;
+  if (Z - GPT < end_unchanged)
+    end_unchanged = Z - GPT;
+
+  if (GAP_SIZE < inslen)
+    make_gap (inslen - GAP_SIZE);
+
+  record_insert (from, inslen);
+
+  bcopy (XSTRING (new)->data, GPT_ADDR, inslen);
+
+  /* Relocate point as if it were a marker.  */
+  if (from < PT)
+    adjust_point (from + inslen - (PT < to ? PT : to));
+
+#ifdef USE_TEXT_PROPERTIES
+  offset_intervals (current_buffer, PT, inslen - numdel);
+#endif
+
+  GAP_SIZE -= inslen;
+  GPT += inslen;
+  ZV += inslen;
+  Z += inslen;
+  if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor.  */
+
+  /* Adjust the overlay center as needed.  This must be done after
+     adjusting the markers that bound the overlays.  */
+  adjust_overlays_for_delete (from, numdel);
+  adjust_overlays_for_insert (from, inslen);
+  adjust_markers_for_insert (from, inslen);
+
+#ifdef USE_TEXT_PROPERTIES
+  /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
+  graft_intervals_into_buffer (XSTRING (new)->intervals, from, inslen,
+			       current_buffer, inherit);
+#endif
+
+  if (inslen == 0)
+    evaporate_overlays (from);
+
+  MODIFF++;
+  UNGCPRO;
+
+  signal_after_change (from, numdel, inslen);
+}
+
 /* Delete characters in current buffer
    from FROM up to (but not including) TO.  */