From: Richard M. Stallman Date: Thu, 17 Jul 1997 06:51:28 +0000 (+0000) Subject: (replace_range): New function. X-Git-Tag: emacs-20.1~1116 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=c5ca4d3a1b9bb3165401212fa39621562c5c0e1f;p=emacs.git (replace_range): New function. --- 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. */