aboutsummaryrefslogtreecommitdiffstats
path: root/src/undo.c
diff options
context:
space:
mode:
authorJuanma Barranquero2014-03-26 16:57:13 +0100
committerJuanma Barranquero2014-03-26 16:57:13 +0100
commit16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614 (patch)
tree29b782fd6e7c44a834dd09442a551520e30bcbd6 /src/undo.c
parent5af73b0fe8975eeb47fb270819b4143c18d71caa (diff)
parent196716cf35f81bea108c3b75362e92c86ed1c016 (diff)
downloademacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.tar.gz
emacs-16adf2e6eb1ddf0b32ebea2d5ce8fa1e4c226614.zip
Merge from emacs-24; up to 2014-03-23T23:14:52Z!yamaoka@jpl.org
Diffstat (limited to 'src/undo.c')
-rw-r--r--src/undo.c112
1 files changed, 62 insertions, 50 deletions
diff --git a/src/undo.c b/src/undo.c
index 7286d40b2e5..2dde02b99a9 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -75,27 +75,8 @@ record_point (ptrdiff_t pt)
75 Fundo_boundary (); 75 Fundo_boundary ();
76 last_undo_buffer = current_buffer; 76 last_undo_buffer = current_buffer;
77 77
78 if (CONSP (BVAR (current_buffer, undo_list))) 78 at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
79 { 79 || NILP (XCAR (BVAR (current_buffer, undo_list)));
80 /* Set AT_BOUNDARY only when we have nothing other than
81 marker adjustment before undo boundary. */
82
83 Lisp_Object tail = BVAR (current_buffer, undo_list), elt;
84
85 while (1)
86 {
87 if (NILP (tail))
88 elt = Qnil;
89 else
90 elt = XCAR (tail);
91 if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt))))
92 break;
93 tail = XCDR (tail);
94 }
95 at_boundary = NILP (elt);
96 }
97 else
98 at_boundary = 1;
99 80
100 if (MODIFF <= SAVE_MODIFF) 81 if (MODIFF <= SAVE_MODIFF)
101 record_first_change (); 82 record_first_change ();
@@ -147,11 +128,61 @@ record_insert (ptrdiff_t beg, ptrdiff_t length)
147 Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list))); 128 Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list)));
148} 129}
149 130
150/* Record that a deletion is about to take place, 131/* Record the fact that markers in the region of FROM, TO are about to
151 of the characters in STRING, at location BEG. */ 132 be adjusted. This is done only when a marker points within text
133 being deleted, because that's the only case where an automatic
134 marker adjustment won't be inverted automatically by undoing the
135 buffer modification. */
136
137static void
138record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
139{
140 Lisp_Object marker;
141 register struct Lisp_Marker *m;
142 register ptrdiff_t charpos, adjustment;
143
144 /* Allocate a cons cell to be the undo boundary after this command. */
145 if (NILP (pending_boundary))
146 pending_boundary = Fcons (Qnil, Qnil);
147
148 if (current_buffer != last_undo_buffer)
149 Fundo_boundary ();
150 last_undo_buffer = current_buffer;
151
152 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
153 {
154 charpos = m->charpos;
155 eassert (charpos <= Z);
156
157 if (from <= charpos && charpos <= to)
158 {
159 /* insertion_type nil markers will end up at the beginning of
160 the re-inserted text after undoing a deletion, and must be
161 adjusted to move them to the correct place.
162
163 insertion_type t markers will automatically move forward
164 upon re-inserting the deleted text, so we have to arrange
165 for them to move backward to the correct position. */
166 adjustment = (m->insertion_type ? to : from) - charpos;
167
168 if (adjustment)
169 {
170 XSETMISC (marker, m);
171 bset_undo_list
172 (current_buffer,
173 Fcons (Fcons (marker, make_number (adjustment)),
174 BVAR (current_buffer, undo_list)));
175 }
176 }
177 }
178}
179
180/* Record that a deletion is about to take place, of the characters in
181 STRING, at location BEG. Optionally record adjustments for markers
182 in the region STRING occupies in the current buffer. */
152 183
153void 184void
154record_delete (ptrdiff_t beg, Lisp_Object string) 185record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
155{ 186{
156 Lisp_Object sbeg; 187 Lisp_Object sbeg;
157 188
@@ -169,34 +200,15 @@ record_delete (ptrdiff_t beg, Lisp_Object string)
169 record_point (beg); 200 record_point (beg);
170 } 201 }
171 202
172 bset_undo_list 203 /* primitive-undo assumes marker adjustments are recorded
173 (current_buffer, 204 immediately before the deletion is recorded. See bug 16818
174 Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list))); 205 discussion. */
175} 206 if (record_markers)
176 207 record_marker_adjustments (beg, beg + SCHARS (string));
177/* Record the fact that MARKER is about to be adjusted by ADJUSTMENT.
178 This is done only when a marker points within text being deleted,
179 because that's the only case where an automatic marker adjustment
180 won't be inverted automatically by undoing the buffer modification. */
181
182void
183record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
184{
185 if (EQ (BVAR (current_buffer, undo_list), Qt))
186 return;
187
188 /* Allocate a cons cell to be the undo boundary after this command. */
189 if (NILP (pending_boundary))
190 pending_boundary = Fcons (Qnil, Qnil);
191
192 if (current_buffer != last_undo_buffer)
193 Fundo_boundary ();
194 last_undo_buffer = current_buffer;
195 208
196 bset_undo_list 209 bset_undo_list
197 (current_buffer, 210 (current_buffer,
198 Fcons (Fcons (marker, make_number (adjustment)), 211 Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list)));
199 BVAR (current_buffer, undo_list)));
200} 212}
201 213
202/* Record that a replacement is about to take place, 214/* Record that a replacement is about to take place,
@@ -206,7 +218,7 @@ record_marker_adjustment (Lisp_Object marker, ptrdiff_t adjustment)
206void 218void
207record_change (ptrdiff_t beg, ptrdiff_t length) 219record_change (ptrdiff_t beg, ptrdiff_t length)
208{ 220{
209 record_delete (beg, make_buffer_string (beg, beg + length, 1)); 221 record_delete (beg, make_buffer_string (beg, beg + length, 1), false);
210 record_insert (beg, length); 222 record_insert (beg, length);
211} 223}
212 224