From 3e1451520bdae2a79247347e66724306692533f6 Mon Sep 17 00:00:00 2001 From: Chong Yidong Date: Fri, 1 Sep 2006 13:28:13 +0000 Subject: [PATCH] * buffer.h (struct buffer_text): New field chars_modiff. (CHARS_MODIFF, BUF_CHARS_MODIFF): New macros. * buffer.c (Fbuffer_chars_modified_tick): New function returning value of BUF_CHARS_MODIFF. (syms_of_buffer): Defsubr it. (Fget_buffer_create): Initialize BUF_CHARS_MODIFF. * insdel.c (modify_region): New argument preserve_chars_modiff. Set CHARS_MODIFF to MODIFF provided preserve_chars_modiff is zero. (insert_1_both, insert_from_string_1, insert_from_buffer_1) (adjust_after_replace, adjust_after_replace_noundo) (replace_range, replace_range_2, del_range_2): Reset CHARS_MODIFF. * lisp.h (modify_region): Add fourth argument in extern. * casefiddle.c (casify_region): Call modify_region with fourth argument zero to assert that CHARS_MODIFF is updated. * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) (Ftranspose_regions): Likewise. * textprop.c (Fadd_text_properties, Fset_text_properties) (Fremove_text_properties, Fremove_list_of_text_properties): Call modify_region with fourth argument 1 to avoid that CHARS_MODIFF is updated. --- src/ChangeLog | 23 +++++++++++++++++++++++ src/buffer.c | 27 +++++++++++++++++++++++++++ src/buffer.h | 10 ++++++++++ src/casefiddle.c | 2 +- src/editfns.c | 14 +++++++------- src/insdel.c | 19 ++++++++++++++++--- src/lisp.h | 2 +- src/textprop.c | 12 ++++++------ 8 files changed, 91 insertions(+), 18 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index f0f8ebf9d7..f2395388d0 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,26 @@ +2006-08-03 Martin Rudalics + + * buffer.h (struct buffer_text): New field chars_modiff. + (CHARS_MODIFF, BUF_CHARS_MODIFF): New macros. + * buffer.c (Fbuffer_chars_modified_tick): New function returning + value of BUF_CHARS_MODIFF. + (syms_of_buffer): Defsubr it. + (Fget_buffer_create): Initialize BUF_CHARS_MODIFF. + * insdel.c (modify_region): New argument preserve_chars_modiff. + Set CHARS_MODIFF to MODIFF provided preserve_chars_modiff is zero. + (insert_1_both, insert_from_string_1, insert_from_buffer_1) + (adjust_after_replace, adjust_after_replace_noundo) + (replace_range, replace_range_2, del_range_2): Reset CHARS_MODIFF. + * lisp.h (modify_region): Add fourth argument in extern. + * casefiddle.c (casify_region): Call modify_region with fourth + argument zero to assert that CHARS_MODIFF is updated. + * editfns.c (Fsubst_char_in_region, Ftranslate_region_internal) + (Ftranspose_regions): Likewise. + * textprop.c (Fadd_text_properties, Fset_text_properties) + (Fremove_text_properties, Fremove_list_of_text_properties): + Call modify_region with fourth argument 1 to avoid that + CHARS_MODIFF is updated. + 2006-08-31 Richard Stallman * editfns.c (Fformat): Don't sign-extend for %o or %x. diff --git a/src/buffer.c b/src/buffer.c index 863b217d2b..58c047a87b 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -374,6 +374,7 @@ The value is never nil. */) BUF_ZV_BYTE (b) = BEG_BYTE; BUF_Z_BYTE (b) = BEG_BYTE; BUF_MODIFF (b) = 1; + BUF_CHARS_MODIFF (b) = 1; BUF_OVERLAY_MODIFF (b) = 1; BUF_SAVE_MODIFF (b) = 1; BUF_INTERVALS (b) = 0; @@ -1148,6 +1149,31 @@ No argument or nil as argument means use current buffer as BUFFER. */) return make_number (BUF_MODIFF (buf)); } + +DEFUN ("buffer-chars-modified-tick", Fbuffer_chars_modified_tick, + Sbuffer_chars_modified_tick, 0, 1, 0, + doc: /* Return BUFFER's character-change tick counter. +Each buffer has a character-change tick counter, which is set to the +value of the buffer's tick counter \(see `buffer-modified-tick'), each +time text in that buffer is inserted or deleted. By comparing the +values returned by two individual calls of buffer-chars-modified-tick, +you can tell whether a character change occurred in that buffer in +between these calls. No argument or nil as argument means use current +buffer as BUFFER. */) + (buffer) + register Lisp_Object buffer; +{ + register struct buffer *buf; + if (NILP (buffer)) + buf = current_buffer; + else + { + CHECK_BUFFER (buffer); + buf = XBUFFER (buffer); + } + + return make_number (BUF_CHARS_MODIFF (buf)); +} DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2, "sRename buffer (to new name): \nP", @@ -6044,6 +6070,7 @@ The function `kill-all-local-variables' runs this before doing anything else. * defsubr (&Sbuffer_modified_p); defsubr (&Sset_buffer_modified_p); defsubr (&Sbuffer_modified_tick); + defsubr (&Sbuffer_chars_modified_tick); defsubr (&Srename_buffer); defsubr (&Sother_buffer); defsubr (&Sbuffer_enable_undo); diff --git a/src/buffer.h b/src/buffer.h index efe0252453..a5f8a6a407 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -82,6 +82,9 @@ Boston, MA 02110-1301, USA. */ /* Modification count. */ #define MODIFF (current_buffer->text->modiff) +/* Character modification count. */ +#define CHARS_MODIFF (current_buffer->text->chars_modiff) + /* Overlay modification count. */ #define OVERLAY_MODIFF (current_buffer->text->overlay_modiff) @@ -147,6 +150,9 @@ Boston, MA 02110-1301, USA. */ /* Modification count. */ #define BUF_MODIFF(buf) ((buf)->text->modiff) +/* Character modification count. */ +#define BUF_CHARS_MODIFF(buf) ((buf)->text->chars_modiff) + /* Modification count as of last visit or save. */ #define BUF_SAVE_MODIFF(buf) ((buf)->text->save_modiff) @@ -406,6 +412,10 @@ struct buffer_text for this buffer. It is incremented for each such event, and never otherwise changed. */ + int chars_modiff; /* This is modified with character change + events for this buffer. It is set to + modiff for each such event, and never + otherwise changed. */ int save_modiff; /* Previous value of modiff, as of last time buffer visited or saved a file. */ diff --git a/src/casefiddle.c b/src/casefiddle.c index 0ad884310e..cb7c953a3e 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -187,7 +187,7 @@ casify_region (flag, b, e) validate_region (&b, &e); start = XFASTINT (b); end = XFASTINT (e); - modify_region (current_buffer, start, end); + modify_region (current_buffer, start, end, 0); record_change (start, end - start); start_byte = CHAR_TO_BYTE (start); end_byte = CHAR_TO_BYTE (end); diff --git a/src/editfns.c b/src/editfns.c index e916b505fe..2c392df564 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2781,7 +2781,7 @@ Both characters must have the same length of multi-byte form. */) else if (!changed) { changed = -1; - modify_region (current_buffer, pos, XINT (end)); + modify_region (current_buffer, pos, XINT (end), 0); if (! NILP (noundo)) { @@ -2897,7 +2897,7 @@ It returns the number of characters changed. */) pos = XINT (start); pos_byte = CHAR_TO_BYTE (pos); end_pos = XINT (end); - modify_region (current_buffer, pos, XINT (end)); + modify_region (current_buffer, pos, XINT (end), 0); cnt = 0; for (; pos < end_pos; ) @@ -4168,7 +4168,7 @@ Transposing beyond buffer boundaries is an error. */) if (end1 == start2) /* adjacent regions */ { - modify_region (current_buffer, start1, end2); + modify_region (current_buffer, start1, end2, 0); record_change (start1, len1 + len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4224,8 +4224,8 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region (current_buffer, start1, end1); - modify_region (current_buffer, start2, end2); + modify_region (current_buffer, start1, end1, 0); + modify_region (current_buffer, start2, end2, 0); record_change (start1, len1); record_change (start2, len2); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4254,7 +4254,7 @@ Transposing beyond buffer boundaries is an error. */) { USE_SAFE_ALLOCA; - modify_region (current_buffer, start1, end2); + modify_region (current_buffer, start1, end2, 0); record_change (start1, (end2 - start1)); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); @@ -4285,7 +4285,7 @@ Transposing beyond buffer boundaries is an error. */) USE_SAFE_ALLOCA; record_change (start1, (end2 - start1)); - modify_region (current_buffer, start1, end2); + modify_region (current_buffer, start1, end2, 0); tmp_interval1 = copy_intervals (cur_intv, start1, len1); tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); diff --git a/src/insdel.c b/src/insdel.c index b97539c1cc..bd6e30d944 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1007,6 +1007,7 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers) will add up to the right stuff in the undo list. */ record_insert (PT, nchars); MODIFF++; + CHARS_MODIFF = MODIFF; bcopy (string, GPT_ADDR, nbytes); @@ -1144,6 +1145,7 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes, record_insert (PT, nchars); MODIFF++; + CHARS_MODIFF = MODIFF; GAP_SIZE -= outgoing_nbytes; GPT += nchars; @@ -1295,6 +1297,7 @@ insert_from_buffer_1 (buf, from, nchars, inherit) record_insert (PT, nchars); MODIFF++; + CHARS_MODIFF = MODIFF; GAP_SIZE -= outgoing_nbytes; GPT += nchars; @@ -1403,6 +1406,7 @@ adjust_after_replace (from, from_byte, prev_text, len, len_byte) if (len == 0) evaporate_overlays (from); MODIFF++; + CHARS_MODIFF = MODIFF; } /* Like adjust_after_replace, but doesn't require PREV_TEXT. @@ -1453,6 +1457,7 @@ adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del, len, len_b if (len == 0) evaporate_overlays (from); MODIFF++; + CHARS_MODIFF = MODIFF; } /* Record undo information, adjust markers and position keepers for an @@ -1645,6 +1650,7 @@ replace_range (from, to, new, prepare, inherit, markers) CHECK_MARKERS (); MODIFF++; + CHARS_MODIFF = MODIFF; UNGCPRO; signal_after_change (from, nchars_del, GPT - from); @@ -1769,6 +1775,7 @@ replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers) CHECK_MARKERS (); MODIFF++; + CHARS_MODIFF = MODIFF; } /* Delete characters in current buffer @@ -1950,6 +1957,7 @@ del_range_2 (from, from_byte, to, to_byte, ret_string) if (! EQ (current_buffer->undo_list, Qt)) record_delete (from, deletion); MODIFF++; + CHARS_MODIFF = MODIFF; /* Relocate point as if it were a marker. */ if (from < PT) @@ -1990,12 +1998,15 @@ del_range_2 (from, from_byte, to, to_byte, ret_string) character positions START to END. This checks the read-only properties of the region, calls the necessary modification hooks, and warns the next redisplay that it should pay attention to that - area. */ + area. + + If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF. + Otherwise set CHARS_MODIFF to the new value of MODIFF. */ void -modify_region (buffer, start, end) +modify_region (buffer, start, end, preserve_chars_modiff) struct buffer *buffer; - int start, end; + int start, end, preserve_chars_modiff; { struct buffer *old_buffer = current_buffer; @@ -2009,6 +2020,8 @@ modify_region (buffer, start, end) if (MODIFF <= SAVE_MODIFF) record_first_change (); MODIFF++; + if (! preserve_chars_modiff) + CHARS_MODIFF = MODIFF; buffer->point_before_scroll = Qnil; diff --git a/src/lisp.h b/src/lisp.h index 0fb14136a5..3d7870c486 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2471,7 +2471,7 @@ extern Lisp_Object del_range_1 P_ ((int, int, int, int)); extern void del_range_byte P_ ((int, int, int)); extern void del_range_both P_ ((int, int, int, int, int)); extern Lisp_Object del_range_2 P_ ((int, int, int, int, int)); -extern void modify_region P_ ((struct buffer *, int, int)); +extern void modify_region P_ ((struct buffer *, int, int, int)); extern void prepare_to_modify_buffer P_ ((int, int, int *)); extern void signal_before_change P_ ((int, int, int *)); extern void signal_after_change P_ ((int, int, int)); diff --git a/src/textprop.c b/src/textprop.c index fd70f039d2..785ed19b56 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -1253,7 +1253,7 @@ Return t if any property value actually changed, nil otherwise. */) } if (BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); /* We are at the beginning of interval I, with LEN chars to scan. */ for (;;) @@ -1393,7 +1393,7 @@ set_text_properties (start, end, properties, object, signal_after_change_p) } if (BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); set_text_properties_1 (start, end, properties, object, i); @@ -1541,7 +1541,7 @@ Use set-text-properties if you want to remove all text properties. */) } if (BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); /* We are at the beginning of an interval, with len to scan */ for (;;) @@ -1655,7 +1655,7 @@ Return t if any property was actually removed, nil otherwise. */) if (LENGTH (i) == len) { if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1668,7 +1668,7 @@ Return t if any property was actually removed, nil otherwise. */) i = split_interval_left (i, len); copy_properties (unchanged, i); if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); remove_properties (Qnil, properties, i, object); if (BUFFERP (object)) signal_after_change (XINT (start), XINT (end) - XINT (start), @@ -1679,7 +1679,7 @@ Return t if any property was actually removed, nil otherwise. */) if (interval_has_some_properties_list (properties, i)) { if (!modified && BUFFERP (object)) - modify_region (XBUFFER (object), XINT (start), XINT (end)); + modify_region (XBUFFER (object), XINT (start), XINT (end), 1); remove_properties (Qnil, properties, i, object); modified = 1; } -- 2.20.1