aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2007-08-21 18:22:03 +0000
committerStefan Monnier2007-08-21 18:22:03 +0000
commit97c4ef2a204f2be3db8de5c900046abe09d0582a (patch)
treed70157d7cbda014f388718d4992374bc0341e913 /src
parentd5dac3b9bd5baa34ebb0506d0cd4460397a03d81 (diff)
downloademacs-97c4ef2a204f2be3db8de5c900046abe09d0582a.tar.gz
emacs-97c4ef2a204f2be3db8de5c900046abe09d0582a.zip
(reset_var_on_error): New fun.
(signal_before_change, signal_after_change): Use it to reset (after|before)-change-functions to nil in case of error. Bind inhibit-modification-hooks to t. Don't bind (after|before)-change-functions to nil while they run.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/insdel.c100
2 files changed, 46 insertions, 62 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index add0663a648..bf015d6959f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
12007-08-21 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * insdel.c (reset_var_on_error): New fun.
4 (signal_before_change, signal_after_change):
5 Use it to reset (after|before)-change-functions to nil in case of error.
6 Bind inhibit-modification-hooks to t.
7 Don't bind (after|before)-change-functions to nil while they run.
8
12007-08-19 Andreas Schwab <schwab@suse.de> 92007-08-19 Andreas Schwab <schwab@suse.de>
2 10
3 * alloc.c (pure): Round PURESIZE up. 11 * alloc.c (pure): Round PURESIZE up.
diff --git a/src/insdel.c b/src/insdel.c
index 14e7478e69a..cd8e2738f9a 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -2137,6 +2137,21 @@ prepare_to_modify_buffer (start, end, preserve_ptr)
2137#define FETCH_END \ 2137#define FETCH_END \
2138 (! NILP (end_marker) ? Fmarker_position (end_marker) : end) 2138 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2139 2139
2140/* Set a variable to nil if an error occurred.
2141 Don't change the variable if there was no error.
2142 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2143 VARIABLE is the variable to maybe set to nil.
2144 NO-ERROR-FLAG is nil if there was an error,
2145 anything else meaning no error (so this function does nothing). */
2146Lisp_Object
2147reset_var_on_error (val)
2148 Lisp_Object val;
2149{
2150 if (NILP (XCDR (val)))
2151 Fset (XCAR (val), Qnil);
2152 return Qnil;
2153}
2154
2140/* Signal a change to the buffer immediately before it happens. 2155/* Signal a change to the buffer immediately before it happens.
2141 START_INT and END_INT are the bounds of the text to be changed. 2156 START_INT and END_INT are the bounds of the text to be changed.
2142 2157
@@ -2152,6 +2167,7 @@ signal_before_change (start_int, end_int, preserve_ptr)
2152 Lisp_Object start_marker, end_marker; 2167 Lisp_Object start_marker, end_marker;
2153 Lisp_Object preserve_marker; 2168 Lisp_Object preserve_marker;
2154 struct gcpro gcpro1, gcpro2, gcpro3; 2169 struct gcpro gcpro1, gcpro2, gcpro3;
2170 int count = SPECPDL_INDEX ();
2155 2171
2156 if (inhibit_modification_hooks) 2172 if (inhibit_modification_hooks)
2157 return; 2173 return;
@@ -2163,6 +2179,8 @@ signal_before_change (start_int, end_int, preserve_ptr)
2163 end_marker = Qnil; 2179 end_marker = Qnil;
2164 GCPRO3 (preserve_marker, start_marker, end_marker); 2180 GCPRO3 (preserve_marker, start_marker, end_marker);
2165 2181
2182 specbind (Qinhibit_modification_hooks, Qt);
2183
2166 /* If buffer is unmodified, run a special hook for that case. */ 2184 /* If buffer is unmodified, run a special hook for that case. */
2167 if (SAVE_MODIFF >= MODIFF 2185 if (SAVE_MODIFF >= MODIFF
2168 && !NILP (Vfirst_change_hook) 2186 && !NILP (Vfirst_change_hook)
@@ -2177,46 +2195,22 @@ signal_before_change (start_int, end_int, preserve_ptr)
2177 if (!NILP (Vbefore_change_functions)) 2195 if (!NILP (Vbefore_change_functions))
2178 { 2196 {
2179 Lisp_Object args[3]; 2197 Lisp_Object args[3];
2180 Lisp_Object before_change_functions; 2198 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
2181 Lisp_Object after_change_functions;
2182 struct gcpro gcpro1, gcpro2;
2183 struct buffer *old = current_buffer;
2184 struct buffer *new;
2185 2199
2186 PRESERVE_VALUE; 2200 PRESERVE_VALUE;
2187 PRESERVE_START_END; 2201 PRESERVE_START_END;
2188 2202
2189 /* "Bind" before-change-functions and after-change-functions 2203 /* Mark before-change-functions to be reset to nil in case of error. */
2190 to nil--but in a way that errors don't know about. 2204 record_unwind_protect (reset_var_on_error, rvoe_arg);
2191 That way, if there's an error in them, they will stay nil. */
2192 before_change_functions = Vbefore_change_functions;
2193 after_change_functions = Vafter_change_functions;
2194 Vbefore_change_functions = Qnil;
2195 Vafter_change_functions = Qnil;
2196 GCPRO2 (before_change_functions, after_change_functions);
2197 2205
2198 /* Actually run the hook functions. */ 2206 /* Actually run the hook functions. */
2199 args[0] = Qbefore_change_functions; 2207 args[0] = Qbefore_change_functions;
2200 args[1] = FETCH_START; 2208 args[1] = FETCH_START;
2201 args[2] = FETCH_END; 2209 args[2] = FETCH_END;
2202 run_hook_list_with_args (before_change_functions, 3, args); 2210 Frun_hook_with_args (3, args);
2203 2211
2204 /* "Unbind" the variables we "bound" to nil. Beware a 2212 /* There was no error: unarm the reset_on_error. */
2205 buffer-local hook which changes the buffer when run (e.g. W3). */ 2213 XSETCDR (rvoe_arg, Qt);
2206 if (old != current_buffer)
2207 {
2208 new = current_buffer;
2209 set_buffer_internal (old);
2210 Vbefore_change_functions = before_change_functions;
2211 Vafter_change_functions = after_change_functions;
2212 set_buffer_internal (new);
2213 }
2214 else
2215 {
2216 Vbefore_change_functions = before_change_functions;
2217 Vafter_change_functions = after_change_functions;
2218 }
2219 UNGCPRO;
2220 } 2214 }
2221 2215
2222 if (current_buffer->overlays_before || current_buffer->overlays_after) 2216 if (current_buffer->overlays_before || current_buffer->overlays_after)
@@ -2232,6 +2226,8 @@ signal_before_change (start_int, end_int, preserve_ptr)
2232 free_marker (end_marker); 2226 free_marker (end_marker);
2233 RESTORE_VALUE; 2227 RESTORE_VALUE;
2234 UNGCPRO; 2228 UNGCPRO;
2229
2230 unbind_to (count, Qnil);
2235} 2231}
2236 2232
2237/* Signal a change immediately after it happens. 2233/* Signal a change immediately after it happens.
@@ -2245,6 +2241,7 @@ void
2245signal_after_change (charpos, lendel, lenins) 2241signal_after_change (charpos, lendel, lenins)
2246 int charpos, lendel, lenins; 2242 int charpos, lendel, lenins;
2247{ 2243{
2244 int count = SPECPDL_INDEX ();
2248 if (inhibit_modification_hooks) 2245 if (inhibit_modification_hooks)
2249 return; 2246 return;
2250 2247
@@ -2275,48 +2272,25 @@ signal_after_change (charpos, lendel, lenins)
2275 if (!NILP (combine_after_change_list)) 2272 if (!NILP (combine_after_change_list))
2276 Fcombine_after_change_execute (); 2273 Fcombine_after_change_execute ();
2277 2274
2275 specbind (Qinhibit_modification_hooks, Qt);
2276
2278 if (!NILP (Vafter_change_functions)) 2277 if (!NILP (Vafter_change_functions))
2279 { 2278 {
2280 Lisp_Object args[4]; 2279 Lisp_Object args[4];
2281 Lisp_Object before_change_functions; 2280 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
2282 Lisp_Object after_change_functions; 2281
2283 struct buffer *old = current_buffer; 2282 /* Mark after-change-functions to be reset to nil in case of error. */
2284 struct buffer *new; 2283 record_unwind_protect (reset_var_on_error, rvoe_arg);
2285 struct gcpro gcpro1, gcpro2;
2286
2287 /* "Bind" before-change-functions and after-change-functions
2288 to nil--but in a way that errors don't know about.
2289 That way, if there's an error in them, they will stay nil. */
2290 before_change_functions = Vbefore_change_functions;
2291 after_change_functions = Vafter_change_functions;
2292 Vbefore_change_functions = Qnil;
2293 Vafter_change_functions = Qnil;
2294 GCPRO2 (before_change_functions, after_change_functions);
2295 2284
2296 /* Actually run the hook functions. */ 2285 /* Actually run the hook functions. */
2297 args[0] = Qafter_change_functions; 2286 args[0] = Qafter_change_functions;
2298 XSETFASTINT (args[1], charpos); 2287 XSETFASTINT (args[1], charpos);
2299 XSETFASTINT (args[2], charpos + lenins); 2288 XSETFASTINT (args[2], charpos + lenins);
2300 XSETFASTINT (args[3], lendel); 2289 XSETFASTINT (args[3], lendel);
2301 run_hook_list_with_args (after_change_functions, 2290 Frun_hook_with_args (4, args);
2302 4, args);
2303 2291
2304 /* "Unbind" the variables we "bound" to nil. Beware a 2292 /* There was no error: unarm the reset_on_error. */
2305 buffer-local hook which changes the buffer when run (e.g. W3). */ 2293 XSETCDR (rvoe_arg, Qt);
2306 if (old != current_buffer)
2307 {
2308 new = current_buffer;
2309 set_buffer_internal (old);
2310 Vbefore_change_functions = before_change_functions;
2311 Vafter_change_functions = after_change_functions;
2312 set_buffer_internal (new);
2313 }
2314 else
2315 {
2316 Vbefore_change_functions = before_change_functions;
2317 Vafter_change_functions = after_change_functions;
2318 }
2319 UNGCPRO;
2320 } 2294 }
2321 2295
2322 if (current_buffer->overlays_before || current_buffer->overlays_after) 2296 if (current_buffer->overlays_before || current_buffer->overlays_after)
@@ -2332,6 +2306,8 @@ signal_after_change (charpos, lendel, lenins)
2332 if (lendel == 0) 2306 if (lendel == 0)
2333 report_interval_modification (make_number (charpos), 2307 report_interval_modification (make_number (charpos),
2334 make_number (charpos + lenins)); 2308 make_number (charpos + lenins));
2309
2310 unbind_to (count, Qnil);
2335} 2311}
2336 2312
2337Lisp_Object 2313Lisp_Object