aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2015-04-13 14:05:09 -0400
committerStefan Monnier2015-04-13 14:05:09 -0400
commit5729f459d1dbb28bc405a142860a99e1329f388a (patch)
treefd47406fdfe5c37382edb1808b0d690ee77f47fa /src
parent5d9432e6491f63fe4859a46737516c9510643626 (diff)
downloademacs-5729f459d1dbb28bc405a142860a99e1329f388a.tar.gz
emacs-5729f459d1dbb28bc405a142860a99e1329f388a.zip
Collapse successive char deletions in the undo log
* src/cmds.c (remove_excessive_undo_boundaries): New function, extracted from Fself_insert_command. (Fdelete_char, Fself_insert_command): Use it. * src/fileio.c (Fmake_symbolic_link): Rename arg to `target'. * src/keyboard.c (syms_of_keyboard): `top-level' shouldn't be special.
Diffstat (limited to 'src')
-rw-r--r--src/cmds.c60
-rw-r--r--src/fileio.c32
-rw-r--r--src/keyboard.c1
3 files changed, 52 insertions, 41 deletions
diff --git a/src/cmds.c b/src/cmds.c
index 270fc39cabc..168ce8355ed 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -213,6 +213,36 @@ to t. */)
213 return Qnil; 213 return Qnil;
214} 214}
215 215
216static int nonundocount;
217
218static void
219remove_excessive_undo_boundaries (void)
220{
221 bool remove_boundary = true;
222
223 if (!EQ (Vthis_command, KVAR (current_kboard, Vlast_command)))
224 nonundocount = 0;
225
226 if (NILP (Vexecuting_kbd_macro))
227 {
228 if (nonundocount <= 0 || nonundocount >= 20)
229 {
230 remove_boundary = false;
231 nonundocount = 0;
232 }
233 nonundocount++;
234 }
235
236 if (remove_boundary
237 && CONSP (BVAR (current_buffer, undo_list))
238 && NILP (XCAR (BVAR (current_buffer, undo_list)))
239 /* Only remove auto-added boundaries, not boundaries
240 added by explicit calls to undo-boundary. */
241 && EQ (BVAR (current_buffer, undo_list), last_undo_boundary))
242 /* Remove the undo_boundary that was just pushed. */
243 bset_undo_list (current_buffer, XCDR (BVAR (current_buffer, undo_list)));
244}
245
216DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP", 246DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP",
217 doc: /* Delete the following N characters (previous if N is negative). 247 doc: /* Delete the following N characters (previous if N is negative).
218Optional second arg KILLFLAG non-nil means kill instead (save in kill ring). 248Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
@@ -227,6 +257,9 @@ because it respects values of `delete-active-region' and `overwrite-mode'. */)
227 257
228 CHECK_NUMBER (n); 258 CHECK_NUMBER (n);
229 259
260 if (abs (XINT (n)) < 2)
261 remove_excessive_undo_boundaries ();
262
230 pos = PT + XINT (n); 263 pos = PT + XINT (n);
231 if (NILP (killflag)) 264 if (NILP (killflag))
232 { 265 {
@@ -252,8 +285,6 @@ because it respects values of `delete-active-region' and `overwrite-mode'. */)
252 return Qnil; 285 return Qnil;
253} 286}
254 287
255static int nonundocount;
256
257/* Note that there's code in command_loop_1 which typically avoids 288/* Note that there's code in command_loop_1 which typically avoids
258 calling this. */ 289 calling this. */
259DEFUN ("self-insert-command", Fself_insert_command, Sself_insert_command, 1, 1, "p", 290DEFUN ("self-insert-command", Fself_insert_command, Sself_insert_command, 1, 1, "p",
@@ -267,34 +298,13 @@ After insertion, the value of `auto-fill-function' is called if the
267At the end, it runs `post-self-insert-hook'. */) 298At the end, it runs `post-self-insert-hook'. */)
268 (Lisp_Object n) 299 (Lisp_Object n)
269{ 300{
270 bool remove_boundary = 1;
271 CHECK_NUMBER (n); 301 CHECK_NUMBER (n);
272 302
273 if (XFASTINT (n) < 0) 303 if (XFASTINT (n) < 0)
274 error ("Negative repetition argument %"pI"d", XFASTINT (n)); 304 error ("Negative repetition argument %"pI"d", XFASTINT (n));
275 305
276 if (!EQ (Vthis_command, KVAR (current_kboard, Vlast_command))) 306 if (XFASTINT (n) < 2)
277 nonundocount = 0; 307 remove_excessive_undo_boundaries ();
278
279 if (NILP (Vexecuting_kbd_macro)
280 && !EQ (minibuf_window, selected_window))
281 {
282 if (nonundocount <= 0 || nonundocount >= 20)
283 {
284 remove_boundary = 0;
285 nonundocount = 0;
286 }
287 nonundocount++;
288 }
289
290 if (remove_boundary
291 && CONSP (BVAR (current_buffer, undo_list))
292 && NILP (XCAR (BVAR (current_buffer, undo_list)))
293 /* Only remove auto-added boundaries, not boundaries
294 added be explicit calls to undo-boundary. */
295 && EQ (BVAR (current_buffer, undo_list), last_undo_boundary))
296 /* Remove the undo_boundary that was just pushed. */
297 bset_undo_list (current_buffer, XCDR (BVAR (current_buffer, undo_list)));
298 308
299 /* Barf if the key that invoked this was not a character. */ 309 /* Barf if the key that invoked this was not a character. */
300 if (!CHARACTERP (last_command_event)) 310 if (!CHARACTERP (last_command_event))
diff --git a/src/fileio.c b/src/fileio.c
index a6e7fbb83d2..796f08d3c58 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2344,62 +2344,62 @@ This is what happens in interactive use with M-x. */)
2344 2344
2345DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3, 2345DEFUN ("make-symbolic-link", Fmake_symbolic_link, Smake_symbolic_link, 2, 3,
2346 "FMake symbolic link to file: \nGMake symbolic link to file %s: \np", 2346 "FMake symbolic link to file: \nGMake symbolic link to file %s: \np",
2347 doc: /* Make a symbolic link to FILENAME, named LINKNAME. 2347 doc: /* Make a symbolic link to TARGET, named LINKNAME.
2348Both args must be strings. 2348Both args must be strings.
2349Signals a `file-already-exists' error if a file LINKNAME already exists 2349Signals a `file-already-exists' error if a file LINKNAME already exists
2350unless optional third argument OK-IF-ALREADY-EXISTS is non-nil. 2350unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
2351A number as third arg means request confirmation if LINKNAME already exists. 2351A number as third arg means request confirmation if LINKNAME already exists.
2352This happens for interactive use with M-x. */) 2352This happens for interactive use with M-x. */)
2353 (Lisp_Object filename, Lisp_Object linkname, Lisp_Object ok_if_already_exists) 2353 (Lisp_Object target, Lisp_Object linkname, Lisp_Object ok_if_already_exists)
2354{ 2354{
2355 Lisp_Object handler; 2355 Lisp_Object handler;
2356 Lisp_Object encoded_filename, encoded_linkname; 2356 Lisp_Object encoded_target, encoded_linkname;
2357 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 2357 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
2358 2358
2359 GCPRO4 (filename, linkname, encoded_filename, encoded_linkname); 2359 GCPRO4 (target, linkname, encoded_target, encoded_linkname);
2360 encoded_filename = encoded_linkname = Qnil; 2360 encoded_target = encoded_linkname = Qnil;
2361 CHECK_STRING (filename); 2361 CHECK_STRING (target);
2362 CHECK_STRING (linkname); 2362 CHECK_STRING (linkname);
2363 /* If the link target has a ~, we must expand it to get 2363 /* If the link target has a ~, we must expand it to get
2364 a truly valid file name. Otherwise, do not expand; 2364 a truly valid file name. Otherwise, do not expand;
2365 we want to permit links to relative file names. */ 2365 we want to permit links to relative file names. */
2366 if (SREF (filename, 0) == '~') 2366 if (SREF (target, 0) == '~')
2367 filename = Fexpand_file_name (filename, Qnil); 2367 target = Fexpand_file_name (target, Qnil);
2368 2368
2369 if (!NILP (Ffile_directory_p (linkname))) 2369 if (!NILP (Ffile_directory_p (linkname)))
2370 linkname = Fexpand_file_name (Ffile_name_nondirectory (filename), linkname); 2370 linkname = Fexpand_file_name (Ffile_name_nondirectory (target), linkname);
2371 else 2371 else
2372 linkname = Fexpand_file_name (linkname, Qnil); 2372 linkname = Fexpand_file_name (linkname, Qnil);
2373 2373
2374 /* If the file name has special constructs in it, 2374 /* If the file name has special constructs in it,
2375 call the corresponding file handler. */ 2375 call the corresponding file handler. */
2376 handler = Ffind_file_name_handler (filename, Qmake_symbolic_link); 2376 handler = Ffind_file_name_handler (target, Qmake_symbolic_link);
2377 if (!NILP (handler)) 2377 if (!NILP (handler))
2378 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, 2378 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, target,
2379 linkname, ok_if_already_exists)); 2379 linkname, ok_if_already_exists));
2380 2380
2381 /* If the new link name has special constructs in it, 2381 /* If the new link name has special constructs in it,
2382 call the corresponding file handler. */ 2382 call the corresponding file handler. */
2383 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link); 2383 handler = Ffind_file_name_handler (linkname, Qmake_symbolic_link);
2384 if (!NILP (handler)) 2384 if (!NILP (handler))
2385 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, filename, 2385 RETURN_UNGCPRO (call4 (handler, Qmake_symbolic_link, target,
2386 linkname, ok_if_already_exists)); 2386 linkname, ok_if_already_exists));
2387 2387
2388 encoded_filename = ENCODE_FILE (filename); 2388 encoded_target = ENCODE_FILE (target);
2389 encoded_linkname = ENCODE_FILE (linkname); 2389 encoded_linkname = ENCODE_FILE (linkname);
2390 2390
2391 if (NILP (ok_if_already_exists) 2391 if (NILP (ok_if_already_exists)
2392 || INTEGERP (ok_if_already_exists)) 2392 || INTEGERP (ok_if_already_exists))
2393 barf_or_query_if_file_exists (linkname, false, "make it a link", 2393 barf_or_query_if_file_exists (linkname, false, "make it a link",
2394 INTEGERP (ok_if_already_exists), false); 2394 INTEGERP (ok_if_already_exists), false);
2395 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) < 0) 2395 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname)) < 0)
2396 { 2396 {
2397 /* If we didn't complain already, silently delete existing file. */ 2397 /* If we didn't complain already, silently delete existing file. */
2398 int symlink_errno; 2398 int symlink_errno;
2399 if (errno == EEXIST) 2399 if (errno == EEXIST)
2400 { 2400 {
2401 unlink (SSDATA (encoded_linkname)); 2401 unlink (SSDATA (encoded_linkname));
2402 if (symlink (SSDATA (encoded_filename), SSDATA (encoded_linkname)) 2402 if (symlink (SSDATA (encoded_target), SSDATA (encoded_linkname))
2403 >= 0) 2403 >= 0)
2404 { 2404 {
2405 UNGCPRO; 2405 UNGCPRO;
@@ -2414,7 +2414,7 @@ This happens for interactive use with M-x. */)
2414 } 2414 }
2415 2415
2416 symlink_errno = errno; 2416 symlink_errno = errno;
2417 report_file_errno ("Making symbolic link", list2 (filename, linkname), 2417 report_file_errno ("Making symbolic link", list2 (target, linkname),
2418 symlink_errno); 2418 symlink_errno);
2419 } 2419 }
2420 UNGCPRO; 2420 UNGCPRO;
diff --git a/src/keyboard.c b/src/keyboard.c
index 2d047da5511..068a47c6c75 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -11492,6 +11492,7 @@ for that character after that prefix key. */);
11492 doc: /* Form to evaluate when Emacs starts up. 11492 doc: /* Form to evaluate when Emacs starts up.
11493Useful to set before you dump a modified Emacs. */); 11493Useful to set before you dump a modified Emacs. */);
11494 Vtop_level = Qnil; 11494 Vtop_level = Qnil;
11495 XSYMBOL (Qtop_level)->declared_special = false;
11495 11496
11496 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table, 11497 DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
11497 doc: /* Translate table for local keyboard input, or nil. 11498 doc: /* Translate table for local keyboard input, or nil.