summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1997-07-17 06:51:28 +0000
committerRichard M. Stallman <rms@gnu.org>1997-07-17 06:51:28 +0000
commit184b15b09b23cac9dd01fe0fcab2b8d55c9700af (patch)
treed6c0776703817f6b8c84e4bd3e5ea9ccd3840376
parent4ab5983b6028b41ff9c8ea28195e9bb90ae08025 (diff)
downloademacs-184b15b09b23cac9dd01fe0fcab2b8d55c9700af.tar.gz
(replace_range): New function.
-rw-r--r--src/insdel.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 098b1670a4f..73f177c02d2 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -695,6 +695,122 @@ insert_from_string_before_markers (string, pos, length, inherit)
}
}
+/* 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. */