1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include "intervals.h"
26 #include "blockinput.h"
28 static void insert_1 ();
29 static void insert_from_string_1 ();
31 /* Move gap to position `pos'.
32 Note that this can quit! */
43 /* Move the gap to POS, which is less than the current GPT.
44 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
46 gap_left (pos
, newgap
)
50 register unsigned char *to
, *from
;
58 if (unchanged_modified
== MODIFF
)
61 end_unchanged
= Z
- pos
- 1;
65 if (Z
- GPT
< end_unchanged
)
66 end_unchanged
= Z
- GPT
;
67 if (pos
< beg_unchanged
)
77 /* Now copy the characters. To move the gap down,
78 copy characters up. */
82 /* I gets number of characters left to copy. */
86 /* If a quit is requested, stop copying now.
87 Change POS to be where we have actually moved the gap to. */
93 /* Move at most 32000 chars before checking again for a quit. */
98 /* bcopy is safe if the two areas of memory do not overlap
99 or on systems where bcopy is always safe for moving upward. */
100 && (BCOPY_UPWARD_SAFE
101 || to
- from
>= 128))
103 /* If overlap is not safe, avoid it by not moving too many
104 characters at once. */
105 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
120 /* Adjust markers, and buffer data structure, to put the gap at POS.
121 POS is where the loop above stopped, which may be what was specified
122 or may be where a quit was detected. */
123 adjust_markers (pos
+ 1, GPT
, GAP_SIZE
);
131 register unsigned char *to
, *from
;
137 if (unchanged_modified
== MODIFF
)
140 end_unchanged
= Z
- pos
- 1;
144 if (Z
- pos
- 1 < end_unchanged
)
145 end_unchanged
= Z
- pos
- 1;
146 if (GPT
- BEG
< beg_unchanged
)
147 beg_unchanged
= GPT
- BEG
;
155 /* Now copy the characters. To move the gap up,
156 copy characters down. */
160 /* I gets number of characters left to copy. */
164 /* If a quit is requested, stop copying now.
165 Change POS to be where we have actually moved the gap to. */
171 /* Move at most 32000 chars before checking again for a quit. */
176 /* bcopy is safe if the two areas of memory do not overlap
177 or on systems where bcopy is always safe for moving downward. */
178 && (BCOPY_DOWNWARD_SAFE
179 || from
- to
>= 128))
181 /* If overlap is not safe, avoid it by not moving too many
182 characters at once. */
183 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
198 adjust_markers (GPT
+ GAP_SIZE
, pos
+ 1 + GAP_SIZE
, - GAP_SIZE
);
203 /* Add `amount' to the position of every marker in the current buffer
204 whose current position is between `from' (exclusive) and `to' (inclusive).
205 Also, any markers past the outside of that interval, in the direction
206 of adjustment, are first moved back to the near end of the interval
207 and then adjusted by `amount'. */
209 adjust_markers (from
, to
, amount
)
210 register int from
, to
, amount
;
213 register struct Lisp_Marker
*m
;
216 marker
= current_buffer
->markers
;
218 while (!NILP (marker
))
220 m
= XMARKER (marker
);
224 if (mpos
> to
&& mpos
< to
+ amount
)
229 if (mpos
> from
+ amount
&& mpos
<= from
)
230 mpos
= from
+ amount
;
232 if (mpos
> from
&& mpos
<= to
)
239 /* Make the gap INCREMENT characters longer. */
244 unsigned char *result
;
249 /* If we have to get more space, get enough to last a while. */
253 result
= BUFFER_REALLOC (BEG_ADDR
, (Z
- BEG
+ GAP_SIZE
+ increment
));
260 /* Prevent quitting in move_gap. */
265 old_gap_size
= GAP_SIZE
;
267 /* Call the newly allocated space a gap at the end of the whole space. */
269 GAP_SIZE
= increment
;
271 /* Move the new gap down to be consecutive with the end of the old one.
272 This adjusts the markers properly too. */
273 gap_left (real_gap_loc
+ old_gap_size
, 1);
275 /* Now combine the two into one large gap. */
276 GAP_SIZE
+= old_gap_size
;
282 /* Insert a string of specified length before point.
283 DO NOT use this for the contents of a Lisp string!
284 prepare_to_modify_buffer could relocate the string. */
286 insert (string
, length
)
287 register unsigned char *string
;
292 insert_1 (string
, length
);
293 signal_after_change (point
-length
, 0, length
);
298 insert_1 (string
, length
)
299 register unsigned char *string
;
302 register Lisp_Object temp
;
304 /* Make sure point-max won't overflow after this insertion. */
305 XSET (temp
, Lisp_Int
, length
+ Z
);
306 if (length
+ Z
!= XINT (temp
))
307 error ("maximum buffer size exceeded");
309 prepare_to_modify_buffer (point
, point
);
313 if (GAP_SIZE
< length
)
314 make_gap (length
- GAP_SIZE
);
316 record_insert (point
, length
);
319 bcopy (string
, GPT_ADDR
, length
);
321 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
322 offset_intervals (current_buffer
, point
, length
);
328 SET_PT (point
+ length
);
331 /* Insert the part of the text of STRING, a Lisp object assumed to be
332 of type string, consisting of the LENGTH characters starting at
333 position POS. If the text of STRING has properties, they are absorbed
336 It does not work to use `insert' for this, because a GC could happen
337 before we bcopy the stuff into the buffer, and relocate the string
338 without insert noticing. */
340 insert_from_string (string
, pos
, length
, inherit
)
342 register int pos
, length
;
347 insert_from_string_1 (string
, pos
, length
, inherit
);
348 signal_after_change (point
-length
, 0, length
);
353 insert_from_string_1 (string
, pos
, length
, inherit
)
355 register int pos
, length
;
358 register Lisp_Object temp
;
361 /* Make sure point-max won't overflow after this insertion. */
362 XSET (temp
, Lisp_Int
, length
+ Z
);
363 if (length
+ Z
!= XINT (temp
))
364 error ("maximum buffer size exceeded");
367 prepare_to_modify_buffer (point
, point
);
371 if (GAP_SIZE
< length
)
372 make_gap (length
- GAP_SIZE
);
374 record_insert (point
, length
);
378 bcopy (XSTRING (string
)->data
, GPT_ADDR
, length
);
380 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
381 offset_intervals (current_buffer
, point
, length
);
388 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
389 graft_intervals_into_buffer (XSTRING (string
)->intervals
, point
, length
,
390 current_buffer
, inherit
);
392 SET_PT (point
+ length
);
395 /* Insert the character C before point */
404 /* Insert the null-terminated string S before point */
410 insert (s
, strlen (s
));
413 /* Like `insert' except that all markers pointing at the place where
414 the insertion happens are adjusted to point after it.
415 Don't use this function to insert part of a Lisp string,
416 since gc could happen and relocate it. */
418 insert_before_markers (string
, length
)
419 unsigned char *string
;
424 register int opoint
= point
;
425 insert_1 (string
, length
);
426 adjust_markers (opoint
- 1, opoint
, length
);
427 signal_after_change (point
-length
, 0, length
);
431 /* Insert part of a Lisp string, relocating markers after. */
433 insert_from_string_before_markers (string
, pos
, length
, inherit
)
435 register int pos
, length
;
440 register int opoint
= point
;
441 insert_from_string_1 (string
, pos
, length
, inherit
);
442 adjust_markers (opoint
- 1, opoint
, length
);
443 signal_after_change (point
-length
, 0, length
);
447 /* Delete characters in current buffer
448 from FROM up to (but not including) TO. */
451 register int from
, to
;
453 return del_range_1 (from
, to
, 1);
456 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
458 del_range_1 (from
, to
, prepare
)
459 register int from
, to
, prepare
;
463 /* Make args be valid */
469 if ((numdel
= to
- from
) <= 0)
472 /* Make sure the gap is somewhere in or next to what we are deleting. */
479 prepare_to_modify_buffer (from
, to
);
481 record_delete (from
, numdel
);
484 /* Relocate point as if it were a marker. */
490 SET_PT (point
- numdel
);
493 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
494 offset_intervals (current_buffer
, from
, - numdel
);
496 /* Relocate all markers pointing into the new, larger gap
497 to point at the end of the text before the gap. */
498 adjust_markers (to
+ GAP_SIZE
, to
+ GAP_SIZE
, - numdel
- GAP_SIZE
);
505 if (GPT
- BEG
< beg_unchanged
)
506 beg_unchanged
= GPT
- BEG
;
507 if (Z
- GPT
< end_unchanged
)
508 end_unchanged
= Z
- GPT
;
510 signal_after_change (from
, numdel
, 0);
513 /* Call this if you're about to change the region of BUFFER from START
514 to END. This checks the read-only properties of the region, calls
515 the necessary modification hooks, and warns the next redisplay that
516 it should pay attention to that area. */
517 modify_region (buffer
, start
, end
)
518 struct buffer
*buffer
;
521 struct buffer
*old_buffer
= current_buffer
;
523 if (buffer
!= old_buffer
)
524 set_buffer_internal (buffer
);
526 prepare_to_modify_buffer (start
, end
);
528 if (start
- 1 < beg_unchanged
|| unchanged_modified
== MODIFF
)
529 beg_unchanged
= start
- 1;
530 if (Z
- end
< end_unchanged
531 || unchanged_modified
== MODIFF
)
532 end_unchanged
= Z
- end
;
534 if (MODIFF
<= current_buffer
->save_modified
)
535 record_first_change ();
538 if (buffer
!= old_buffer
)
539 set_buffer_internal (old_buffer
);
542 /* Check that it is okay to modify the buffer between START and END.
543 Run the before-change-function, if any. If intervals are in use,
544 verify that the text to be modified is not read-only, and call
545 any modification properties the text may have. */
547 prepare_to_modify_buffer (start
, end
)
548 Lisp_Object start
, end
;
550 if (!NILP (current_buffer
->read_only
))
551 Fbarf_if_buffer_read_only ();
553 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
554 verify_interval_modification (current_buffer
, start
, end
);
556 verify_overlay_modification (start
, end
);
558 #ifdef CLASH_DETECTION
559 if (!NILP (current_buffer
->filename
)
560 && current_buffer
->save_modified
>= MODIFF
)
561 lock_file (current_buffer
->filename
);
563 /* At least warn if this file has changed on disk since it was visited. */
564 if (!NILP (current_buffer
->filename
)
565 && current_buffer
->save_modified
>= MODIFF
566 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
567 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
568 call1 (intern ("ask-user-about-supersession-threat"),
569 current_buffer
->filename
);
570 #endif /* not CLASH_DETECTION */
572 signal_before_change (start
, end
);
574 Vdeactivate_mark
= Qt
;
578 before_change_function_restore (value
)
581 Vbefore_change_function
= value
;
585 after_change_function_restore (value
)
588 Vafter_change_function
= value
;
592 before_change_functions_restore (value
)
595 Vbefore_change_functions
= value
;
599 after_change_functions_restore (value
)
602 Vafter_change_functions
= value
;
605 /* Signal a change to the buffer immediately before it happens.
606 START and END are the bounds of the text to be changed,
609 signal_before_change (start
, end
)
610 Lisp_Object start
, end
;
612 /* If buffer is unmodified, run a special hook for that case. */
613 if (current_buffer
->save_modified
>= MODIFF
614 && !NILP (Vfirst_change_hook
)
615 && !NILP (Vrun_hooks
))
616 call1 (Vrun_hooks
, Qfirst_change_hook
);
618 /* Now in any case run the before-change-function if any. */
619 if (!NILP (Vbefore_change_function
))
621 int count
= specpdl_ptr
- specpdl
;
622 Lisp_Object function
;
624 function
= Vbefore_change_function
;
626 record_unwind_protect (after_change_function_restore
,
627 Vafter_change_function
);
628 record_unwind_protect (before_change_function_restore
,
629 Vbefore_change_function
);
630 record_unwind_protect (after_change_functions_restore
,
631 Vafter_change_functions
);
632 record_unwind_protect (before_change_functions_restore
,
633 Vbefore_change_functions
);
634 Vafter_change_function
= Qnil
;
635 Vbefore_change_function
= Qnil
;
636 Vafter_change_functions
= Qnil
;
637 Vbefore_change_functions
= Qnil
;
639 call2 (function
, start
, end
);
640 unbind_to (count
, Qnil
);
643 /* Now in any case run the before-change-function if any. */
644 if (!NILP (Vbefore_change_functions
))
646 int count
= specpdl_ptr
- specpdl
;
647 Lisp_Object functions
;
649 functions
= Vbefore_change_functions
;
651 record_unwind_protect (after_change_function_restore
,
652 Vafter_change_function
);
653 record_unwind_protect (before_change_function_restore
,
654 Vbefore_change_function
);
655 record_unwind_protect (after_change_functions_restore
,
656 Vafter_change_functions
);
657 record_unwind_protect (before_change_functions_restore
,
658 Vbefore_change_functions
);
659 Vafter_change_function
= Qnil
;
660 Vbefore_change_function
= Qnil
;
661 Vafter_change_functions
= Qnil
;
662 Vbefore_change_functions
= Qnil
;
664 while (CONSP (functions
))
666 call2 (XCONS (functions
)->car
, start
, end
);
667 functions
= XCONS (functions
)->cdr
;
669 unbind_to (count
, Qnil
);
673 /* Signal a change immediately after it happens.
674 POS is the address of the start of the changed text.
675 LENDEL is the number of characters of the text before the change.
676 (Not the whole buffer; just the part that was changed.)
677 LENINS is the number of characters in the changed text. */
679 signal_after_change (pos
, lendel
, lenins
)
680 int pos
, lendel
, lenins
;
682 if (!NILP (Vafter_change_function
))
684 int count
= specpdl_ptr
- specpdl
;
685 Lisp_Object function
;
686 function
= Vafter_change_function
;
688 record_unwind_protect (after_change_function_restore
,
689 Vafter_change_function
);
690 record_unwind_protect (before_change_function_restore
,
691 Vbefore_change_function
);
692 record_unwind_protect (after_change_functions_restore
,
693 Vafter_change_functions
);
694 record_unwind_protect (before_change_functions_restore
,
695 Vbefore_change_functions
);
696 Vafter_change_function
= Qnil
;
697 Vbefore_change_function
= Qnil
;
698 Vafter_change_functions
= Qnil
;
699 Vbefore_change_functions
= Qnil
;
701 call3 (function
, make_number (pos
), make_number (pos
+ lenins
),
702 make_number (lendel
));
703 unbind_to (count
, Qnil
);
705 if (!NILP (Vafter_change_functions
))
707 int count
= specpdl_ptr
- specpdl
;
708 Lisp_Object functions
;
709 functions
= Vafter_change_functions
;
711 record_unwind_protect (after_change_function_restore
,
712 Vafter_change_function
);
713 record_unwind_protect (before_change_function_restore
,
714 Vbefore_change_function
);
715 record_unwind_protect (after_change_functions_restore
,
716 Vafter_change_functions
);
717 record_unwind_protect (before_change_functions_restore
,
718 Vbefore_change_functions
);
719 Vafter_change_function
= Qnil
;
720 Vbefore_change_function
= Qnil
;
721 Vafter_change_functions
= Qnil
;
722 Vbefore_change_functions
= Qnil
;
724 while (CONSP (functions
))
726 call3 (XCONS (functions
)->car
,
727 make_number (pos
), make_number (pos
+ lenins
),
728 make_number (lendel
));
729 functions
= XCONS (functions
)->cdr
;
731 unbind_to (count
, Qnil
);