From: Stefan Monnier Date: Fri, 4 Aug 2006 15:22:09 +0000 (+0000) Subject: (Fsubst_char_in_region): Redo the setup work after running X-Git-Tag: emacs-pretest-22.0.90~1110 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=0f2e2a3bbc74a84038de18603e5d734f38fa9db4;p=emacs.git (Fsubst_char_in_region): Redo the setup work after running the before-change-functions since they may have altered the buffer. --- diff --git a/src/ChangeLog b/src/ChangeLog index 52847a7fe1f..49c4649d144 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2006-08-04 Stefan Monnier + + * editfns.c (Fsubst_char_in_region): Redo the setup work after running + the before-change-functions since they may have altered the buffer. + 2006-08-04 Ralf Angeli * w32fns.c (w32_createwindow): Handle -geometry command line option diff --git a/src/editfns.c b/src/editfns.c index e692204c702..8ac61f3d006 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -2691,6 +2691,10 @@ Both characters must have the same length of multi-byte form. */) Lisp_Object start, end, fromchar, tochar, noundo; { register int pos, pos_byte, stop, i, len, end_byte; + /* Keep track of the first change in the buffer: + if 0 we haven't found it yet. + if < 0 we've found it and we've run the before-change-function. + if > 0 we've actually performed it and the value is its position. */ int changed = 0; unsigned char fromstr[MAX_MULTIBYTE_LENGTH], tostr[MAX_MULTIBYTE_LENGTH]; unsigned char *p; @@ -2703,6 +2707,8 @@ Both characters must have the same length of multi-byte form. */) int last_changed = 0; int multibyte_p = !NILP (current_buffer->enable_multibyte_characters); + restart: + validate_region (&start, &end); CHECK_NUMBER (fromchar); CHECK_NUMBER (tochar); @@ -2740,7 +2746,7 @@ Both characters must have the same length of multi-byte form. */) That's faster than getting rid of things, and it prevents even the entry for a first change. Also inhibit locking the file. */ - if (!NILP (noundo)) + if (!changed && !NILP (noundo)) { record_unwind_protect (subst_char_in_region_unwind, current_buffer->undo_list); @@ -2774,10 +2780,14 @@ Both characters must have the same length of multi-byte form. */) && (len == 2 || (p[2] == fromstr[2] && (len == 3 || p[3] == fromstr[3])))))) { - if (! changed) + if (changed < 0) + /* We've already seen this and run the before-change-function; + this time we only need to record the actual position. */ + changed = pos; + else if (!changed) { - changed = pos; - modify_region (current_buffer, changed, XINT (end)); + changed = -1; + modify_region (current_buffer, pos, XINT (end)); if (! NILP (noundo)) { @@ -2786,6 +2796,10 @@ Both characters must have the same length of multi-byte form. */) if (MODIFF - 1 == current_buffer->auto_save_modified) current_buffer->auto_save_modified++; } + + /* The before-change-function may have moved the gap + or even modified the buffer so we should start over. */ + goto restart; } /* Take care of the case where the new character @@ -2838,7 +2852,7 @@ Both characters must have the same length of multi-byte form. */) pos++; } - if (changed) + if (changed > 0) { signal_after_change (changed, last_changed - changed, last_changed - changed);