aboutsummaryrefslogtreecommitdiffstats
path: root/src/undo.c
diff options
context:
space:
mode:
authorPhillip Lord2015-11-19 15:57:55 +0000
committerPhillip Lord2015-11-26 17:57:11 +0000
commit7592cb9d2a5d68dcb556c87226e38588ce555bd9 (patch)
treed845f1a53b432956e3c1711b586d938aac50996a /src/undo.c
parent02cd9cb8afd9510e3bdb20ce7148d1b9a6aa9d12 (diff)
downloademacs-7592cb9d2a5d68dcb556c87226e38588ce555bd9.tar.gz
emacs-7592cb9d2a5d68dcb556c87226e38588ce555bd9.zip
After delete, record point location in undo.
Addresses Bug #21968. * lisp/simple.el (undo-auto--add-boundary): Clean up code to better support intercalating calls. * src/keyboard.c,src/keyboard.h (command_loop_1): Store value of point and current buffer before each command. * src/undo.c (record_point): Now only record the point. * src/undo.c (prepare_record): Functionality removed form record_point. * src/undo.c (record_delete): Check if point needs recording. * src/undo.c (undo-boundary): Record value of point before each boundary. * test/automated/simple-test.el: New tests. Conflicts: src/undo.c
Diffstat (limited to 'src/undo.c')
-rw-r--r--src/undo.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/src/undo.c b/src/undo.c
index 060dbfc97b1..68065750b0f 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -22,10 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 22
23#include "lisp.h" 23#include "lisp.h"
24#include "buffer.h" 24#include "buffer.h"
25 25#include "keyboard.h"
26/* Position of point last time we inserted a boundary. */
27static struct buffer *last_boundary_buffer;
28static ptrdiff_t last_boundary_position;
29 26
30/* The first time a command records something for undo. 27/* The first time a command records something for undo.
31 it also allocates the undo-boundary object 28 it also allocates the undo-boundary object
@@ -36,36 +33,44 @@ static Lisp_Object pending_boundary;
36 33
37/* Record point as it was at beginning of this command (if necessary) 34/* Record point as it was at beginning of this command (if necessary)
38 and prepare the undo info for recording a change. 35 and prepare the undo info for recording a change.
36/* Prepare the undo info for recording a change. */
37static void
38prepare_record ()
39{
40 /* Allocate a cons cell to be the undo boundary after this command. */
41 if (NILP (pending_boundary))
42 pending_boundary = Fcons (Qnil, Qnil);
43
44 run_undoable_change ();
45
46 if (MODIFF <= SAVE_MODIFF)
47 record_first_change ();
48}
49
50/* Record point as it was at beginning of this command.
39 PT is the position of point that will naturally occur as a result of the 51 PT is the position of point that will naturally occur as a result of the
40 undo record that will be added just after this command terminates. */ 52 undo record that will be added just after this command terminates. */
41
42static void 53static void
43record_point (ptrdiff_t pt) 54record_point (ptrdiff_t pt)
44{ 55{
45 bool at_boundary;
46
47 /* Don't record position of pt when undo_inhibit_record_point holds. */ 56 /* Don't record position of pt when undo_inhibit_record_point holds. */
48 if (undo_inhibit_record_point) 57 if (undo_inhibit_record_point)
49 return; 58 return;
50 59
51 /* Allocate a cons cell to be the undo boundary after this command. */ 60 bool at_boundary;
52 if (NILP (pending_boundary))
53 pending_boundary = Fcons (Qnil, Qnil);
54 61
55 at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) 62 at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
56 || NILP (XCAR (BVAR (current_buffer, undo_list))); 63 || NILP (XCAR (BVAR (current_buffer, undo_list)));
57 64
58 if (MODIFF <= SAVE_MODIFF) 65 prepare_record();
59 record_first_change ();
60 66
61 /* If we are just after an undo boundary, and 67 /* If we are just after an undo boundary, and
62 point wasn't at start of deleted range, record where it was. */ 68 point wasn't at start of deleted range, record where it was. */
63 if (at_boundary 69 if (at_boundary){
64 && current_buffer == last_boundary_buffer
65 && last_boundary_position != pt)
66 bset_undo_list (current_buffer, 70 bset_undo_list (current_buffer,
67 Fcons (make_number (last_boundary_position), 71 Fcons (make_number (pt),
68 BVAR (current_buffer, undo_list))); 72 BVAR (current_buffer, undo_list)));
73 }
69} 74}
70 75
71/* Record an insertion that just happened or is about to happen, 76/* Record an insertion that just happened or is about to happen,
@@ -81,7 +86,7 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
81 if (EQ (BVAR (current_buffer, undo_list), Qt)) 86 if (EQ (BVAR (current_buffer, undo_list), Qt))
82 return; 87 return;
83 88
84 record_point (beg); 89 prepare_record ();
85 90
86 /* If this is following another insertion and consecutive with it 91 /* If this is following another insertion and consecutive with it
87 in the buffer, combine the two. */ 92 in the buffer, combine the two. */
@@ -153,7 +158,6 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
153/* Record that a deletion is about to take place, of the characters in 158/* Record that a deletion is about to take place, of the characters in
154 STRING, at location BEG. Optionally record adjustments for markers 159 STRING, at location BEG. Optionally record adjustments for markers
155 in the region STRING occupies in the current buffer. */ 160 in the region STRING occupies in the current buffer. */
156
157void 161void
158record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers) 162record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
159{ 163{
@@ -162,15 +166,21 @@ record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
162 if (EQ (BVAR (current_buffer, undo_list), Qt)) 166 if (EQ (BVAR (current_buffer, undo_list), Qt))
163 return; 167 return;
164 168
169 if (point_before_last_command_or_undo != beg &&
170 buffer_before_last_command_or_undo == current_buffer)
171 {
172 record_point (point_before_last_command_or_undo);
173 }
174
165 if (PT == beg + SCHARS (string)) 175 if (PT == beg + SCHARS (string))
166 { 176 {
167 XSETINT (sbeg, -beg); 177 XSETINT (sbeg, -beg);
168 record_point (PT); 178 prepare_record ();
169 } 179 }
170 else 180 else
171 { 181 {
172 XSETFASTINT (sbeg, beg); 182 XSETFASTINT (sbeg, beg);
173 record_point (beg); 183 prepare_record ();
174 } 184 }
175 185
176 /* primitive-undo assumes marker adjustments are recorded 186 /* primitive-undo assumes marker adjustments are recorded
@@ -268,10 +278,11 @@ but another undo command will undo to the previous boundary. */)
268 bset_undo_list (current_buffer, 278 bset_undo_list (current_buffer,
269 Fcons (Qnil, BVAR (current_buffer, undo_list))); 279 Fcons (Qnil, BVAR (current_buffer, undo_list)));
270 } 280 }
271 last_boundary_position = PT;
272 last_boundary_buffer = current_buffer;
273 281
274 Fset (Qundo_auto__last_boundary_cause, Qexplicit); 282 Fset (Qundo_auto__last_boundary_cause, Qexplicit);
283 point_before_last_command_or_undo = PT;
284 buffer_before_last_command_or_undo = current_buffer;
285
275 return Qnil; 286 return Qnil;
276} 287}
277 288
@@ -423,8 +434,6 @@ syms_of_undo (void)
423 pending_boundary = Qnil; 434 pending_boundary = Qnil;
424 staticpro (&pending_boundary); 435 staticpro (&pending_boundary);
425 436
426 last_boundary_buffer = NULL;
427
428 defsubr (&Sundo_boundary); 437 defsubr (&Sundo_boundary);
429 438
430 DEFVAR_INT ("undo-limit", undo_limit, 439 DEFVAR_INT ("undo-limit", undo_limit,