Mercurial > hg > xemacs-beta
diff src/insdel.c @ 438:84b14dcb0985 r21-2-27
Import from CVS: tag r21-2-27
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:32:25 +0200 |
parents | 3ecd8885ac67 |
children | 8de8e3f6228a |
line wrap: on
line diff
--- a/src/insdel.c Mon Aug 13 11:31:26 2007 +0200 +++ b/src/insdel.c Mon Aug 13 11:32:25 2007 +0200 @@ -2057,7 +2057,12 @@ of the specified region, that will also be handled correctly. begin_multiple_change() returns a number (actually a specpdl depth) - that you must pass to end_multiple_change() when you are done. */ + that you must pass to end_multiple_change() when you are done. + + FSF Emacs 20 implements a similar feature, accessible from Lisp + through a `combine-after-change-calls' special form, which is + essentially equivalent to this function. We should consider + whether we want to introduce a similar Lisp form. */ int begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end) @@ -2105,7 +2110,8 @@ /* We should first reset the variable and then change the buffer, because Fset_buffer() can throw. */ inside_change_hook = 0; - Fset_buffer (buffer); + if (XBUFFER (buffer) != current_buffer) + Fset_buffer (buffer); return Qnil; } @@ -2155,6 +2161,7 @@ if (!inside_change_hook) { Lisp_Object buffer; + int speccount; /* Are we in a multiple-change session? */ if (buf->text->changes->in_multiple_change && @@ -2192,6 +2199,9 @@ } /* Now in any case run the before-change-functions if any. */ + speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); + inside_change_hook = 1; MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { @@ -2200,25 +2210,28 @@ /* Obsolete, for compatibility */ || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) { - int speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); set_buffer_internal (buf); - inside_change_hook = 1; va_run_hook_with_args (Qbefore_change_functions, 2, make_int (start), make_int (end)); /* Obsolete, for compatibility */ va_run_hook_with_args (Qbefore_change_function, 2, make_int (start), make_int (end)); - unbind_to (speccount, Qnil); } } + /* Make sure endpoints remain valid. before-change-functions + might have modified the buffer. */ + if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); + if (start > BUF_ZV (buf)) start = BUF_ZV (buf); + if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf); + if (end > BUF_ZV (buf)) end = BUF_ZV (buf); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); - report_extent_modification (buffer, start, end, - &inside_change_hook, 0); + report_extent_modification (buffer, start, end, 0); } + unbind_to (speccount, Qnil); /* Only now do we indicate that the before-change-functions have been called, in case some function throws out. */ @@ -2255,6 +2268,7 @@ if (!inside_change_hook) { Lisp_Object buffer; + int speccount; if (buf->text->changes->in_multiple_change && buf->text->changes->mc_begin != 0) @@ -2267,6 +2281,9 @@ return; /* after-change-functions signalled when all changes done */ } + speccount = specpdl_depth (); + record_unwind_protect (change_function_restore, Fcurrent_buffer ()); + inside_change_hook = 1; MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); @@ -2275,10 +2292,7 @@ /* Obsolete, for compatibility */ || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) { - int speccount = specpdl_depth (); - record_unwind_protect (change_function_restore, Fcurrent_buffer ()); set_buffer_internal (buf); - inside_change_hook = 1; /* The actual after-change functions take slightly different arguments than what we were passed. */ va_run_hook_with_args (Qafter_change_functions, 3, @@ -2288,16 +2302,24 @@ va_run_hook_with_args (Qafter_change_function, 3, make_int (start), make_int (new_end), make_int (orig_end - start)); - unbind_to (speccount, Qnil); } } + /* Make sure endpoints remain valid. after-change-functions + might have modified the buffer. */ + if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf); + if (start > BUF_ZV (buf)) start = BUF_ZV (buf); + if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf); + if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf); + if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf); + if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf); + MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) { XSETBUFFER (buffer, mbuf); - report_extent_modification (buffer, start, new_end, - &inside_change_hook, 1); + report_extent_modification (buffer, start, new_end, 1); } + unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */ } }