diff options
| author | Phillip Lord | 2015-08-06 21:33:58 +0100 |
|---|---|---|
| committer | Phillip Lord | 2015-11-12 21:06:05 +0000 |
| commit | 44dfa86b7d382b84564d68472da1448d08f48129 (patch) | |
| tree | 778e2228ec90a4401b2be6cd7b258ee44a212b26 /src/undo.c | |
| parent | 0aec2aaccd8b745fa7214f3edd453c04a04bfba4 (diff) | |
| download | emacs-44dfa86b7d382b84564d68472da1448d08f48129.tar.gz emacs-44dfa86b7d382b84564d68472da1448d08f48129.zip | |
The heuristic that Emacs uses to add an `undo-boundary' has been
reworked, as it interacts poorly with functions on `post-command-hook'
or `after-change-functions'.
* lisp/simple.el: New section added.
* src/cmds.c (remove_excessive_undo_boundaries): Now in lisp.
(self_insert_command): Calls simple.el to amalgamate.
(delete_char): Calls simple.el to amalgamate.
* src/keyboard.c (last_undo_boundary): Removed.
* src/undo.c (run_undoable_change): New function.
Diffstat (limited to 'src/undo.c')
| -rw-r--r-- | src/undo.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/src/undo.c b/src/undo.c index 750bc8afff2..364b37eeeb4 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -26,10 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include "commands.h" | 26 | #include "commands.h" |
| 27 | #include "window.h" | 27 | #include "window.h" |
| 28 | 28 | ||
| 29 | /* Last buffer for which undo information was recorded. */ | ||
| 30 | /* BEWARE: This is not traced by the GC, so never dereference it! */ | ||
| 31 | static struct buffer *last_undo_buffer; | ||
| 32 | |||
| 33 | /* Position of point last time we inserted a boundary. */ | 29 | /* Position of point last time we inserted a boundary. */ |
| 34 | static struct buffer *last_boundary_buffer; | 30 | static struct buffer *last_boundary_buffer; |
| 35 | static ptrdiff_t last_boundary_position; | 31 | static ptrdiff_t last_boundary_position; |
| @@ -41,6 +37,12 @@ static ptrdiff_t last_boundary_position; | |||
| 41 | an undo-boundary. */ | 37 | an undo-boundary. */ |
| 42 | static Lisp_Object pending_boundary; | 38 | static Lisp_Object pending_boundary; |
| 43 | 39 | ||
| 40 | void | ||
| 41 | run_undoable_change () | ||
| 42 | { | ||
| 43 | call0 (Qundo_auto__undoable_change); | ||
| 44 | } | ||
| 45 | |||
| 44 | /* Record point as it was at beginning of this command (if necessary) | 46 | /* Record point as it was at beginning of this command (if necessary) |
| 45 | and prepare the undo info for recording a change. | 47 | and prepare the undo info for recording a change. |
| 46 | PT is the position of point that will naturally occur as a result of the | 48 | PT is the position of point that will naturally occur as a result of the |
| @@ -59,15 +61,7 @@ record_point (ptrdiff_t pt) | |||
| 59 | if (NILP (pending_boundary)) | 61 | if (NILP (pending_boundary)) |
| 60 | pending_boundary = Fcons (Qnil, Qnil); | 62 | pending_boundary = Fcons (Qnil, Qnil); |
| 61 | 63 | ||
| 62 | if ((current_buffer != last_undo_buffer) | 64 | run_undoable_change (); |
| 63 | /* Don't call Fundo_boundary for the first change. Otherwise we | ||
| 64 | risk overwriting last_boundary_position in Fundo_boundary with | ||
| 65 | PT of the current buffer and as a consequence not insert an | ||
| 66 | undo boundary because last_boundary_position will equal pt in | ||
| 67 | the test at the end of the present function (Bug#731). */ | ||
| 68 | && (MODIFF > SAVE_MODIFF)) | ||
| 69 | Fundo_boundary (); | ||
| 70 | last_undo_buffer = current_buffer; | ||
| 71 | 65 | ||
| 72 | at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) | 66 | at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) |
| 73 | || NILP (XCAR (BVAR (current_buffer, undo_list))); | 67 | || NILP (XCAR (BVAR (current_buffer, undo_list))); |
| @@ -139,9 +133,7 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) | |||
| 139 | if (NILP (pending_boundary)) | 133 | if (NILP (pending_boundary)) |
| 140 | pending_boundary = Fcons (Qnil, Qnil); | 134 | pending_boundary = Fcons (Qnil, Qnil); |
| 141 | 135 | ||
| 142 | if (current_buffer != last_undo_buffer) | 136 | run_undoable_change (); |
| 143 | Fundo_boundary (); | ||
| 144 | last_undo_buffer = current_buffer; | ||
| 145 | 137 | ||
| 146 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) | 138 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) |
| 147 | { | 139 | { |
| @@ -228,10 +220,6 @@ record_first_change (void) | |||
| 228 | if (EQ (BVAR (current_buffer, undo_list), Qt)) | 220 | if (EQ (BVAR (current_buffer, undo_list), Qt)) |
| 229 | return; | 221 | return; |
| 230 | 222 | ||
| 231 | if (current_buffer != last_undo_buffer) | ||
| 232 | Fundo_boundary (); | ||
| 233 | last_undo_buffer = current_buffer; | ||
| 234 | |||
| 235 | if (base_buffer->base_buffer) | 223 | if (base_buffer->base_buffer) |
| 236 | base_buffer = base_buffer->base_buffer; | 224 | base_buffer = base_buffer->base_buffer; |
| 237 | 225 | ||
| @@ -259,15 +247,10 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length, | |||
| 259 | if (NILP (pending_boundary)) | 247 | if (NILP (pending_boundary)) |
| 260 | pending_boundary = Fcons (Qnil, Qnil); | 248 | pending_boundary = Fcons (Qnil, Qnil); |
| 261 | 249 | ||
| 262 | if (buf != last_undo_buffer) | ||
| 263 | boundary = true; | ||
| 264 | last_undo_buffer = buf; | ||
| 265 | |||
| 266 | /* Switch temporarily to the buffer that was changed. */ | 250 | /* Switch temporarily to the buffer that was changed. */ |
| 267 | current_buffer = buf; | 251 | set_buffer_internal (buf); |
| 268 | 252 | ||
| 269 | if (boundary) | 253 | run_undoable_change (); |
| 270 | Fundo_boundary (); | ||
| 271 | 254 | ||
| 272 | if (MODIFF <= SAVE_MODIFF) | 255 | if (MODIFF <= SAVE_MODIFF) |
| 273 | record_first_change (); | 256 | record_first_change (); |
| @@ -278,7 +261,8 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length, | |||
| 278 | bset_undo_list (current_buffer, | 261 | bset_undo_list (current_buffer, |
| 279 | Fcons (entry, BVAR (current_buffer, undo_list))); | 262 | Fcons (entry, BVAR (current_buffer, undo_list))); |
| 280 | 263 | ||
| 281 | current_buffer = obuf; | 264 | /* Reset the buffer */ |
| 265 | set_buffer_internal (obuf); | ||
| 282 | } | 266 | } |
| 283 | 267 | ||
| 284 | DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0, | 268 | DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0, |
| @@ -308,6 +292,8 @@ but another undo command will undo to the previous boundary. */) | |||
| 308 | } | 292 | } |
| 309 | last_boundary_position = PT; | 293 | last_boundary_position = PT; |
| 310 | last_boundary_buffer = current_buffer; | 294 | last_boundary_buffer = current_buffer; |
| 295 | |||
| 296 | Fset (Qundo_auto__last_boundary_cause, Qexplicit); | ||
| 311 | return Qnil; | 297 | return Qnil; |
| 312 | } | 298 | } |
| 313 | 299 | ||
| @@ -383,7 +369,6 @@ truncate_undo_list (struct buffer *b) | |||
| 383 | && !NILP (Vundo_outer_limit_function)) | 369 | && !NILP (Vundo_outer_limit_function)) |
| 384 | { | 370 | { |
| 385 | Lisp_Object tem; | 371 | Lisp_Object tem; |
| 386 | struct buffer *temp = last_undo_buffer; | ||
| 387 | 372 | ||
| 388 | /* Normally the function this calls is undo-outer-limit-truncate. */ | 373 | /* Normally the function this calls is undo-outer-limit-truncate. */ |
| 389 | tem = call1 (Vundo_outer_limit_function, make_number (size_so_far)); | 374 | tem = call1 (Vundo_outer_limit_function, make_number (size_so_far)); |
| @@ -394,10 +379,6 @@ truncate_undo_list (struct buffer *b) | |||
| 394 | unbind_to (count, Qnil); | 379 | unbind_to (count, Qnil); |
| 395 | return; | 380 | return; |
| 396 | } | 381 | } |
| 397 | /* That function probably used the minibuffer, and if so, that | ||
| 398 | changed last_undo_buffer. Change it back so that we don't | ||
| 399 | force next change to make an undo boundary here. */ | ||
| 400 | last_undo_buffer = temp; | ||
| 401 | } | 382 | } |
| 402 | 383 | ||
| 403 | if (CONSP (next)) | 384 | if (CONSP (next)) |
| @@ -455,6 +436,9 @@ void | |||
| 455 | syms_of_undo (void) | 436 | syms_of_undo (void) |
| 456 | { | 437 | { |
| 457 | DEFSYM (Qinhibit_read_only, "inhibit-read-only"); | 438 | DEFSYM (Qinhibit_read_only, "inhibit-read-only"); |
| 439 | DEFSYM (Qundo_auto__undoable_change, "undo-auto--undoable-change"); | ||
| 440 | DEFSYM (Qundo_auto__last_boundary_cause, "undo-auto--last-boundary-cause"); | ||
| 441 | DEFSYM (Qexplicit, "explicit"); | ||
| 458 | 442 | ||
| 459 | /* Marker for function call undo list elements. */ | 443 | /* Marker for function call undo list elements. */ |
| 460 | DEFSYM (Qapply, "apply"); | 444 | DEFSYM (Qapply, "apply"); |
| @@ -462,7 +446,6 @@ syms_of_undo (void) | |||
| 462 | pending_boundary = Qnil; | 446 | pending_boundary = Qnil; |
| 463 | staticpro (&pending_boundary); | 447 | staticpro (&pending_boundary); |
| 464 | 448 | ||
| 465 | last_undo_buffer = NULL; | ||
| 466 | last_boundary_buffer = NULL; | 449 | last_boundary_buffer = NULL; |
| 467 | 450 | ||
| 468 | defsubr (&Sundo_boundary); | 451 | defsubr (&Sundo_boundary); |