X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/307d0e95ee9da988333c9d373b9955300bbaa340..3521bd09b3c11b68c009d290efb4350289f2d3e6:/src/insdel.c diff --git a/src/insdel.c b/src/insdel.c index c0afa80d5e..58c3e15c23 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -771,8 +771,13 @@ count_combining_after (const unsigned char *string, /* Insert a sequence of NCHARS chars which occupy NBYTES bytes - starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS - are the same as in insert_1. */ + starting at STRING. INHERIT non-zero means inherit the text + properties from neighboring characters; zero means inserted text + will have no text properties. PREPARE non-zero means call + prepare_to_modify_buffer, which checks that the region is not + read-only, and calls before-change-function and any modification + properties the text may have. BEFORE_MARKERS non-zero means adjust + all markers that point at the insertion place to point after it. */ void insert_1_both (const char *string, @@ -977,11 +982,15 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte, } /* Insert a sequence of NCHARS chars which occupy NBYTES bytes - starting at GPT_ADDR. */ + starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at + GPT_ADDR (if not text_at_gap_tail). */ void -insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes) +insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail) { + int ins_charpos = GPT; + int ins_bytepos = GPT_BYTE; + if (NILP (BVAR (current_buffer, enable_multibyte_characters))) nchars = nbytes; @@ -989,28 +998,31 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes) MODIFF++; GAP_SIZE -= nbytes; - GPT += nchars; + if (! text_at_gap_tail) + { + GPT += nchars; + GPT_BYTE += nbytes; + } ZV += nchars; Z += nchars; - GPT_BYTE += nbytes; ZV_BYTE += nbytes; Z_BYTE += nbytes; if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ eassert (GPT <= GPT_BYTE); - adjust_overlays_for_insert (GPT - nchars, nchars); - adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes, - GPT, GPT_BYTE, 0); + adjust_overlays_for_insert (ins_charpos, nchars); + adjust_markers_for_insert (ins_charpos, ins_bytepos, + ins_charpos + nchars, ins_bytepos + nbytes, 0); if (buffer_intervals (current_buffer)) { - offset_intervals (current_buffer, GPT - nchars, nchars); - graft_intervals_into_buffer (NULL, GPT - nchars, nchars, + offset_intervals (current_buffer, ins_charpos, nchars); + graft_intervals_into_buffer (NULL, ins_charpos, nchars, current_buffer, 0); } - if (GPT - nchars < PT) + if (ins_charpos < PT) adjust_point (nchars, nbytes); check_markers (); @@ -1162,16 +1174,14 @@ insert_from_buffer_1 (struct buffer *buf, /* Record undo information and adjust markers and position keepers for a replacement of a text PREV_TEXT at FROM to a new text of LEN - chars (LEN_BYTE bytes). If TEXT_AT_GAP_TAIL, the new text - resides at the gap tail; i.e. at (GAP_END_ADDR - LEN_BYTE) - Otherwise, the text resides in the gap just after GPT_BYTE. + chars (LEN_BYTE bytes) which resides in the gap just after + GPT_ADDR. PREV_TEXT nil means the new text was just inserted. */ -void +static void adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, - Lisp_Object prev_text, ptrdiff_t len, ptrdiff_t len_byte, - bool text_at_gap_tail) + Lisp_Object prev_text, ptrdiff_t len, ptrdiff_t len_byte) { ptrdiff_t nchars_del = 0, nbytes_del = 0; @@ -1191,11 +1201,8 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, GAP_SIZE -= len_byte; ZV += len; Z+= len; ZV_BYTE += len_byte; Z_BYTE += len_byte; - if (! text_at_gap_tail) - { - GPT += len; GPT_BYTE += len_byte; - if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ - } + GPT += len; GPT_BYTE += len_byte; + if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ if (nchars_del > 0) adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del, @@ -1204,12 +1211,9 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte, adjust_markers_for_insert (from, from_byte, from + len, from_byte + len_byte, 0); - if (! EQ (BVAR (current_buffer, undo_list), Qt)) - { - if (nchars_del > 0) - record_delete (from, prev_text); - record_insert (from, len); - } + if (nchars_del > 0) + record_delete (from, prev_text); + record_insert (from, len); if (len > nchars_del) adjust_overlays_for_insert (from, len - nchars_del); @@ -1250,7 +1254,7 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, GPT -= len; GPT_BYTE -= len_byte; ZV -= len; ZV_BYTE -= len_byte; Z -= len; Z_BYTE -= len_byte; - adjust_after_replace (from, from_byte, Qnil, newlen, len_byte, 0); + adjust_after_replace (from, from_byte, Qnil, newlen, len_byte); } /* Replace the text from character positions FROM to TO with NEW, @@ -1366,12 +1370,12 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, emacs_abort (); #endif - if (! EQ (BVAR (current_buffer, undo_list), Qt)) + /* Record the insertion first, so that when we undo, + the deletion will be undone first. Thus, undo + will insert before deleting, and thus will keep + the markers before and after this text separate. */ + if (!NILP (deletion)) { - /* Record the insertion first, so that when we undo, - the deletion will be undone first. Thus, undo - will insert before deleting, and thus will keep - the markers before and after this text separate. */ record_insert (from + SCHARS (deletion), inschars); record_delete (from, deletion); } @@ -1711,8 +1715,7 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte, so that undo handles this after reinserting the text. */ adjust_markers_for_delete (from, from_byte, to, to_byte); - if (! EQ (BVAR (current_buffer, undo_list), Qt)) - record_delete (from, deletion); + record_delete (from, deletion); MODIFF++; CHARS_MODIFF = MODIFF; @@ -1799,7 +1802,7 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, /* If we're modifying the buffer other than shown in a selected window, let redisplay consider other windows if this buffer is visible. */ - if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer + if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer && buffer_window_count (current_buffer)) ++windows_or_buffers_changed; @@ -1906,12 +1909,18 @@ prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end, VARIABLE is the variable to maybe set to nil. NO-ERROR-FLAG is nil if there was an error, anything else meaning no error (so this function does nothing). */ -static Lisp_Object -reset_var_on_error (Lisp_Object val) +struct rvoe_arg { - if (NILP (XCDR (val))) - Fset (XCAR (val), Qnil); - return Qnil; + Lisp_Object *location; + bool errorp; +}; + +static void +reset_var_on_error (void *ptr) +{ + struct rvoe_arg *p = ptr; + if (p->errorp) + *p->location = Qnil; } /* Signal a change to the buffer immediately before it happens. @@ -1929,6 +1938,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, Lisp_Object preserve_marker; struct gcpro gcpro1, gcpro2, gcpro3; ptrdiff_t count = SPECPDL_INDEX (); + struct rvoe_arg rvoe_arg; if (inhibit_modification_hooks) return; @@ -1956,13 +1966,14 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, if (!NILP (Vbefore_change_functions)) { Lisp_Object args[3]; - Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil); + rvoe_arg.location = &Vbefore_change_functions; + rvoe_arg.errorp = 1; PRESERVE_VALUE; PRESERVE_START_END; /* Mark before-change-functions to be reset to nil in case of error. */ - record_unwind_protect (reset_var_on_error, rvoe_arg); + record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg); /* Actually run the hook functions. */ args[0] = Qbefore_change_functions; @@ -1971,7 +1982,7 @@ signal_before_change (ptrdiff_t start_int, ptrdiff_t end_int, Frun_hook_with_args (3, args); /* There was no error: unarm the reset_on_error. */ - XSETCDR (rvoe_arg, Qt); + rvoe_arg.errorp = 0; } if (buffer_has_overlays ()) @@ -2002,6 +2013,8 @@ void signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) { ptrdiff_t count = SPECPDL_INDEX (); + struct rvoe_arg rvoe_arg; + if (inhibit_modification_hooks) return; @@ -2035,10 +2048,11 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) if (!NILP (Vafter_change_functions)) { Lisp_Object args[4]; - Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil); + rvoe_arg.location = &Vafter_change_functions; + rvoe_arg.errorp = 1; /* Mark after-change-functions to be reset to nil in case of error. */ - record_unwind_protect (reset_var_on_error, rvoe_arg); + record_unwind_protect_ptr (reset_var_on_error, &rvoe_arg); /* Actually run the hook functions. */ args[0] = Qafter_change_functions; @@ -2048,7 +2062,7 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) Frun_hook_with_args (4, args); /* There was no error: unarm the reset_on_error. */ - XSETCDR (rvoe_arg, Qt); + rvoe_arg.errorp = 0; } if (buffer_has_overlays ()) @@ -2068,11 +2082,10 @@ signal_after_change (ptrdiff_t charpos, ptrdiff_t lendel, ptrdiff_t lenins) unbind_to (count, Qnil); } -static Lisp_Object +static void Fcombine_after_change_execute_1 (Lisp_Object val) { Vcombine_after_change_calls = val; - return val; } DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,