comparison 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
comparison
equal deleted inserted replaced
437:e2a4e8b94b82 438:84b14dcb0985
2055 with the correct arguments. The after-change region is calculated 2055 with the correct arguments. The after-change region is calculated
2056 automatically, however, and if changes somehow or other happen outside 2056 automatically, however, and if changes somehow or other happen outside
2057 of the specified region, that will also be handled correctly. 2057 of the specified region, that will also be handled correctly.
2058 2058
2059 begin_multiple_change() returns a number (actually a specpdl depth) 2059 begin_multiple_change() returns a number (actually a specpdl depth)
2060 that you must pass to end_multiple_change() when you are done. */ 2060 that you must pass to end_multiple_change() when you are done.
2061
2062 FSF Emacs 20 implements a similar feature, accessible from Lisp
2063 through a `combine-after-change-calls' special form, which is
2064 essentially equivalent to this function. We should consider
2065 whether we want to introduce a similar Lisp form. */
2061 2066
2062 int 2067 int
2063 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end) 2068 begin_multiple_change (struct buffer *buf, Bufpos start, Bufpos end)
2064 { 2069 {
2065 /* This function can GC */ 2070 /* This function can GC */
2103 change_function_restore (Lisp_Object buffer) 2108 change_function_restore (Lisp_Object buffer)
2104 { 2109 {
2105 /* We should first reset the variable and then change the buffer, 2110 /* We should first reset the variable and then change the buffer,
2106 because Fset_buffer() can throw. */ 2111 because Fset_buffer() can throw. */
2107 inside_change_hook = 0; 2112 inside_change_hook = 0;
2108 Fset_buffer (buffer); 2113 if (XBUFFER (buffer) != current_buffer)
2114 Fset_buffer (buffer);
2109 return Qnil; 2115 return Qnil;
2110 } 2116 }
2111 2117
2112 static int in_first_change; 2118 static int in_first_change;
2113 2119
2153 Lisp_Object bufcons; 2159 Lisp_Object bufcons;
2154 2160
2155 if (!inside_change_hook) 2161 if (!inside_change_hook)
2156 { 2162 {
2157 Lisp_Object buffer; 2163 Lisp_Object buffer;
2164 int speccount;
2158 2165
2159 /* Are we in a multiple-change session? */ 2166 /* Are we in a multiple-change session? */
2160 if (buf->text->changes->in_multiple_change && 2167 if (buf->text->changes->in_multiple_change &&
2161 buf->text->changes->mc_begin != 0) 2168 buf->text->changes->mc_begin != 0)
2162 { 2169 {
2190 signal_first_change (mbuf); 2197 signal_first_change (mbuf);
2191 } 2198 }
2192 } 2199 }
2193 2200
2194 /* Now in any case run the before-change-functions if any. */ 2201 /* Now in any case run the before-change-functions if any. */
2202 speccount = specpdl_depth ();
2203 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2204 inside_change_hook = 1;
2195 2205
2196 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 2206 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2197 { 2207 {
2198 XSETBUFFER (buffer, mbuf); 2208 XSETBUFFER (buffer, mbuf);
2199 if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer)) 2209 if (!NILP (symbol_value_in_buffer (Qbefore_change_functions, buffer))
2200 /* Obsolete, for compatibility */ 2210 /* Obsolete, for compatibility */
2201 || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer))) 2211 || !NILP (symbol_value_in_buffer (Qbefore_change_function, buffer)))
2202 { 2212 {
2203 int speccount = specpdl_depth ();
2204 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2205 set_buffer_internal (buf); 2213 set_buffer_internal (buf);
2206 inside_change_hook = 1;
2207 va_run_hook_with_args (Qbefore_change_functions, 2, 2214 va_run_hook_with_args (Qbefore_change_functions, 2,
2208 make_int (start), make_int (end)); 2215 make_int (start), make_int (end));
2209 /* Obsolete, for compatibility */ 2216 /* Obsolete, for compatibility */
2210 va_run_hook_with_args (Qbefore_change_function, 2, 2217 va_run_hook_with_args (Qbefore_change_function, 2,
2211 make_int (start), make_int (end)); 2218 make_int (start), make_int (end));
2212 unbind_to (speccount, Qnil);
2213 } 2219 }
2214 } 2220 }
2215 2221
2222 /* Make sure endpoints remain valid. before-change-functions
2223 might have modified the buffer. */
2224 if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
2225 if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
2226 if (end < BUF_BEGV (buf)) end = BUF_BEGV (buf);
2227 if (end > BUF_ZV (buf)) end = BUF_ZV (buf);
2228
2216 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 2229 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2217 { 2230 {
2218 XSETBUFFER (buffer, mbuf); 2231 XSETBUFFER (buffer, mbuf);
2219 report_extent_modification (buffer, start, end, 2232 report_extent_modification (buffer, start, end, 0);
2220 &inside_change_hook, 0); 2233 }
2221 } 2234 unbind_to (speccount, Qnil);
2222 2235
2223 /* Only now do we indicate that the before-change-functions have 2236 /* Only now do we indicate that the before-change-functions have
2224 been called, in case some function throws out. */ 2237 been called, in case some function throws out. */
2225 buf->text->changes->mc_begin_signaled = 1; 2238 buf->text->changes->mc_begin_signaled = 1;
2226 } 2239 }
2253 } 2266 }
2254 2267
2255 if (!inside_change_hook) 2268 if (!inside_change_hook)
2256 { 2269 {
2257 Lisp_Object buffer; 2270 Lisp_Object buffer;
2271 int speccount;
2258 2272
2259 if (buf->text->changes->in_multiple_change && 2273 if (buf->text->changes->in_multiple_change &&
2260 buf->text->changes->mc_begin != 0) 2274 buf->text->changes->mc_begin != 0)
2261 { 2275 {
2262 assert (start >= buf->text->changes->mc_begin && 2276 assert (start >= buf->text->changes->mc_begin &&
2265 orig_end <= buf->text->changes->mc_new_end); 2279 orig_end <= buf->text->changes->mc_new_end);
2266 buf->text->changes->mc_new_end += new_end - orig_end; 2280 buf->text->changes->mc_new_end += new_end - orig_end;
2267 return; /* after-change-functions signalled when all changes done */ 2281 return; /* after-change-functions signalled when all changes done */
2268 } 2282 }
2269 2283
2284 speccount = specpdl_depth ();
2285 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2286 inside_change_hook = 1;
2270 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 2287 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2271 { 2288 {
2272 XSETBUFFER (buffer, mbuf); 2289 XSETBUFFER (buffer, mbuf);
2273 2290
2274 if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer)) 2291 if (!NILP (symbol_value_in_buffer (Qafter_change_functions, buffer))
2275 /* Obsolete, for compatibility */ 2292 /* Obsolete, for compatibility */
2276 || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer))) 2293 || !NILP (symbol_value_in_buffer (Qafter_change_function, buffer)))
2277 { 2294 {
2278 int speccount = specpdl_depth ();
2279 record_unwind_protect (change_function_restore, Fcurrent_buffer ());
2280 set_buffer_internal (buf); 2295 set_buffer_internal (buf);
2281 inside_change_hook = 1;
2282 /* The actual after-change functions take slightly 2296 /* The actual after-change functions take slightly
2283 different arguments than what we were passed. */ 2297 different arguments than what we were passed. */
2284 va_run_hook_with_args (Qafter_change_functions, 3, 2298 va_run_hook_with_args (Qafter_change_functions, 3,
2285 make_int (start), make_int (new_end), 2299 make_int (start), make_int (new_end),
2286 make_int (orig_end - start)); 2300 make_int (orig_end - start));
2287 /* Obsolete, for compatibility */ 2301 /* Obsolete, for compatibility */
2288 va_run_hook_with_args (Qafter_change_function, 3, 2302 va_run_hook_with_args (Qafter_change_function, 3,
2289 make_int (start), make_int (new_end), 2303 make_int (start), make_int (new_end),
2290 make_int (orig_end - start)); 2304 make_int (orig_end - start));
2291 unbind_to (speccount, Qnil);
2292 } 2305 }
2293 } 2306 }
2294 2307
2308 /* Make sure endpoints remain valid. after-change-functions
2309 might have modified the buffer. */
2310 if (start < BUF_BEGV (buf)) start = BUF_BEGV (buf);
2311 if (start > BUF_ZV (buf)) start = BUF_ZV (buf);
2312 if (new_end < BUF_BEGV (buf)) new_end = BUF_BEGV (buf);
2313 if (new_end > BUF_ZV (buf)) new_end = BUF_ZV (buf);
2314 if (orig_end < BUF_BEGV (buf)) orig_end = BUF_BEGV (buf);
2315 if (orig_end > BUF_ZV (buf)) orig_end = BUF_ZV (buf);
2316
2295 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons) 2317 MAP_INDIRECT_BUFFERS (buf, mbuf, bufcons)
2296 { 2318 {
2297 XSETBUFFER (buffer, mbuf); 2319 XSETBUFFER (buffer, mbuf);
2298 report_extent_modification (buffer, start, new_end, 2320 report_extent_modification (buffer, start, new_end, 1);
2299 &inside_change_hook, 1); 2321 }
2300 } 2322 unbind_to (speccount, Qnil); /* sets inside_change_hook back to 0 */
2301 } 2323 }
2302 } 2324 }
2303 2325
2304 /* Call this if you're about to change the region of BUFFER from START 2326 /* Call this if you're about to change the region of BUFFER from START
2305 to END. This checks the read-only properties of the region, calls 2327 to END. This checks the read-only properties of the region, calls