aboutsummaryrefslogtreecommitdiffstats
path: root/src/undo.c
diff options
context:
space:
mode:
authorPhillip Lord2015-08-06 21:33:58 +0100
committerPhillip Lord2015-11-12 21:06:05 +0000
commit44dfa86b7d382b84564d68472da1448d08f48129 (patch)
tree778e2228ec90a4401b2be6cd7b258ee44a212b26 /src/undo.c
parent0aec2aaccd8b745fa7214f3edd453c04a04bfba4 (diff)
downloademacs-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.c51
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! */
31static 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. */
34static struct buffer *last_boundary_buffer; 30static struct buffer *last_boundary_buffer;
35static ptrdiff_t last_boundary_position; 31static ptrdiff_t last_boundary_position;
@@ -41,6 +37,12 @@ static ptrdiff_t last_boundary_position;
41 an undo-boundary. */ 37 an undo-boundary. */
42static Lisp_Object pending_boundary; 38static Lisp_Object pending_boundary;
43 39
40void
41run_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
284DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0, 268DEFUN ("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
455syms_of_undo (void) 436syms_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);