diff options
| author | Richard M. Stallman | 1998-01-01 07:03:19 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1998-01-01 07:03:19 +0000 |
| commit | 3be111318f0061aeceb2c65d83eaae8df5835717 (patch) | |
| tree | e0e27221744447c178a68b508fe8efa91b2cb538 /src | |
| parent | 604ee0f3ab62615ed6cdc7146aa5f1fe9d042351 (diff) | |
| download | emacs-3be111318f0061aeceb2c65d83eaae8df5835717.tar.gz emacs-3be111318f0061aeceb2c65d83eaae8df5835717.zip | |
(move_gap): Use move_gap_both.
(move_gap_both): New function.
(gap_left, gap_right): Take both charpos and bytepos args.
(adjust_markers_gap_motion): Renamed from adjust_markers and simplified.
(adjust_markers_for_delete): New function.
(adjust_markers_for_insert): Take args in chars and bytes.
Also new arg BEFORE_MARKERS. One call does all marker updating
needed for any insert.
(adjust_point): Take 2 args and update PT and PT_BYTE.
(make_gap): Handle bytes vs chars.
(insert, insert_and_inherit): Handle bytes vs chars.
Pass new BEFORE_MARKERS arg to insert_1.
(insert_before_markers, insert_before_markers_and_inherit): Likewise.
(insert_from_string, insert_from_string_before_markers): Likewise.
(insert_from_buffer): Likewise.
(insert_1): Handle bytes vs chars. New arg BEFORE_MARKERS.
(insert_from_string_1, insert_from_buffer_1): Likewise.
(replace_range): Likewise.
(del_range_2): New subroutine, taken from del_range_1.
(del_range_1): Use del_range_2.
(del_range_byte, del_range_both): New functions.
Diffstat (limited to 'src')
| -rw-r--r-- | src/insdel.c | 936 |
1 files changed, 613 insertions, 323 deletions
diff --git a/src/insdel.c b/src/insdel.c index a001c81bd99..1d69d541001 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Buffer insertion/deletion and gap motion for GNU Emacs. | 1 | /* Buffer insertion/deletion and gap motion for GNU Emacs. |
| 2 | Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc. | 2 | Copyright (C) 1985, 86, 93, 94, 95, 1997 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This file is part of GNU Emacs. | 4 | This file is part of GNU Emacs. |
| 5 | 5 | ||
| @@ -33,12 +33,14 @@ Boston, MA 02111-1307, USA. */ | |||
| 33 | 33 | ||
| 34 | #define min(x, y) ((x) < (y) ? (x) : (y)) | 34 | #define min(x, y) ((x) < (y) ? (x) : (y)) |
| 35 | 35 | ||
| 36 | static void insert_from_string_1 (); | 36 | static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int)); |
| 37 | static void insert_from_buffer_1 (); | 37 | static void insert_from_buffer_1 (); |
| 38 | static void gap_left (); | 38 | static void gap_left P_ ((int, int, int)); |
| 39 | static void gap_right (); | 39 | static void gap_right P_ ((int, int)); |
| 40 | static void adjust_markers (); | 40 | static void adjust_markers_gap_motion P_ ((int, int, int)); |
| 41 | static void adjust_point (); | 41 | static void adjust_markers_for_insert P_ ((int, int, int, int, int)); |
| 42 | static void adjust_markers_for_delete P_ ((int, int, int, int)); | ||
| 43 | static void adjust_point P_ ((int, int)); | ||
| 42 | 44 | ||
| 43 | Lisp_Object Fcombine_after_change_execute (); | 45 | Lisp_Object Fcombine_after_change_execute (); |
| 44 | 46 | ||
| @@ -61,54 +63,64 @@ Lisp_Object combine_after_change_list; | |||
| 61 | /* Buffer which combine_after_change_list is about. */ | 63 | /* Buffer which combine_after_change_list is about. */ |
| 62 | Lisp_Object combine_after_change_buffer; | 64 | Lisp_Object combine_after_change_buffer; |
| 63 | 65 | ||
| 64 | /* Move gap to position `pos'. | 66 | /* Move gap to position CHARPOS. |
| 65 | Note that this can quit! */ | 67 | Note that this can quit! */ |
| 66 | 68 | ||
| 67 | void | 69 | void |
| 68 | move_gap (pos) | 70 | move_gap (charpos) |
| 69 | int pos; | 71 | int charpos; |
| 70 | { | 72 | { |
| 71 | if (pos < GPT) | 73 | move_gap_both (charpos, charpos_to_bytepos (charpos)); |
| 72 | gap_left (pos, 0); | ||
| 73 | else if (pos > GPT) | ||
| 74 | gap_right (pos); | ||
| 75 | } | 74 | } |
| 76 | 75 | ||
| 77 | /* Move the gap to POS, which is less than the current GPT. | 76 | /* Move gap to byte position BYTEPOS, which is also char position CHARPOS. |
| 77 | Note that this can quit! */ | ||
| 78 | |||
| 79 | void | ||
| 80 | move_gap_both (charpos, bytepos) | ||
| 81 | int charpos, bytepos; | ||
| 82 | { | ||
| 83 | if (bytepos < GPT_BYTE) | ||
| 84 | gap_left (charpos, bytepos, 0); | ||
| 85 | else if (bytepos > GPT_BYTE) | ||
| 86 | gap_right (charpos, bytepos); | ||
| 87 | } | ||
| 88 | |||
| 89 | /* Move the gap to a position less than the current GPT. | ||
| 90 | BYTEPOS describes the new position as a byte position, | ||
| 91 | and CHARPOS is the corresponding char position. | ||
| 78 | If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */ | 92 | If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */ |
| 79 | 93 | ||
| 80 | static void | 94 | static void |
| 81 | gap_left (pos, newgap) | 95 | gap_left (charpos, bytepos, newgap) |
| 82 | register int pos; | 96 | register int charpos, bytepos; |
| 83 | int newgap; | 97 | int newgap; |
| 84 | { | 98 | { |
| 85 | register unsigned char *to, *from; | 99 | register unsigned char *to, *from; |
| 86 | register int i; | 100 | register int i; |
| 87 | int new_s1; | 101 | int new_s1; |
| 88 | 102 | ||
| 89 | pos--; | ||
| 90 | |||
| 91 | if (!newgap) | 103 | if (!newgap) |
| 92 | { | 104 | { |
| 93 | if (unchanged_modified == MODIFF | 105 | if (unchanged_modified == MODIFF |
| 94 | && overlay_unchanged_modified == OVERLAY_MODIFF) | 106 | && overlay_unchanged_modified == OVERLAY_MODIFF) |
| 95 | { | 107 | { |
| 96 | beg_unchanged = pos; | 108 | beg_unchanged = charpos - BEG; |
| 97 | end_unchanged = Z - pos - 1; | 109 | end_unchanged = Z - charpos; |
| 98 | } | 110 | } |
| 99 | else | 111 | else |
| 100 | { | 112 | { |
| 101 | if (Z - GPT < end_unchanged) | 113 | if (Z - GPT < end_unchanged) |
| 102 | end_unchanged = Z - GPT; | 114 | end_unchanged = Z - GPT; |
| 103 | if (pos < beg_unchanged) | 115 | if (charpos < beg_unchanged) |
| 104 | beg_unchanged = pos; | 116 | beg_unchanged = charpos - BEG; |
| 105 | } | 117 | } |
| 106 | } | 118 | } |
| 107 | 119 | ||
| 108 | i = GPT; | 120 | i = GPT_BYTE; |
| 109 | to = GAP_END_ADDR; | 121 | to = GAP_END_ADDR; |
| 110 | from = GPT_ADDR; | 122 | from = GPT_ADDR; |
| 111 | new_s1 = GPT - BEG; | 123 | new_s1 = GPT_BYTE; |
| 112 | 124 | ||
| 113 | /* Now copy the characters. To move the gap down, | 125 | /* Now copy the characters. To move the gap down, |
| 114 | copy characters up. */ | 126 | copy characters up. */ |
| @@ -116,14 +128,15 @@ gap_left (pos, newgap) | |||
| 116 | while (1) | 128 | while (1) |
| 117 | { | 129 | { |
| 118 | /* I gets number of characters left to copy. */ | 130 | /* I gets number of characters left to copy. */ |
| 119 | i = new_s1 - pos; | 131 | i = new_s1 - bytepos; |
| 120 | if (i == 0) | 132 | if (i == 0) |
| 121 | break; | 133 | break; |
| 122 | /* If a quit is requested, stop copying now. | 134 | /* If a quit is requested, stop copying now. |
| 123 | Change POS to be where we have actually moved the gap to. */ | 135 | Change BYTEPOS to be where we have actually moved the gap to. */ |
| 124 | if (QUITP) | 136 | if (QUITP) |
| 125 | { | 137 | { |
| 126 | pos = new_s1; | 138 | bytepos = new_s1; |
| 139 | charpos = BYTE_TO_CHAR (bytepos); | ||
| 127 | break; | 140 | break; |
| 128 | } | 141 | } |
| 129 | /* Move at most 32000 chars before checking again for a quit. */ | 142 | /* Move at most 32000 chars before checking again for a quit. */ |
| @@ -153,44 +166,48 @@ gap_left (pos, newgap) | |||
| 153 | } | 166 | } |
| 154 | } | 167 | } |
| 155 | 168 | ||
| 156 | /* Adjust markers, and buffer data structure, to put the gap at POS. | 169 | /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS. |
| 157 | POS is where the loop above stopped, which may be what was specified | 170 | BYTEPOS is where the loop above stopped, which may be what was specified |
| 158 | or may be where a quit was detected. */ | 171 | or may be where a quit was detected. */ |
| 159 | adjust_markers (pos + 1, GPT, GAP_SIZE); | 172 | adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE); |
| 160 | GPT = pos + 1; | 173 | GPT_BYTE = bytepos; |
| 174 | GPT = charpos; | ||
| 175 | if (bytepos < charpos) | ||
| 176 | abort (); | ||
| 161 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 177 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 162 | QUIT; | 178 | QUIT; |
| 163 | } | 179 | } |
| 164 | 180 | ||
| 181 | /* Move the gap to a position greater than than the current GPT. | ||
| 182 | BYTEPOS describes the new position as a byte position, | ||
| 183 | and CHARPOS is the corresponding char position. */ | ||
| 184 | |||
| 165 | static void | 185 | static void |
| 166 | gap_right (pos) | 186 | gap_right (charpos, bytepos) |
| 167 | register int pos; | 187 | register int charpos, bytepos; |
| 168 | { | 188 | { |
| 169 | register unsigned char *to, *from; | 189 | register unsigned char *to, *from; |
| 170 | register int i; | 190 | register int i; |
| 171 | int new_s1; | 191 | int new_s1; |
| 172 | 192 | ||
| 173 | pos--; | ||
| 174 | |||
| 175 | if (unchanged_modified == MODIFF | 193 | if (unchanged_modified == MODIFF |
| 176 | && overlay_unchanged_modified == OVERLAY_MODIFF) | 194 | && overlay_unchanged_modified == OVERLAY_MODIFF) |
| 177 | |||
| 178 | { | 195 | { |
| 179 | beg_unchanged = pos; | 196 | beg_unchanged = charpos - BEG; |
| 180 | end_unchanged = Z - pos - 1; | 197 | end_unchanged = Z - charpos; |
| 181 | } | 198 | } |
| 182 | else | 199 | else |
| 183 | { | 200 | { |
| 184 | if (Z - pos - 1 < end_unchanged) | 201 | if (Z - charpos - 1 < end_unchanged) |
| 185 | end_unchanged = Z - pos - 1; | 202 | end_unchanged = Z - charpos; |
| 186 | if (GPT - BEG < beg_unchanged) | 203 | if (GPT - BEG < beg_unchanged) |
| 187 | beg_unchanged = GPT - BEG; | 204 | beg_unchanged = GPT - BEG; |
| 188 | } | 205 | } |
| 189 | 206 | ||
| 190 | i = GPT; | 207 | i = GPT_BYTE; |
| 191 | from = GAP_END_ADDR; | 208 | from = GAP_END_ADDR; |
| 192 | to = GPT_ADDR; | 209 | to = GPT_ADDR; |
| 193 | new_s1 = GPT - 1; | 210 | new_s1 = GPT_BYTE; |
| 194 | 211 | ||
| 195 | /* Now copy the characters. To move the gap up, | 212 | /* Now copy the characters. To move the gap up, |
| 196 | copy characters down. */ | 213 | copy characters down. */ |
| @@ -198,14 +215,15 @@ gap_right (pos) | |||
| 198 | while (1) | 215 | while (1) |
| 199 | { | 216 | { |
| 200 | /* I gets number of characters left to copy. */ | 217 | /* I gets number of characters left to copy. */ |
| 201 | i = pos - new_s1; | 218 | i = bytepos - new_s1; |
| 202 | if (i == 0) | 219 | if (i == 0) |
| 203 | break; | 220 | break; |
| 204 | /* If a quit is requested, stop copying now. | 221 | /* If a quit is requested, stop copying now. |
| 205 | Change POS to be where we have actually moved the gap to. */ | 222 | Change BYTEPOS to be where we have actually moved the gap to. */ |
| 206 | if (QUITP) | 223 | if (QUITP) |
| 207 | { | 224 | { |
| 208 | pos = new_s1; | 225 | bytepos = new_s1; |
| 226 | charpos = BYTE_TO_CHAR (bytepos); | ||
| 209 | break; | 227 | break; |
| 210 | } | 228 | } |
| 211 | /* Move at most 32000 chars before checking again for a quit. */ | 229 | /* Move at most 32000 chars before checking again for a quit. */ |
| @@ -235,14 +253,18 @@ gap_right (pos) | |||
| 235 | } | 253 | } |
| 236 | } | 254 | } |
| 237 | 255 | ||
| 238 | adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE); | 256 | adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE, |
| 239 | GPT = pos + 1; | 257 | - GAP_SIZE); |
| 258 | GPT = charpos; | ||
| 259 | GPT_BYTE = bytepos; | ||
| 260 | if (bytepos < charpos) | ||
| 261 | abort (); | ||
| 240 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 262 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 241 | QUIT; | 263 | QUIT; |
| 242 | } | 264 | } |
| 243 | 265 | ||
| 244 | /* Add AMOUNT to the position of every marker in the current buffer | 266 | /* Add AMOUNT to the byte position of every marker in the current buffer |
| 245 | whose current position is between FROM (exclusive) and TO (inclusive). | 267 | whose current byte position is between FROM (exclusive) and TO (inclusive). |
| 246 | 268 | ||
| 247 | Also, any markers past the outside of that interval, in the direction | 269 | Also, any markers past the outside of that interval, in the direction |
| 248 | of adjustment, are first moved back to the near end of the interval | 270 | of adjustment, are first moved back to the near end of the interval |
| @@ -250,10 +272,15 @@ gap_right (pos) | |||
| 250 | 272 | ||
| 251 | When the latter adjustment is done, if AMOUNT is negative, | 273 | When the latter adjustment is done, if AMOUNT is negative, |
| 252 | we record the adjustment for undo. (This case happens only for | 274 | we record the adjustment for undo. (This case happens only for |
| 253 | deletion.) */ | 275 | deletion.) |
| 276 | |||
| 277 | The markers' character positions are not altered, | ||
| 278 | because gap motion does not affect character positions. */ | ||
| 279 | |||
| 280 | int adjust_markers_test; | ||
| 254 | 281 | ||
| 255 | static void | 282 | static void |
| 256 | adjust_markers (from, to, amount) | 283 | adjust_markers_gap_motion (from, to, amount) |
| 257 | register int from, to, amount; | 284 | register int from, to, amount; |
| 258 | { | 285 | { |
| 259 | Lisp_Object marker; | 286 | Lisp_Object marker; |
| @@ -269,7 +296,11 @@ adjust_markers (from, to, amount) | |||
| 269 | if (amount > 0) | 296 | if (amount > 0) |
| 270 | { | 297 | { |
| 271 | if (mpos > to && mpos < to + amount) | 298 | if (mpos > to && mpos < to + amount) |
| 272 | mpos = to + amount; | 299 | { |
| 300 | if (adjust_markers_test) | ||
| 301 | abort (); | ||
| 302 | mpos = to + amount; | ||
| 303 | } | ||
| 273 | } | 304 | } |
| 274 | else | 305 | else |
| 275 | { | 306 | { |
| @@ -278,24 +309,9 @@ adjust_markers (from, to, amount) | |||
| 278 | but then this range contains no markers. */ | 309 | but then this range contains no markers. */ |
| 279 | if (mpos > from + amount && mpos <= from) | 310 | if (mpos > from + amount && mpos <= from) |
| 280 | { | 311 | { |
| 281 | int before = mpos; | 312 | if (adjust_markers_test) |
| 282 | int after = from + amount; | 313 | abort (); |
| 283 | 314 | mpos = from + amount; | |
| 284 | mpos = after; | ||
| 285 | |||
| 286 | /* Compute the before and after positions | ||
| 287 | as buffer positions. */ | ||
| 288 | if (before > GPT + GAP_SIZE) | ||
| 289 | before -= GAP_SIZE; | ||
| 290 | else if (before > GPT) | ||
| 291 | before = GPT; | ||
| 292 | |||
| 293 | if (after > GPT + GAP_SIZE) | ||
| 294 | after -= GAP_SIZE; | ||
| 295 | else if (after > GPT) | ||
| 296 | after = GPT; | ||
| 297 | |||
| 298 | record_marker_adjustment (marker, after - before); | ||
| 299 | } | 315 | } |
| 300 | } | 316 | } |
| 301 | if (mpos > from && mpos <= to) | 317 | if (mpos > from && mpos <= to) |
| @@ -305,73 +321,177 @@ adjust_markers (from, to, amount) | |||
| 305 | } | 321 | } |
| 306 | } | 322 | } |
| 307 | 323 | ||
| 308 | /* Adjust markers whose insertion-type is t | 324 | /* Adjust all markers for a deletion |
| 309 | for an insertion of AMOUNT characters at POS. */ | 325 | whose range in bytes is FROM_BYTE to TO_BYTE. |
| 326 | The range in charpos is FROM to TO. | ||
| 327 | |||
| 328 | This function assumes that the gap is adjacent to | ||
| 329 | or inside of the range being deleted. */ | ||
| 310 | 330 | ||
| 311 | static void | 331 | static void |
| 312 | adjust_markers_for_insert (pos, amount) | 332 | adjust_markers_for_delete (from, from_byte, to, to_byte) |
| 313 | register int pos, amount; | 333 | register int from, from_byte, to, to_byte; |
| 334 | { | ||
| 335 | Lisp_Object marker; | ||
| 336 | register struct Lisp_Marker *m; | ||
| 337 | register int charpos; | ||
| 338 | /* This is what GAP_SIZE will be when this deletion is finished. */ | ||
| 339 | int coming_gap_size = GAP_SIZE + to_byte - from_byte; | ||
| 340 | |||
| 341 | marker = BUF_MARKERS (current_buffer); | ||
| 342 | |||
| 343 | while (!NILP (marker)) | ||
| 344 | { | ||
| 345 | m = XMARKER (marker); | ||
| 346 | charpos = m->charpos; | ||
| 347 | |||
| 348 | if (charpos > Z) | ||
| 349 | abort (); | ||
| 350 | |||
| 351 | /* If the marker is after the deletion, | ||
| 352 | its bufpos needs no change because the deleted text | ||
| 353 | becomes gap; but its charpos needs to be decreased. */ | ||
| 354 | if (charpos > to) | ||
| 355 | m->charpos -= to - from; | ||
| 356 | |||
| 357 | /* Here's the case where a marker is inside text being deleted. | ||
| 358 | We take advantage of the fact that the deletion is at the gap. */ | ||
| 359 | else if (charpos > from) | ||
| 360 | { | ||
| 361 | record_marker_adjustment (marker, from - charpos); | ||
| 362 | m->charpos = from; | ||
| 363 | /* The gap must be at or after FROM_BYTE when we do a deletion. */ | ||
| 364 | m->bufpos = from_byte; | ||
| 365 | } | ||
| 366 | |||
| 367 | /* In a single-byte buffer, a marker's two positions must be equal. */ | ||
| 368 | if (Z == Z_BYTE) | ||
| 369 | { | ||
| 370 | register int i = m->bufpos; | ||
| 371 | |||
| 372 | /* We use FROM_BYTE here instead of GPT_BYTE | ||
| 373 | because FROM_BYTE is where the gap will be after the deletion. */ | ||
| 374 | if (i > from_byte + coming_gap_size) | ||
| 375 | i -= coming_gap_size; | ||
| 376 | else if (i > from_byte) | ||
| 377 | i = from_byte; | ||
| 378 | |||
| 379 | if (m->charpos != i) | ||
| 380 | abort (); | ||
| 381 | } | ||
| 382 | |||
| 383 | marker = m->chain; | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | /* Adjust markers for an insertion at CHARPOS / BYTEPOS | ||
| 388 | consisting of NCHARS chars, which are NBYTES bytes. | ||
| 389 | |||
| 390 | We have to relocate the charpos of every marker that points | ||
| 391 | after the insertion (but not their bufpos). | ||
| 392 | |||
| 393 | When a marker points at the insertion point, | ||
| 394 | we advance it if either its insertion-type is t | ||
| 395 | or BEFORE_MARKERS is true. */ | ||
| 396 | |||
| 397 | static void | ||
| 398 | adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers) | ||
| 399 | register int from, from_byte, to, to_byte, before_markers; | ||
| 314 | { | 400 | { |
| 315 | Lisp_Object marker; | 401 | Lisp_Object marker; |
| 316 | int adjusted = 0; | 402 | int adjusted = 0; |
| 403 | int nchars = to - from; | ||
| 404 | int nbytes = to_byte - from_byte; | ||
| 317 | 405 | ||
| 318 | marker = BUF_MARKERS (current_buffer); | 406 | marker = BUF_MARKERS (current_buffer); |
| 319 | 407 | ||
| 320 | while (!NILP (marker)) | 408 | while (!NILP (marker)) |
| 321 | { | 409 | { |
| 322 | register struct Lisp_Marker *m = XMARKER (marker); | 410 | register struct Lisp_Marker *m = XMARKER (marker); |
| 323 | if (m->insertion_type && m->bufpos == pos) | 411 | if (m->bufpos == from_byte |
| 412 | && (m->insertion_type || before_markers)) | ||
| 324 | { | 413 | { |
| 325 | m->bufpos += amount; | 414 | m->bufpos += nbytes; |
| 326 | adjusted = 1; | 415 | m->charpos += nchars; |
| 416 | if (m->insertion_type) | ||
| 417 | adjusted = 1; | ||
| 327 | } | 418 | } |
| 419 | else if (m->bufpos > from_byte) | ||
| 420 | m->charpos += nchars; | ||
| 421 | |||
| 422 | /* In a single-byte buffer, a marker's two positions must be equal. */ | ||
| 423 | if (Z == Z_BYTE) | ||
| 424 | { | ||
| 425 | register int i = m->bufpos; | ||
| 426 | |||
| 427 | if (i > GPT_BYTE + GAP_SIZE) | ||
| 428 | i -= GAP_SIZE; | ||
| 429 | else if (i > GPT_BYTE) | ||
| 430 | i = GPT_BYTE; | ||
| 431 | |||
| 432 | if (m->charpos != i) | ||
| 433 | abort (); | ||
| 434 | } | ||
| 435 | |||
| 328 | marker = m->chain; | 436 | marker = m->chain; |
| 329 | } | 437 | } |
| 438 | |||
| 439 | /* Adjusting only markers whose insertion-type is t may result in | ||
| 440 | disordered overlays in the slot `overlays_before'. */ | ||
| 330 | if (adjusted) | 441 | if (adjusted) |
| 331 | /* Adjusting only markers whose insertion-type is t may result in | 442 | fix_overlays_before (current_buffer, from, to); |
| 332 | disordered overlays in the slot `overlays_before'. */ | ||
| 333 | fix_overlays_before (current_buffer, pos, pos + amount); | ||
| 334 | } | 443 | } |
| 335 | 444 | ||
| 336 | /* Add the specified amount to point. This is used only when the value | 445 | /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters. |
| 337 | of point changes due to an insert or delete; it does not represent | 446 | |
| 338 | a conceptual change in point as a marker. In particular, point is | 447 | This is used only when the value of point changes due to an insert |
| 339 | not crossing any interval boundaries, so there's no need to use the | 448 | or delete; it does not represent a conceptual change in point as a |
| 340 | usual SET_PT macro. In fact it would be incorrect to do so, because | 449 | marker. In particular, point is not crossing any interval |
| 341 | either the old or the new value of point is out of sync with the | 450 | boundaries, so there's no need to use the usual SET_PT macro. In |
| 342 | current set of intervals. */ | 451 | fact it would be incorrect to do so, because either the old or the |
| 452 | new value of point is out of sync with the current set of | ||
| 453 | intervals. */ | ||
| 454 | |||
| 343 | static void | 455 | static void |
| 344 | adjust_point (amount) | 456 | adjust_point (nchars, nbytes) |
| 345 | int amount; | 457 | int nchars, nbytes; |
| 346 | { | 458 | { |
| 347 | BUF_PT (current_buffer) += amount; | 459 | BUF_PT (current_buffer) += nchars; |
| 460 | BUF_PT_BYTE (current_buffer) += nbytes; | ||
| 461 | |||
| 462 | /* In a single-byte buffer, the two positions must be equal. */ | ||
| 463 | if (ZV == ZV_BYTE | ||
| 464 | && PT != PT_BYTE) | ||
| 465 | abort (); | ||
| 348 | } | 466 | } |
| 349 | 467 | ||
| 350 | /* Make the gap INCREMENT characters longer. */ | 468 | /* Make the gap NBYTES_ADDED bytes longer. */ |
| 351 | 469 | ||
| 352 | void | 470 | void |
| 353 | make_gap (increment) | 471 | make_gap (nbytes_added) |
| 354 | int increment; | 472 | int nbytes_added; |
| 355 | { | 473 | { |
| 356 | unsigned char *result; | 474 | unsigned char *result; |
| 357 | Lisp_Object tem; | 475 | Lisp_Object tem; |
| 358 | int real_gap_loc; | 476 | int real_gap_loc; |
| 477 | int real_gap_loc_byte; | ||
| 359 | int old_gap_size; | 478 | int old_gap_size; |
| 360 | 479 | ||
| 361 | /* If we have to get more space, get enough to last a while. */ | 480 | /* If we have to get more space, get enough to last a while. */ |
| 362 | increment += 2000; | 481 | nbytes_added += 2000; |
| 363 | 482 | ||
| 364 | /* Don't allow a buffer size that won't fit in an int | 483 | /* Don't allow a buffer size that won't fit in an int |
| 365 | even if it will fit in a Lisp integer. | 484 | even if it will fit in a Lisp integer. |
| 366 | That won't work because so many places use `int'. */ | 485 | That won't work because so many places use `int'. */ |
| 367 | 486 | ||
| 368 | if (Z - BEG + GAP_SIZE + increment | 487 | if (Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added |
| 369 | >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1))) | 488 | >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1))) |
| 370 | error ("Buffer exceeds maximum size"); | 489 | error ("Buffer exceeds maximum size"); |
| 371 | 490 | ||
| 372 | BLOCK_INPUT; | 491 | BLOCK_INPUT; |
| 373 | /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */ | 492 | /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */ |
| 374 | result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment + 1)); | 493 | result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE |
| 494 | + GAP_SIZE + nbytes_added + 1)); | ||
| 375 | 495 | ||
| 376 | if (result == 0) | 496 | if (result == 0) |
| 377 | { | 497 | { |
| @@ -388,19 +508,21 @@ make_gap (increment) | |||
| 388 | Vinhibit_quit = Qt; | 508 | Vinhibit_quit = Qt; |
| 389 | 509 | ||
| 390 | real_gap_loc = GPT; | 510 | real_gap_loc = GPT; |
| 511 | real_gap_loc_byte = GPT_BYTE; | ||
| 391 | old_gap_size = GAP_SIZE; | 512 | old_gap_size = GAP_SIZE; |
| 392 | 513 | ||
| 393 | /* Call the newly allocated space a gap at the end of the whole space. */ | 514 | /* Call the newly allocated space a gap at the end of the whole space. */ |
| 394 | GPT = Z + GAP_SIZE; | 515 | GPT = Z + GAP_SIZE; |
| 395 | GAP_SIZE = increment; | 516 | GAP_SIZE = nbytes_added; |
| 396 | 517 | ||
| 397 | /* Move the new gap down to be consecutive with the end of the old one. | 518 | /* Move the new gap down to be consecutive with the end of the old one. |
| 398 | This adjusts the markers properly too. */ | 519 | This adjusts the markers properly too. */ |
| 399 | gap_left (real_gap_loc + old_gap_size, 1); | 520 | gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); |
| 400 | 521 | ||
| 401 | /* Now combine the two into one large gap. */ | 522 | /* Now combine the two into one large gap. */ |
| 402 | GAP_SIZE += old_gap_size; | 523 | GAP_SIZE += old_gap_size; |
| 403 | GPT = real_gap_loc; | 524 | GPT = real_gap_loc; |
| 525 | GPT_BYTE = real_gap_loc_byte; | ||
| 404 | 526 | ||
| 405 | /* Put an anchor. */ | 527 | /* Put an anchor. */ |
| 406 | *(Z_ADDR) = 0; | 528 | *(Z_ADDR) = 0; |
| @@ -413,72 +535,138 @@ make_gap (increment) | |||
| 413 | prepare_to_modify_buffer could relocate the text. */ | 535 | prepare_to_modify_buffer could relocate the text. */ |
| 414 | 536 | ||
| 415 | void | 537 | void |
| 416 | insert (string, length) | 538 | insert (string, nbytes) |
| 417 | register unsigned char *string; | 539 | register unsigned char *string; |
| 418 | register length; | 540 | register nbytes; |
| 419 | { | 541 | { |
| 420 | if (length > 0) | 542 | if (nbytes > 0) |
| 421 | { | 543 | { |
| 422 | insert_1 (string, length, 0, 1); | 544 | int opoint = PT; |
| 423 | signal_after_change (PT-length, 0, length); | 545 | insert_1 (string, nbytes, 0, 1, 0); |
| 546 | signal_after_change (opoint, 0, PT - opoint); | ||
| 424 | } | 547 | } |
| 425 | } | 548 | } |
| 426 | 549 | ||
| 427 | void | 550 | void |
| 428 | insert_and_inherit (string, length) | 551 | insert_and_inherit (string, nbytes) |
| 429 | register unsigned char *string; | 552 | register unsigned char *string; |
| 430 | register length; | 553 | register nbytes; |
| 431 | { | 554 | { |
| 432 | if (length > 0) | 555 | if (nbytes > 0) |
| 433 | { | 556 | { |
| 434 | insert_1 (string, length, 1, 1); | 557 | int opoint = PT; |
| 435 | signal_after_change (PT-length, 0, length); | 558 | insert_1 (string, nbytes, 1, 1, 0); |
| 559 | signal_after_change (opoint, 0, PT - opoint); | ||
| 436 | } | 560 | } |
| 437 | } | 561 | } |
| 438 | 562 | ||
| 563 | /* Insert the character C before point */ | ||
| 564 | |||
| 439 | void | 565 | void |
| 440 | insert_1 (string, length, inherit, prepare) | 566 | insert_char (c) |
| 567 | int c; | ||
| 568 | { | ||
| 569 | unsigned char workbuf[4], *str; | ||
| 570 | int len = CHAR_STRING (c, workbuf, str); | ||
| 571 | |||
| 572 | insert (str, len); | ||
| 573 | } | ||
| 574 | |||
| 575 | /* Insert the null-terminated string S before point */ | ||
| 576 | |||
| 577 | void | ||
| 578 | insert_string (s) | ||
| 579 | char *s; | ||
| 580 | { | ||
| 581 | insert (s, strlen (s)); | ||
| 582 | } | ||
| 583 | |||
| 584 | /* Like `insert' except that all markers pointing at the place where | ||
| 585 | the insertion happens are adjusted to point after it. | ||
| 586 | Don't use this function to insert part of a Lisp string, | ||
| 587 | since gc could happen and relocate it. */ | ||
| 588 | |||
| 589 | void | ||
| 590 | insert_before_markers (string, nbytes) | ||
| 591 | unsigned char *string; | ||
| 592 | register int nbytes; | ||
| 593 | { | ||
| 594 | if (nbytes > 0) | ||
| 595 | { | ||
| 596 | int opoint = PT; | ||
| 597 | |||
| 598 | insert_1 (string, nbytes, 0, 1, 1); | ||
| 599 | signal_after_change (opoint, 0, PT - opoint); | ||
| 600 | } | ||
| 601 | } | ||
| 602 | |||
| 603 | void | ||
| 604 | insert_before_markers_and_inherit (string, nbytes) | ||
| 605 | unsigned char *string; | ||
| 606 | register int nbytes; | ||
| 607 | { | ||
| 608 | if (nbytes > 0) | ||
| 609 | { | ||
| 610 | int opoint = PT; | ||
| 611 | |||
| 612 | insert_1 (string, nbytes, 1, 1, 1); | ||
| 613 | signal_after_change (opoint, 0, PT - opoint); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | /* Subroutine used by the insert functions above. */ | ||
| 618 | |||
| 619 | void | ||
| 620 | insert_1 (string, nbytes, inherit, prepare, before_markers) | ||
| 441 | register unsigned char *string; | 621 | register unsigned char *string; |
| 442 | register int length; | 622 | register int nbytes; |
| 443 | int inherit, prepare; | 623 | int inherit, prepare, before_markers; |
| 444 | { | 624 | { |
| 445 | register Lisp_Object temp; | 625 | register Lisp_Object temp; |
| 626 | int nchars = chars_in_text (string, nbytes); | ||
| 446 | 627 | ||
| 447 | if (prepare) | 628 | if (prepare) |
| 448 | prepare_to_modify_buffer (PT, PT, NULL); | 629 | prepare_to_modify_buffer (PT, PT, NULL); |
| 449 | 630 | ||
| 450 | if (PT != GPT) | 631 | if (PT != GPT) |
| 451 | move_gap (PT); | 632 | move_gap_both (PT, PT_BYTE); |
| 452 | if (GAP_SIZE < length) | 633 | if (GAP_SIZE < nbytes) |
| 453 | make_gap (length - GAP_SIZE); | 634 | make_gap (nbytes - GAP_SIZE); |
| 454 | 635 | ||
| 455 | record_insert (PT, length); | 636 | record_insert (PT, nchars); |
| 456 | MODIFF++; | 637 | MODIFF++; |
| 457 | 638 | ||
| 458 | bcopy (string, GPT_ADDR, length); | 639 | bcopy (string, GPT_ADDR, nbytes); |
| 459 | 640 | ||
| 460 | #ifdef USE_TEXT_PROPERTIES | 641 | #ifdef USE_TEXT_PROPERTIES |
| 461 | if (BUF_INTERVALS (current_buffer) != 0) | 642 | if (BUF_INTERVALS (current_buffer) != 0) |
| 462 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ | 643 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ |
| 463 | offset_intervals (current_buffer, PT, length); | 644 | offset_intervals (current_buffer, PT, nchars); |
| 464 | #endif | 645 | #endif |
| 465 | 646 | ||
| 466 | GAP_SIZE -= length; | 647 | GAP_SIZE -= nbytes; |
| 467 | GPT += length; | 648 | GPT += nchars; |
| 468 | ZV += length; | 649 | ZV += nchars; |
| 469 | Z += length; | 650 | Z += nchars; |
| 651 | GPT_BYTE += nbytes; | ||
| 652 | ZV_BYTE += nbytes; | ||
| 653 | Z_BYTE += nbytes; | ||
| 470 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 654 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 471 | adjust_overlays_for_insert (PT, length); | 655 | adjust_overlays_for_insert (PT, nchars); |
| 472 | adjust_markers_for_insert (PT, length); | 656 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, |
| 473 | adjust_point (length); | 657 | before_markers); |
| 658 | adjust_point (nchars, nbytes); | ||
| 659 | |||
| 660 | if (GPT_BYTE < GPT) | ||
| 661 | abort (); | ||
| 474 | 662 | ||
| 475 | #ifdef USE_TEXT_PROPERTIES | 663 | #ifdef USE_TEXT_PROPERTIES |
| 476 | if (!inherit && BUF_INTERVALS (current_buffer) != 0) | 664 | if (!inherit && BUF_INTERVALS (current_buffer) != 0) |
| 477 | Fset_text_properties (make_number (PT - length), make_number (PT), | 665 | Fset_text_properties (make_number (PT - nchars), make_number (PT), |
| 478 | Qnil, Qnil); | 666 | Qnil, Qnil); |
| 479 | #endif | 667 | #endif |
| 480 | } | 668 | } |
| 481 | 669 | ||
| 482 | /* Insert the part of the text of STRING, a Lisp object assumed to be | 670 | /* Insert the part of the text of STRING, a Lisp object assumed to be |
| 483 | of type string, consisting of the LENGTH characters starting at | 671 | of type string, consisting of the LENGTH characters starting at |
| 484 | position POS. If the text of STRING has properties, they are absorbed | 672 | position POS. If the text of STRING has properties, they are absorbed |
| @@ -496,58 +684,91 @@ insert_from_string (string, pos, length, inherit) | |||
| 496 | { | 684 | { |
| 497 | if (length > 0) | 685 | if (length > 0) |
| 498 | { | 686 | { |
| 499 | insert_from_string_1 (string, pos, length, inherit); | 687 | int opoint = PT; |
| 500 | signal_after_change (PT-length, 0, length); | 688 | int nchars = chars_in_text (XSTRING (string)->data + pos, length); |
| 689 | insert_from_string_1 (string, pos, length, nchars, inherit, 0); | ||
| 690 | signal_after_change (opoint, 0, PT - opoint); | ||
| 501 | } | 691 | } |
| 502 | } | 692 | } |
| 503 | 693 | ||
| 504 | static void | 694 | /* Like `insert' except that all markers pointing at the place where |
| 505 | insert_from_string_1 (string, pos, length, inherit) | 695 | the insertion happens are adjusted to point after it. |
| 696 | Don't use this function to insert part of a Lisp string, | ||
| 697 | since gc could happen and relocate it. */ | ||
| 698 | |||
| 699 | /* Insert part of a Lisp string, relocating markers after. */ | ||
| 700 | |||
| 701 | void | ||
| 702 | insert_from_string_before_markers (string, pos, length, inherit) | ||
| 506 | Lisp_Object string; | 703 | Lisp_Object string; |
| 507 | register int pos, length; | 704 | register int pos, length; |
| 508 | int inherit; | 705 | int inherit; |
| 509 | { | 706 | { |
| 707 | if (length > 0) | ||
| 708 | { | ||
| 709 | int opoint = PT; | ||
| 710 | int nchars = chars_in_text (XSTRING (string)->data + pos, length); | ||
| 711 | insert_from_string_1 (string, pos, length, nchars, inherit, 1); | ||
| 712 | signal_after_change (opoint, 0, PT - opoint); | ||
| 713 | } | ||
| 714 | } | ||
| 715 | |||
| 716 | /* Subroutine of the insertion functions above. */ | ||
| 717 | |||
| 718 | static void | ||
| 719 | insert_from_string_1 (string, pos, nbytes, nchars, inherit, before_markers) | ||
| 720 | Lisp_Object string; | ||
| 721 | register int pos, nbytes, nchars; | ||
| 722 | int inherit, before_markers; | ||
| 723 | { | ||
| 510 | register Lisp_Object temp; | 724 | register Lisp_Object temp; |
| 511 | struct gcpro gcpro1; | 725 | struct gcpro gcpro1; |
| 512 | 726 | ||
| 513 | /* Make sure point-max won't overflow after this insertion. */ | 727 | /* Make sure point-max won't overflow after this insertion. */ |
| 514 | XSETINT (temp, length + Z); | 728 | XSETINT (temp, nbytes + Z_BYTE); |
| 515 | if (length + Z != XINT (temp)) | 729 | if (nbytes + Z_BYTE != XINT (temp)) |
| 516 | error ("maximum buffer size exceeded"); | 730 | error ("Maximum buffer size exceeded"); |
| 517 | 731 | ||
| 518 | GCPRO1 (string); | 732 | GCPRO1 (string); |
| 519 | prepare_to_modify_buffer (PT, PT, NULL); | 733 | prepare_to_modify_buffer (PT, PT, NULL); |
| 520 | 734 | ||
| 521 | if (PT != GPT) | 735 | if (PT != GPT) |
| 522 | move_gap (PT); | 736 | move_gap_both (PT, PT_BYTE); |
| 523 | if (GAP_SIZE < length) | 737 | if (GAP_SIZE < nbytes) |
| 524 | make_gap (length - GAP_SIZE); | 738 | make_gap (nbytes - GAP_SIZE); |
| 525 | 739 | ||
| 526 | record_insert (PT, length); | 740 | record_insert (PT, nchars); |
| 527 | MODIFF++; | 741 | MODIFF++; |
| 528 | UNGCPRO; | 742 | UNGCPRO; |
| 529 | 743 | ||
| 530 | bcopy (XSTRING (string)->data, GPT_ADDR, length); | 744 | bcopy (XSTRING (string)->data, GPT_ADDR, nbytes); |
| 531 | 745 | ||
| 532 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 746 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 533 | offset_intervals (current_buffer, PT, length); | 747 | offset_intervals (current_buffer, PT, nchars); |
| 534 | 748 | ||
| 535 | GAP_SIZE -= length; | 749 | GAP_SIZE -= nbytes; |
| 536 | GPT += length; | 750 | GPT += nchars; |
| 537 | ZV += length; | 751 | ZV += nchars; |
| 538 | Z += length; | 752 | Z += nchars; |
| 753 | GPT_BYTE += nbytes; | ||
| 754 | ZV_BYTE += nbytes; | ||
| 755 | Z_BYTE += nbytes; | ||
| 539 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 756 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 540 | adjust_overlays_for_insert (PT, length); | 757 | adjust_overlays_for_insert (PT, nchars); |
| 541 | adjust_markers_for_insert (PT, length); | 758 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, |
| 759 | before_markers); | ||
| 760 | |||
| 761 | if (GPT_BYTE < GPT) | ||
| 762 | abort (); | ||
| 542 | 763 | ||
| 543 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 764 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 544 | graft_intervals_into_buffer (XSTRING (string)->intervals, PT, length, | 765 | graft_intervals_into_buffer (XSTRING (string)->intervals, PT, nchars, |
| 545 | current_buffer, inherit); | 766 | current_buffer, inherit); |
| 546 | 767 | ||
| 547 | adjust_point (length); | 768 | adjust_point (nchars, nbytes); |
| 548 | } | 769 | } |
| 549 | 770 | ||
| 550 | /* Insert text from BUF, starting at POS and having length LENGTH, into the | 771 | /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the |
| 551 | current buffer. If the text in BUF has properties, they are absorbed | 772 | current buffer. If the text in BUF has properties, they are absorbed |
| 552 | into the current buffer. | 773 | into the current buffer. |
| 553 | 774 | ||
| @@ -555,147 +776,88 @@ insert_from_string_1 (string, pos, length, inherit) | |||
| 555 | and relocate BUF's text before the bcopy happens. */ | 776 | and relocate BUF's text before the bcopy happens. */ |
| 556 | 777 | ||
| 557 | void | 778 | void |
| 558 | insert_from_buffer (buf, pos, length, inherit) | 779 | insert_from_buffer (buf, charpos, nchars, inherit) |
| 559 | struct buffer *buf; | 780 | struct buffer *buf; |
| 560 | int pos, length; | 781 | int charpos, nchars; |
| 561 | int inherit; | 782 | int inherit; |
| 562 | { | 783 | { |
| 563 | if (length > 0) | 784 | if (nchars > 0) |
| 564 | { | 785 | { |
| 565 | insert_from_buffer_1 (buf, pos, length, inherit); | 786 | int opoint = PT; |
| 566 | signal_after_change (PT-length, 0, length); | 787 | |
| 788 | insert_from_buffer_1 (buf, charpos, nchars, inherit); | ||
| 789 | signal_after_change (opoint, 0, PT - opoint); | ||
| 567 | } | 790 | } |
| 568 | } | 791 | } |
| 569 | 792 | ||
| 570 | static void | 793 | static void |
| 571 | insert_from_buffer_1 (buf, pos, length, inherit) | 794 | insert_from_buffer_1 (buf, from, nchars, inherit) |
| 572 | struct buffer *buf; | 795 | struct buffer *buf; |
| 573 | int pos, length; | 796 | int from, nchars; |
| 574 | int inherit; | 797 | int inherit; |
| 575 | { | 798 | { |
| 576 | register Lisp_Object temp; | 799 | register Lisp_Object temp; |
| 577 | int chunk; | 800 | int chunk; |
| 801 | int from_byte = buf_charpos_to_bytepos (buf, from); | ||
| 802 | int to_byte = buf_charpos_to_bytepos (buf, from + nchars); | ||
| 803 | int nbytes = to_byte - from_byte; | ||
| 578 | 804 | ||
| 579 | /* Make sure point-max won't overflow after this insertion. */ | 805 | /* Make sure point-max won't overflow after this insertion. */ |
| 580 | XSETINT (temp, length + Z); | 806 | XSETINT (temp, nbytes + Z); |
| 581 | if (length + Z != XINT (temp)) | 807 | if (nbytes + Z != XINT (temp)) |
| 582 | error ("maximum buffer size exceeded"); | 808 | error ("Maximum buffer size exceeded"); |
| 583 | 809 | ||
| 584 | prepare_to_modify_buffer (PT, PT, NULL); | 810 | prepare_to_modify_buffer (PT, PT, NULL); |
| 585 | 811 | ||
| 586 | if (PT != GPT) | 812 | if (PT != GPT) |
| 587 | move_gap (PT); | 813 | move_gap_both (PT, PT_BYTE); |
| 588 | if (GAP_SIZE < length) | 814 | if (GAP_SIZE < nbytes) |
| 589 | make_gap (length - GAP_SIZE); | 815 | make_gap (nbytes - GAP_SIZE); |
| 590 | 816 | ||
| 591 | record_insert (PT, length); | 817 | record_insert (PT, nchars); |
| 592 | MODIFF++; | 818 | MODIFF++; |
| 593 | 819 | ||
| 594 | if (pos < BUF_GPT (buf)) | 820 | if (from < BUF_GPT (buf)) |
| 595 | { | 821 | { |
| 596 | chunk = BUF_GPT (buf) - pos; | 822 | chunk = BUF_GPT_BYTE (buf) - from_byte; |
| 597 | if (chunk > length) | 823 | if (chunk > nbytes) |
| 598 | chunk = length; | 824 | chunk = nbytes; |
| 599 | bcopy (BUF_CHAR_ADDRESS (buf, pos), GPT_ADDR, chunk); | 825 | bcopy (BUF_BYTE_ADDRESS (buf, from_byte), GPT_ADDR, chunk); |
| 600 | } | 826 | } |
| 601 | else | 827 | else |
| 602 | chunk = 0; | 828 | chunk = 0; |
| 603 | if (chunk < length) | 829 | if (chunk < nbytes) |
| 604 | bcopy (BUF_CHAR_ADDRESS (buf, pos + chunk), | 830 | bcopy (BUF_BYTE_ADDRESS (buf, from_byte + chunk), |
| 605 | GPT_ADDR + chunk, length - chunk); | 831 | GPT_ADDR + chunk, nbytes - chunk); |
| 606 | 832 | ||
| 607 | #ifdef USE_TEXT_PROPERTIES | 833 | #ifdef USE_TEXT_PROPERTIES |
| 608 | if (BUF_INTERVALS (current_buffer) != 0) | 834 | if (BUF_INTERVALS (current_buffer) != 0) |
| 609 | offset_intervals (current_buffer, PT, length); | 835 | offset_intervals (current_buffer, PT, nchars); |
| 610 | #endif | 836 | #endif |
| 611 | 837 | ||
| 612 | GAP_SIZE -= length; | 838 | GAP_SIZE -= nbytes; |
| 613 | GPT += length; | 839 | GPT += nchars; |
| 614 | ZV += length; | 840 | ZV += nchars; |
| 615 | Z += length; | 841 | Z += nchars; |
| 842 | GPT_BYTE += nbytes; | ||
| 843 | ZV_BYTE += nbytes; | ||
| 844 | Z_BYTE += nbytes; | ||
| 616 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 845 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 617 | adjust_overlays_for_insert (PT, length); | 846 | adjust_overlays_for_insert (PT, nchars); |
| 618 | adjust_markers_for_insert (PT, length); | 847 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, 0); |
| 619 | adjust_point (length); | 848 | adjust_point (nchars, nbytes); |
| 849 | |||
| 850 | if (GPT_BYTE < GPT) | ||
| 851 | abort (); | ||
| 620 | 852 | ||
| 621 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 853 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 622 | graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf), | 854 | graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf), |
| 623 | pos, length), | 855 | from, nchars), |
| 624 | PT - length, length, current_buffer, inherit); | 856 | PT - nchars, nchars, |
| 625 | } | 857 | current_buffer, inherit); |
| 626 | |||
| 627 | /* Insert the character C before point */ | ||
| 628 | |||
| 629 | void | ||
| 630 | insert_char (c) | ||
| 631 | int c; | ||
| 632 | { | ||
| 633 | unsigned char workbuf[4], *str; | ||
| 634 | int len = CHAR_STRING (c, workbuf, str); | ||
| 635 | |||
| 636 | insert (str, len); | ||
| 637 | } | ||
| 638 | |||
| 639 | /* Insert the null-terminated string S before point */ | ||
| 640 | |||
| 641 | void | ||
| 642 | insert_string (s) | ||
| 643 | char *s; | ||
| 644 | { | ||
| 645 | insert (s, strlen (s)); | ||
| 646 | } | ||
| 647 | |||
| 648 | /* Like `insert' except that all markers pointing at the place where | ||
| 649 | the insertion happens are adjusted to point after it. | ||
| 650 | Don't use this function to insert part of a Lisp string, | ||
| 651 | since gc could happen and relocate it. */ | ||
| 652 | |||
| 653 | void | ||
| 654 | insert_before_markers (string, length) | ||
| 655 | unsigned char *string; | ||
| 656 | register int length; | ||
| 657 | { | ||
| 658 | if (length > 0) | ||
| 659 | { | ||
| 660 | register int opoint = PT; | ||
| 661 | insert_1 (string, length, 0, 1); | ||
| 662 | adjust_markers (opoint - 1, opoint, length); | ||
| 663 | signal_after_change (PT-length, 0, length); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | void | ||
| 668 | insert_before_markers_and_inherit (string, length) | ||
| 669 | unsigned char *string; | ||
| 670 | register int length; | ||
| 671 | { | ||
| 672 | if (length > 0) | ||
| 673 | { | ||
| 674 | register int opoint = PT; | ||
| 675 | insert_1 (string, length, 1, 1); | ||
| 676 | adjust_markers (opoint - 1, opoint, length); | ||
| 677 | signal_after_change (PT-length, 0, length); | ||
| 678 | } | ||
| 679 | } | ||
| 680 | |||
| 681 | /* Insert part of a Lisp string, relocating markers after. */ | ||
| 682 | |||
| 683 | void | ||
| 684 | insert_from_string_before_markers (string, pos, length, inherit) | ||
| 685 | Lisp_Object string; | ||
| 686 | register int pos, length; | ||
| 687 | int inherit; | ||
| 688 | { | ||
| 689 | if (length > 0) | ||
| 690 | { | ||
| 691 | register int opoint = PT; | ||
| 692 | insert_from_string_1 (string, pos, length, inherit); | ||
| 693 | adjust_markers (opoint - 1, opoint, length); | ||
| 694 | signal_after_change (PT-length, 0, length); | ||
| 695 | } | ||
| 696 | } | 858 | } |
| 697 | 859 | ||
| 698 | /* Replace the text from FROM to TO with NEW, | 860 | /* Replace the text from character positions FROM to TO with NEW, |
| 699 | If PREPARE is nonzero, call prepare_to_modify_buffer. | 861 | If PREPARE is nonzero, call prepare_to_modify_buffer. |
| 700 | If INHERIT, the newly inserted text should inherit text properties | 862 | If INHERIT, the newly inserted text should inherit text properties |
| 701 | from the surrounding non-deleted text. */ | 863 | from the surrounding non-deleted text. */ |
| @@ -710,8 +872,10 @@ replace_range (from, to, new, prepare, inherit) | |||
| 710 | Lisp_Object new; | 872 | Lisp_Object new; |
| 711 | int from, to, prepare, inherit; | 873 | int from, to, prepare, inherit; |
| 712 | { | 874 | { |
| 713 | int numdel; | 875 | int insbytes = XSTRING (new)->size; |
| 714 | int inslen = XSTRING (new)->size; | 876 | int inschars; |
| 877 | int from_byte, to_byte; | ||
| 878 | int nbytes_del, nchars_del; | ||
| 715 | register Lisp_Object temp; | 879 | register Lisp_Object temp; |
| 716 | struct gcpro gcpro1; | 880 | struct gcpro gcpro1; |
| 717 | 881 | ||
| @@ -724,95 +888,117 @@ replace_range (from, to, new, prepare, inherit) | |||
| 724 | to = from + range_length; | 888 | to = from + range_length; |
| 725 | } | 889 | } |
| 726 | 890 | ||
| 891 | UNGCPRO; | ||
| 892 | |||
| 727 | /* Make args be valid */ | 893 | /* Make args be valid */ |
| 728 | if (from < BEGV) | 894 | if (from < BEGV) |
| 729 | from = BEGV; | 895 | from = BEGV; |
| 730 | if (to > ZV) | 896 | if (to > ZV) |
| 731 | to = ZV; | 897 | to = ZV; |
| 732 | 898 | ||
| 733 | UNGCPRO; | 899 | from_byte = CHAR_TO_BYTE (from); |
| 900 | to_byte = CHAR_TO_BYTE (to); | ||
| 734 | 901 | ||
| 735 | numdel = to - from; | 902 | nchars_del = to - from; |
| 903 | nbytes_del = to_byte - from_byte; | ||
| 904 | |||
| 905 | if (nbytes_del <= 0 && insbytes == 0) | ||
| 906 | return; | ||
| 736 | 907 | ||
| 737 | /* Make sure point-max won't overflow after this insertion. */ | 908 | /* Make sure point-max won't overflow after this insertion. */ |
| 738 | XSETINT (temp, Z - numdel + inslen); | 909 | XSETINT (temp, Z_BYTE - nbytes_del + insbytes); |
| 739 | if (Z - numdel + inslen != XINT (temp)) | 910 | if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) |
| 740 | error ("maximum buffer size exceeded"); | 911 | error ("Maximum buffer size exceeded"); |
| 741 | 912 | ||
| 742 | if (numdel <= 0 && inslen == 0) | 913 | inschars = XINT (Fchars_in_string (new)); |
| 743 | return; | ||
| 744 | 914 | ||
| 745 | GCPRO1 (new); | 915 | GCPRO1 (new); |
| 746 | 916 | ||
| 747 | /* Make sure the gap is somewhere in or next to what we are deleting. */ | 917 | /* Make sure the gap is somewhere in or next to what we are deleting. */ |
| 748 | if (from > GPT) | 918 | if (from > GPT) |
| 749 | gap_right (from); | 919 | gap_right (from, from_byte); |
| 750 | if (to < GPT) | 920 | if (to < GPT) |
| 751 | gap_left (to, 0); | 921 | gap_left (to, to_byte, 0); |
| 752 | 922 | ||
| 753 | /* Relocate all markers pointing into the new, larger gap | 923 | /* Relocate all markers pointing into the new, larger gap |
| 754 | to point at the end of the text before the gap. | 924 | to point at the end of the text before the gap. |
| 755 | This has to be done before recording the deletion, | 925 | Do this before recording the deletion, |
| 756 | so undo handles this after reinserting the text. */ | 926 | so that undo handles this after reinserting the text. */ |
| 757 | adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); | 927 | adjust_markers_for_delete (from, from_byte, to, to_byte); |
| 758 | 928 | ||
| 759 | record_delete (from, numdel); | 929 | record_delete (from, nchars_del); |
| 760 | 930 | ||
| 761 | GAP_SIZE += numdel; | 931 | GAP_SIZE += nbytes_del; |
| 762 | ZV -= numdel; | 932 | ZV -= nchars_del; |
| 763 | Z -= numdel; | 933 | Z -= nchars_del; |
| 934 | ZV_BYTE -= nbytes_del; | ||
| 935 | Z_BYTE -= nbytes_del; | ||
| 764 | GPT = from; | 936 | GPT = from; |
| 937 | GPT_BYTE = from_byte; | ||
| 765 | *(GPT_ADDR) = 0; /* Put an anchor. */ | 938 | *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 766 | 939 | ||
| 940 | if (GPT_BYTE < GPT) | ||
| 941 | abort (); | ||
| 942 | |||
| 767 | if (GPT - BEG < beg_unchanged) | 943 | if (GPT - BEG < beg_unchanged) |
| 768 | beg_unchanged = GPT - BEG; | 944 | beg_unchanged = GPT - BEG; |
| 769 | if (Z - GPT < end_unchanged) | 945 | if (Z - GPT < end_unchanged) |
| 770 | end_unchanged = Z - GPT; | 946 | end_unchanged = Z - GPT; |
| 771 | 947 | ||
| 772 | if (GAP_SIZE < inslen) | 948 | if (GAP_SIZE < insbytes) |
| 773 | make_gap (inslen - GAP_SIZE); | 949 | make_gap (insbytes - GAP_SIZE); |
| 774 | 950 | ||
| 775 | record_insert (from, inslen); | 951 | record_insert (from, inschars); |
| 776 | 952 | ||
| 777 | bcopy (XSTRING (new)->data, GPT_ADDR, inslen); | 953 | bcopy (XSTRING (new)->data, GPT_ADDR, insbytes); |
| 778 | 954 | ||
| 779 | /* Relocate point as if it were a marker. */ | 955 | /* Relocate point as if it were a marker. */ |
| 780 | if (from < PT) | 956 | if (from < PT) |
| 781 | adjust_point (from + inslen - (PT < to ? PT : to)); | 957 | adjust_point (from + inschars - (PT < to ? PT : to), |
| 958 | (from_byte + insbytes | ||
| 959 | - (PT_BYTE < to_byte ? PT_BYTE : to_byte))); | ||
| 782 | 960 | ||
| 783 | #ifdef USE_TEXT_PROPERTIES | 961 | #ifdef USE_TEXT_PROPERTIES |
| 784 | offset_intervals (current_buffer, PT, inslen - numdel); | 962 | offset_intervals (current_buffer, PT, inschars - nchars_del); |
| 785 | #endif | 963 | #endif |
| 786 | 964 | ||
| 787 | GAP_SIZE -= inslen; | 965 | GAP_SIZE -= insbytes; |
| 788 | GPT += inslen; | 966 | GPT += inschars; |
| 789 | ZV += inslen; | 967 | ZV += inschars; |
| 790 | Z += inslen; | 968 | Z += inschars; |
| 969 | GPT_BYTE += insbytes; | ||
| 970 | ZV_BYTE += insbytes; | ||
| 971 | ZV_BYTE += insbytes; | ||
| 791 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 972 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 792 | 973 | ||
| 974 | if (GPT_BYTE < GPT) | ||
| 975 | abort (); | ||
| 976 | |||
| 793 | /* Adjust the overlay center as needed. This must be done after | 977 | /* Adjust the overlay center as needed. This must be done after |
| 794 | adjusting the markers that bound the overlays. */ | 978 | adjusting the markers that bound the overlays. */ |
| 795 | adjust_overlays_for_delete (from, numdel); | 979 | adjust_overlays_for_delete (from, nchars_del); |
| 796 | adjust_overlays_for_insert (from, inslen); | 980 | adjust_overlays_for_insert (from, inschars); |
| 797 | adjust_markers_for_insert (from, inslen); | 981 | adjust_markers_for_insert (from, from_byte, from + inschars, |
| 982 | from_byte + insbytes, 0); | ||
| 798 | 983 | ||
| 799 | #ifdef USE_TEXT_PROPERTIES | 984 | #ifdef USE_TEXT_PROPERTIES |
| 800 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 985 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 801 | graft_intervals_into_buffer (XSTRING (new)->intervals, from, inslen, | 986 | graft_intervals_into_buffer (XSTRING (new)->intervals, from, |
| 802 | current_buffer, inherit); | 987 | inschars, current_buffer, inherit); |
| 803 | #endif | 988 | #endif |
| 804 | 989 | ||
| 805 | if (inslen == 0) | 990 | if (insbytes == 0) |
| 806 | evaporate_overlays (from); | 991 | evaporate_overlays (from); |
| 807 | 992 | ||
| 808 | MODIFF++; | 993 | MODIFF++; |
| 809 | UNGCPRO; | 994 | UNGCPRO; |
| 810 | 995 | ||
| 811 | signal_after_change (from, numdel, inslen); | 996 | signal_after_change (from, nchars_del, inschars); |
| 812 | } | 997 | } |
| 813 | 998 | ||
| 814 | /* Delete characters in current buffer | 999 | /* Delete characters in current buffer |
| 815 | from FROM up to (but not including) TO. */ | 1000 | from FROM up to (but not including) TO. |
| 1001 | If TO comes before FROM, we delete nothing. */ | ||
| 816 | 1002 | ||
| 817 | void | 1003 | void |
| 818 | del_range (from, to) | 1004 | del_range (from, to) |
| @@ -827,69 +1013,170 @@ void | |||
| 827 | del_range_1 (from, to, prepare) | 1013 | del_range_1 (from, to, prepare) |
| 828 | int from, to, prepare; | 1014 | int from, to, prepare; |
| 829 | { | 1015 | { |
| 830 | register int numdel; | 1016 | int from_byte, to_byte; |
| 1017 | |||
| 1018 | /* Make args be valid */ | ||
| 1019 | if (from < BEGV) | ||
| 1020 | from = BEGV; | ||
| 1021 | if (to > ZV) | ||
| 1022 | to = ZV; | ||
| 1023 | |||
| 1024 | if (to <= from) | ||
| 1025 | return; | ||
| 1026 | |||
| 1027 | if (prepare) | ||
| 1028 | { | ||
| 1029 | int range_length = to - from; | ||
| 1030 | prepare_to_modify_buffer (from, to, &from); | ||
| 1031 | to = from + range_length; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | from_byte = CHAR_TO_BYTE (from); | ||
| 1035 | to_byte = CHAR_TO_BYTE (to); | ||
| 1036 | |||
| 1037 | del_range_2 (from, to, from_byte, to_byte); | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | /* Like del_range_1 but args are byte positions, not char positions. */ | ||
| 1041 | |||
| 1042 | void | ||
| 1043 | del_range_byte (from_byte, to_byte, prepare) | ||
| 1044 | int from_byte, to_byte, prepare; | ||
| 1045 | { | ||
| 1046 | int from, to; | ||
| 1047 | |||
| 1048 | /* Make args be valid */ | ||
| 1049 | if (from_byte < BEGV_BYTE) | ||
| 1050 | from_byte = BEGV_BYTE; | ||
| 1051 | if (to_byte > ZV_BYTE) | ||
| 1052 | to_byte = ZV_BYTE; | ||
| 1053 | |||
| 1054 | if (to_byte <= from_byte) | ||
| 1055 | return; | ||
| 1056 | |||
| 1057 | from = BYTE_TO_CHAR (from_byte); | ||
| 1058 | to = BYTE_TO_CHAR (to_byte); | ||
| 831 | 1059 | ||
| 832 | if (prepare) | 1060 | if (prepare) |
| 833 | { | 1061 | { |
| 1062 | int old_from = from, old_to = Z - to; | ||
| 834 | int range_length = to - from; | 1063 | int range_length = to - from; |
| 835 | prepare_to_modify_buffer (from, to, &from); | 1064 | prepare_to_modify_buffer (from, to, &from); |
| 836 | to = from + range_length; | 1065 | to = from + range_length; |
| 1066 | |||
| 1067 | if (old_from != from) | ||
| 1068 | from_byte = CHAR_TO_BYTE (from); | ||
| 1069 | if (old_to == Z - to) | ||
| 1070 | to_byte = CHAR_TO_BYTE (to); | ||
| 837 | } | 1071 | } |
| 838 | 1072 | ||
| 1073 | del_range_2 (from, to, from_byte, to_byte); | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | /* Like del_range_1, but positions are specified both as charpos | ||
| 1077 | and bytepos. */ | ||
| 1078 | |||
| 1079 | void | ||
| 1080 | del_range_both (from, to, from_byte, to_byte, prepare) | ||
| 1081 | int from, to, from_byte, to_byte, prepare; | ||
| 1082 | { | ||
| 839 | /* Make args be valid */ | 1083 | /* Make args be valid */ |
| 1084 | if (from_byte < BEGV_BYTE) | ||
| 1085 | from_byte = BEGV_BYTE; | ||
| 1086 | if (to_byte > ZV_BYTE) | ||
| 1087 | to_byte = ZV_BYTE; | ||
| 1088 | |||
| 1089 | if (to_byte <= from_byte) | ||
| 1090 | return; | ||
| 1091 | |||
| 840 | if (from < BEGV) | 1092 | if (from < BEGV) |
| 841 | from = BEGV; | 1093 | from = BEGV; |
| 842 | if (to > ZV) | 1094 | if (to > ZV) |
| 843 | to = ZV; | 1095 | to = ZV; |
| 844 | 1096 | ||
| 845 | if ((numdel = to - from) <= 0) | 1097 | if (prepare) |
| 846 | return; | 1098 | { |
| 1099 | int old_from = from, old_to = Z - to; | ||
| 1100 | int range_length = to - from; | ||
| 1101 | prepare_to_modify_buffer (from, to, &from); | ||
| 1102 | to = from + range_length; | ||
| 1103 | |||
| 1104 | if (old_from != from) | ||
| 1105 | from_byte = CHAR_TO_BYTE (from); | ||
| 1106 | if (old_to == Z - to) | ||
| 1107 | to_byte = CHAR_TO_BYTE (to); | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | del_range_2 (from, to, from_byte, to_byte); | ||
| 1111 | } | ||
| 1112 | |||
| 1113 | /* Delete a range of text, specified both as character positions | ||
| 1114 | and byte positions. FROM and TO are character positions, | ||
| 1115 | while FROM_BYTE and TO_BYTE are byte positions. */ | ||
| 1116 | |||
| 1117 | void | ||
| 1118 | del_range_2 (from, to, from_byte, to_byte) | ||
| 1119 | int from, to, from_byte, to_byte; | ||
| 1120 | { | ||
| 1121 | register int nbytes_del, nchars_del; | ||
| 1122 | |||
| 1123 | nchars_del = to - from; | ||
| 1124 | nbytes_del = to_byte - from_byte; | ||
| 847 | 1125 | ||
| 848 | /* Make sure the gap is somewhere in or next to what we are deleting. */ | 1126 | /* Make sure the gap is somewhere in or next to what we are deleting. */ |
| 849 | if (from > GPT) | 1127 | if (from > GPT) |
| 850 | gap_right (from); | 1128 | gap_right (from, from_byte); |
| 851 | if (to < GPT) | 1129 | if (to < GPT) |
| 852 | gap_left (to, 0); | 1130 | gap_left (to, to_byte, 0); |
| 853 | 1131 | ||
| 854 | /* Relocate all markers pointing into the new, larger gap | 1132 | /* Relocate all markers pointing into the new, larger gap |
| 855 | to point at the end of the text before the gap. | 1133 | to point at the end of the text before the gap. |
| 856 | This has to be done before recording the deletion, | 1134 | Do this before recording the deletion, |
| 857 | so undo handles this after reinserting the text. */ | 1135 | so that undo handles this after reinserting the text. */ |
| 858 | adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); | 1136 | adjust_markers_for_delete (from, from_byte, to, to_byte); |
| 859 | 1137 | ||
| 860 | record_delete (from, numdel); | 1138 | record_delete (from, nchars_del); |
| 861 | MODIFF++; | 1139 | MODIFF++; |
| 862 | 1140 | ||
| 863 | /* Relocate point as if it were a marker. */ | 1141 | /* Relocate point as if it were a marker. */ |
| 864 | if (from < PT) | 1142 | if (from < PT) |
| 865 | adjust_point (from - (PT < to ? PT : to)); | 1143 | adjust_point (from - (PT < to ? PT : to), |
| 1144 | from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte)); | ||
| 866 | 1145 | ||
| 867 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 1146 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 868 | offset_intervals (current_buffer, from, - numdel); | 1147 | offset_intervals (current_buffer, from, - nchars_del); |
| 869 | 1148 | ||
| 870 | /* Adjust the overlay center as needed. This must be done after | 1149 | /* Adjust the overlay center as needed. This must be done after |
| 871 | adjusting the markers that bound the overlays. */ | 1150 | adjusting the markers that bound the overlays. */ |
| 872 | adjust_overlays_for_delete (from, numdel); | 1151 | adjust_overlays_for_delete (from_byte, nchars_del); |
| 873 | 1152 | ||
| 874 | GAP_SIZE += numdel; | 1153 | GAP_SIZE += nbytes_del; |
| 875 | ZV -= numdel; | 1154 | ZV_BYTE -= nbytes_del; |
| 876 | Z -= numdel; | 1155 | Z_BYTE -= nbytes_del; |
| 1156 | ZV -= nchars_del; | ||
| 1157 | Z -= nchars_del; | ||
| 877 | GPT = from; | 1158 | GPT = from; |
| 1159 | GPT_BYTE = from_byte; | ||
| 878 | *(GPT_ADDR) = 0; /* Put an anchor. */ | 1160 | *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 879 | 1161 | ||
| 1162 | if (GPT_BYTE < GPT) | ||
| 1163 | abort (); | ||
| 1164 | |||
| 880 | if (GPT - BEG < beg_unchanged) | 1165 | if (GPT - BEG < beg_unchanged) |
| 881 | beg_unchanged = GPT - BEG; | 1166 | beg_unchanged = GPT - BEG; |
| 882 | if (Z - GPT < end_unchanged) | 1167 | if (Z - GPT < end_unchanged) |
| 883 | end_unchanged = Z - GPT; | 1168 | end_unchanged = Z - GPT; |
| 884 | 1169 | ||
| 885 | evaporate_overlays (from); | 1170 | evaporate_overlays (from); |
| 886 | signal_after_change (from, numdel, 0); | 1171 | signal_after_change (from, nchars_del, 0); |
| 887 | } | 1172 | } |
| 888 | 1173 | ||
| 889 | /* Call this if you're about to change the region of BUFFER from START | 1174 | /* Call this if you're about to change the region of BUFFER from |
| 890 | to END. This checks the read-only properties of the region, calls | 1175 | character positions START to END. This checks the read-only |
| 891 | the necessary modification hooks, and warns the next redisplay that | 1176 | properties of the region, calls the necessary modification hooks, |
| 892 | it should pay attention to that area. */ | 1177 | and warns the next redisplay that it should pay attention to that |
| 1178 | area. */ | ||
| 1179 | |||
| 893 | void | 1180 | void |
| 894 | modify_region (buffer, start, end) | 1181 | modify_region (buffer, start, end) |
| 895 | struct buffer *buffer; | 1182 | struct buffer *buffer; |
| @@ -921,7 +1208,9 @@ modify_region (buffer, start, end) | |||
| 921 | set_buffer_internal (old_buffer); | 1208 | set_buffer_internal (old_buffer); |
| 922 | } | 1209 | } |
| 923 | 1210 | ||
| 924 | /* Check that it is okay to modify the buffer between START and END. | 1211 | /* Check that it is okay to modify the buffer between START and END, |
| 1212 | which are char positions. | ||
| 1213 | |||
| 925 | Run the before-change-function, if any. If intervals are in use, | 1214 | Run the before-change-function, if any. If intervals are in use, |
| 926 | verify that the text to be modified is not read-only, and call | 1215 | verify that the text to be modified is not read-only, and call |
| 927 | any modification properties the text may have. | 1216 | any modification properties the text may have. |
| @@ -1103,15 +1392,15 @@ signal_before_change (start_int, end_int, preserve_ptr) | |||
| 1103 | } | 1392 | } |
| 1104 | 1393 | ||
| 1105 | /* Signal a change immediately after it happens. | 1394 | /* Signal a change immediately after it happens. |
| 1106 | POS is the address of the start of the changed text. | 1395 | CHARPOS is the character position of the start of the changed text. |
| 1107 | LENDEL is the number of characters of the text before the change. | 1396 | LENDEL is the number of characters of the text before the change. |
| 1108 | (Not the whole buffer; just the part that was changed.) | 1397 | (Not the whole buffer; just the part that was changed.) |
| 1109 | LENINS is the number of characters in that part of the text | 1398 | LENINS is the number of characters in that part of the text |
| 1110 | after the change. */ | 1399 | after the change. */ |
| 1111 | 1400 | ||
| 1112 | void | 1401 | void |
| 1113 | signal_after_change (pos, lendel, lenins) | 1402 | signal_after_change (charpos, lendel, lenins) |
| 1114 | int pos, lendel, lenins; | 1403 | int charpos, lendel, lenins; |
| 1115 | { | 1404 | { |
| 1116 | /* If we are deferring calls to the after-change functions | 1405 | /* If we are deferring calls to the after-change functions |
| 1117 | and there are no before-change functions, | 1406 | and there are no before-change functions, |
| @@ -1127,8 +1416,8 @@ signal_after_change (pos, lendel, lenins) | |||
| 1127 | && current_buffer != XBUFFER (combine_after_change_buffer)) | 1416 | && current_buffer != XBUFFER (combine_after_change_buffer)) |
| 1128 | Fcombine_after_change_execute (); | 1417 | Fcombine_after_change_execute (); |
| 1129 | 1418 | ||
| 1130 | elt = Fcons (make_number (pos - BEG), | 1419 | elt = Fcons (make_number (charpos - BEG), |
| 1131 | Fcons (make_number (Z - (pos - lendel + lenins)), | 1420 | Fcons (make_number (Z - (charpos - lendel + lenins)), |
| 1132 | Fcons (make_number (lenins - lendel), Qnil))); | 1421 | Fcons (make_number (lenins - lendel), Qnil))); |
| 1133 | combine_after_change_list | 1422 | combine_after_change_list |
| 1134 | = Fcons (elt, combine_after_change_list); | 1423 | = Fcons (elt, combine_after_change_list); |
| @@ -1145,7 +1434,7 @@ signal_after_change (pos, lendel, lenins) | |||
| 1145 | because it is obsolete anyway and new code should not use it. */ | 1434 | because it is obsolete anyway and new code should not use it. */ |
| 1146 | if (!NILP (Vafter_change_function)) | 1435 | if (!NILP (Vafter_change_function)) |
| 1147 | call3 (Vafter_change_function, | 1436 | call3 (Vafter_change_function, |
| 1148 | make_number (pos), make_number (pos + lenins), | 1437 | make_number (charpos), make_number (charpos + lenins), |
| 1149 | make_number (lendel)); | 1438 | make_number (lendel)); |
| 1150 | 1439 | ||
| 1151 | if (!NILP (Vafter_change_functions)) | 1440 | if (!NILP (Vafter_change_functions)) |
| @@ -1166,8 +1455,8 @@ signal_after_change (pos, lendel, lenins) | |||
| 1166 | 1455 | ||
| 1167 | /* Actually run the hook functions. */ | 1456 | /* Actually run the hook functions. */ |
| 1168 | args[0] = Qafter_change_functions; | 1457 | args[0] = Qafter_change_functions; |
| 1169 | XSETFASTINT (args[1], pos); | 1458 | XSETFASTINT (args[1], charpos); |
| 1170 | XSETFASTINT (args[2], pos + lenins); | 1459 | XSETFASTINT (args[2], charpos + lenins); |
| 1171 | XSETFASTINT (args[3], lendel); | 1460 | XSETFASTINT (args[3], lendel); |
| 1172 | run_hook_list_with_args (after_change_functions, | 1461 | run_hook_list_with_args (after_change_functions, |
| 1173 | 4, args); | 1462 | 4, args); |
| @@ -1180,16 +1469,17 @@ signal_after_change (pos, lendel, lenins) | |||
| 1180 | 1469 | ||
| 1181 | if (!NILP (current_buffer->overlays_before) | 1470 | if (!NILP (current_buffer->overlays_before) |
| 1182 | || !NILP (current_buffer->overlays_after)) | 1471 | || !NILP (current_buffer->overlays_after)) |
| 1183 | report_overlay_modification (make_number (pos), | 1472 | report_overlay_modification (make_number (charpos), |
| 1184 | make_number (pos + lenins), | 1473 | make_number (charpos + lenins), |
| 1185 | 1, | 1474 | 1, |
| 1186 | make_number (pos), make_number (pos + lenins), | 1475 | make_number (charpos), |
| 1476 | make_number (charpos + lenins), | ||
| 1187 | make_number (lendel)); | 1477 | make_number (lendel)); |
| 1188 | 1478 | ||
| 1189 | /* After an insertion, call the text properties | 1479 | /* After an insertion, call the text properties |
| 1190 | insert-behind-hooks or insert-in-front-hooks. */ | 1480 | insert-behind-hooks or insert-in-front-hooks. */ |
| 1191 | if (lendel == 0) | 1481 | if (lendel == 0) |
| 1192 | report_interval_modification (pos, pos + lenins); | 1482 | report_interval_modification (charpos, charpos + lenins); |
| 1193 | } | 1483 | } |
| 1194 | 1484 | ||
| 1195 | Lisp_Object | 1485 | Lisp_Object |