X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/ab5796a9f97180707734a81320e3eb81937281fe..03da5d089a8ed035cec443a27259e7d21487a22e:/src/insdel.c diff --git a/src/insdel.c b/src/insdel.c index 88bf1ddd08..fd41603724 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -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 @@ -441,9 +441,13 @@ adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers) } /* Adjusting only markers whose insertion-type is t may result in - disordered overlays in the slot `overlays_before'. */ + - disordered start and end in overlays, and + - disordered overlays in the slot `overlays_before' of current_buffer. */ if (adjusted) - fix_overlays_before (current_buffer, from, to); + { + fix_start_end_in_overlays(from, to); + fix_overlays_before (current_buffer, from, to); + } } /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters. @@ -1053,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); @@ -1070,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); @@ -1460,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); } - + /* 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 @@ -1552,7 +1564,7 @@ replace_range (from, to, new, prepare, inherit, markers) Z_BYTE -= nbytes_del; GPT = from; GPT_BYTE = from_byte; - *(GPT_ADDR) = 0; /* Put an anchor. */ + if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ if (GPT_BYTE < GPT) abort (); @@ -1637,6 +1649,126 @@ replace_range (from, to, new, prepare, inherit, markers) update_compositions (from, GPT, CHECK_BORDER); } +/* 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++; +} + /* Delete characters in current buffer from FROM up to (but not including) TO. If TO comes before FROM, we delete nothing. */ @@ -1835,7 +1967,7 @@ del_range_2 (from, from_byte, to, to_byte, ret_string) Z -= nchars_del; GPT = from; GPT_BYTE = from_byte; - *(GPT_ADDR) = 0; /* Put an anchor. */ + if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ if (GPT_BYTE < GPT) abort (); @@ -2261,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;