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 ();
30 static void gap_left ();
31 static void gap_right ();
32 static void adjust_markers ();
34 /* Move gap to position `pos'.
35 Note that this can quit! */
46 /* Move the gap to POS, which is less than the current GPT.
47 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
50 gap_left (pos
, newgap
)
54 register unsigned char *to
, *from
;
62 if (unchanged_modified
== MODIFF
)
65 end_unchanged
= Z
- pos
- 1;
69 if (Z
- GPT
< end_unchanged
)
70 end_unchanged
= Z
- GPT
;
71 if (pos
< beg_unchanged
)
81 /* Now copy the characters. To move the gap down,
82 copy characters up. */
86 /* I gets number of characters left to copy. */
90 /* If a quit is requested, stop copying now.
91 Change POS to be where we have actually moved the gap to. */
97 /* Move at most 32000 chars before checking again for a quit. */
102 /* bcopy is safe if the two areas of memory do not overlap
103 or on systems where bcopy is always safe for moving upward. */
104 && (BCOPY_UPWARD_SAFE
105 || to
- from
>= 128))
107 /* If overlap is not safe, avoid it by not moving too many
108 characters at once. */
109 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
124 /* Adjust markers, and buffer data structure, to put the gap at POS.
125 POS is where the loop above stopped, which may be what was specified
126 or may be where a quit was detected. */
127 adjust_markers (pos
+ 1, GPT
, GAP_SIZE
);
136 register unsigned char *to
, *from
;
142 if (unchanged_modified
== MODIFF
)
145 end_unchanged
= Z
- pos
- 1;
149 if (Z
- pos
- 1 < end_unchanged
)
150 end_unchanged
= Z
- pos
- 1;
151 if (GPT
- BEG
< beg_unchanged
)
152 beg_unchanged
= GPT
- BEG
;
160 /* Now copy the characters. To move the gap up,
161 copy characters down. */
165 /* I gets number of characters left to copy. */
169 /* If a quit is requested, stop copying now.
170 Change POS to be where we have actually moved the gap to. */
176 /* Move at most 32000 chars before checking again for a quit. */
181 /* bcopy is safe if the two areas of memory do not overlap
182 or on systems where bcopy is always safe for moving downward. */
183 && (BCOPY_DOWNWARD_SAFE
184 || from
- to
>= 128))
186 /* If overlap is not safe, avoid it by not moving too many
187 characters at once. */
188 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
203 adjust_markers (GPT
+ GAP_SIZE
, pos
+ 1 + GAP_SIZE
, - GAP_SIZE
);
208 /* Add `amount' to the position of every marker in the current buffer
209 whose current position is between `from' (exclusive) and `to' (inclusive).
210 Also, any markers past the outside of that interval, in the direction
211 of adjustment, are first moved back to the near end of the interval
212 and then adjusted by `amount'. */
215 adjust_markers (from
, to
, amount
)
216 register int from
, to
, amount
;
219 register struct Lisp_Marker
*m
;
222 marker
= current_buffer
->markers
;
224 while (!NILP (marker
))
226 m
= XMARKER (marker
);
230 if (mpos
> to
&& mpos
< to
+ amount
)
235 if (mpos
> from
+ amount
&& mpos
<= from
)
236 mpos
= from
+ amount
;
238 if (mpos
> from
&& mpos
<= to
)
245 /* Make the gap INCREMENT characters longer. */
250 unsigned char *result
;
255 /* If we have to get more space, get enough to last a while. */
259 result
= BUFFER_REALLOC (BEG_ADDR
, (Z
- BEG
+ GAP_SIZE
+ increment
));
266 /* Prevent quitting in move_gap. */
271 old_gap_size
= GAP_SIZE
;
273 /* Call the newly allocated space a gap at the end of the whole space. */
275 GAP_SIZE
= increment
;
277 /* Move the new gap down to be consecutive with the end of the old one.
278 This adjusts the markers properly too. */
279 gap_left (real_gap_loc
+ old_gap_size
, 1);
281 /* Now combine the two into one large gap. */
282 GAP_SIZE
+= old_gap_size
;
288 /* Insert a string of specified length before point.
289 DO NOT use this for the contents of a Lisp string!
290 prepare_to_modify_buffer could relocate the string. */
292 insert (string
, length
)
293 register unsigned char *string
;
298 insert_1 (string
, length
);
299 signal_after_change (PT
-length
, 0, length
);
304 insert_1 (string
, length
)
305 register unsigned char *string
;
308 register Lisp_Object temp
;
310 /* Make sure point-max won't overflow after this insertion. */
311 XSET (temp
, Lisp_Int
, length
+ Z
);
312 if (length
+ Z
!= XINT (temp
))
313 error ("maximum buffer size exceeded");
315 prepare_to_modify_buffer (PT
, PT
);
319 if (GAP_SIZE
< length
)
320 make_gap (length
- GAP_SIZE
);
322 record_insert (PT
, length
);
325 bcopy (string
, GPT_ADDR
, length
);
327 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
328 offset_intervals (current_buffer
, PT
, length
);
334 SET_PT (PT
+ length
);
337 /* Insert the part of the text of STRING, a Lisp object assumed to be
338 of type string, consisting of the LENGTH characters starting at
339 position POS. If the text of STRING has properties, they are absorbed
342 It does not work to use `insert' for this, because a GC could happen
343 before we bcopy the stuff into the buffer, and relocate the string
344 without insert noticing. */
346 insert_from_string (string
, pos
, length
, inherit
)
348 register int pos
, length
;
353 insert_from_string_1 (string
, pos
, length
, inherit
);
354 signal_after_change (PT
-length
, 0, length
);
359 insert_from_string_1 (string
, pos
, length
, inherit
)
361 register int pos
, length
;
364 register Lisp_Object temp
;
367 /* Make sure point-max won't overflow after this insertion. */
368 XSET (temp
, Lisp_Int
, length
+ Z
);
369 if (length
+ Z
!= XINT (temp
))
370 error ("maximum buffer size exceeded");
373 prepare_to_modify_buffer (PT
, PT
);
377 if (GAP_SIZE
< length
)
378 make_gap (length
- GAP_SIZE
);
380 record_insert (PT
, length
);
384 bcopy (XSTRING (string
)->data
, GPT_ADDR
, length
);
386 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
387 offset_intervals (current_buffer
, PT
, length
);
394 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
395 graft_intervals_into_buffer (XSTRING (string
)->intervals
, PT
, length
,
396 current_buffer
, inherit
);
398 SET_PT (PT
+ length
);
401 /* Insert the character C before point */
410 /* Insert the null-terminated string S before point */
416 insert (s
, strlen (s
));
419 /* Like `insert' except that all markers pointing at the place where
420 the insertion happens are adjusted to point after it.
421 Don't use this function to insert part of a Lisp string,
422 since gc could happen and relocate it. */
424 insert_before_markers (string
, length
)
425 unsigned char *string
;
430 register int opoint
= PT
;
431 insert_1 (string
, length
);
432 adjust_markers (opoint
- 1, opoint
, length
);
433 signal_after_change (PT
-length
, 0, length
);
437 /* Insert part of a Lisp string, relocating markers after. */
439 insert_from_string_before_markers (string
, pos
, length
, inherit
)
441 register int pos
, length
;
446 register int opoint
= PT
;
447 insert_from_string_1 (string
, pos
, length
, inherit
);
448 adjust_markers (opoint
- 1, opoint
, length
);
449 signal_after_change (PT
-length
, 0, length
);
453 /* Delete characters in current buffer
454 from FROM up to (but not including) TO. */
457 register int from
, to
;
459 return del_range_1 (from
, to
, 1);
462 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
464 del_range_1 (from
, to
, prepare
)
465 register int from
, to
, prepare
;
469 /* Make args be valid */
475 if ((numdel
= to
- from
) <= 0)
478 /* Make sure the gap is somewhere in or next to what we are deleting. */
485 prepare_to_modify_buffer (from
, to
);
487 record_delete (from
, numdel
);
490 /* Relocate point as if it were a marker. */
496 SET_PT (PT
- numdel
);
499 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
500 offset_intervals (current_buffer
, from
, - numdel
);
502 /* Relocate all markers pointing into the new, larger gap
503 to point at the end of the text before the gap. */
504 adjust_markers (to
+ GAP_SIZE
, to
+ GAP_SIZE
, - numdel
- GAP_SIZE
);
511 if (GPT
- BEG
< beg_unchanged
)
512 beg_unchanged
= GPT
- BEG
;
513 if (Z
- GPT
< end_unchanged
)
514 end_unchanged
= Z
- GPT
;
516 signal_after_change (from
, numdel
, 0);
519 /* Call this if you're about to change the region of BUFFER from START
520 to END. This checks the read-only properties of the region, calls
521 the necessary modification hooks, and warns the next redisplay that
522 it should pay attention to that area. */
523 modify_region (buffer
, start
, end
)
524 struct buffer
*buffer
;
527 struct buffer
*old_buffer
= current_buffer
;
529 if (buffer
!= old_buffer
)
530 set_buffer_internal (buffer
);
532 prepare_to_modify_buffer (start
, end
);
534 if (start
- 1 < beg_unchanged
|| unchanged_modified
== MODIFF
)
535 beg_unchanged
= start
- 1;
536 if (Z
- end
< end_unchanged
537 || unchanged_modified
== MODIFF
)
538 end_unchanged
= Z
- end
;
540 if (MODIFF
<= current_buffer
->save_modified
)
541 record_first_change ();
544 if (buffer
!= old_buffer
)
545 set_buffer_internal (old_buffer
);
548 /* Check that it is okay to modify the buffer between START and END.
549 Run the before-change-function, if any. If intervals are in use,
550 verify that the text to be modified is not read-only, and call
551 any modification properties the text may have. */
553 prepare_to_modify_buffer (start
, end
)
554 Lisp_Object start
, end
;
556 if (!NILP (current_buffer
->read_only
))
557 Fbarf_if_buffer_read_only ();
559 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
560 verify_interval_modification (current_buffer
, start
, end
);
562 verify_overlay_modification (start
, end
);
564 #ifdef CLASH_DETECTION
565 if (!NILP (current_buffer
->filename
)
566 && current_buffer
->save_modified
>= MODIFF
)
567 lock_file (current_buffer
->filename
);
569 /* At least warn if this file has changed on disk since it was visited. */
570 if (!NILP (current_buffer
->filename
)
571 && current_buffer
->save_modified
>= MODIFF
572 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
573 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
574 call1 (intern ("ask-user-about-supersession-threat"),
575 current_buffer
->filename
);
576 #endif /* not CLASH_DETECTION */
578 signal_before_change (start
, end
);
580 Vdeactivate_mark
= Qt
;
584 before_change_function_restore (value
)
587 Vbefore_change_function
= value
;
591 after_change_function_restore (value
)
594 Vafter_change_function
= value
;
598 before_change_functions_restore (value
)
601 Vbefore_change_functions
= value
;
605 after_change_functions_restore (value
)
608 Vafter_change_functions
= value
;
611 /* Signal a change to the buffer immediately before it happens.
612 START and END are the bounds of the text to be changed,
615 signal_before_change (start
, end
)
616 Lisp_Object start
, end
;
618 /* If buffer is unmodified, run a special hook for that case. */
619 if (current_buffer
->save_modified
>= MODIFF
620 && !NILP (Vfirst_change_hook
)
621 && !NILP (Vrun_hooks
))
622 call1 (Vrun_hooks
, Qfirst_change_hook
);
624 /* Now in any case run the before-change-function if any. */
625 if (!NILP (Vbefore_change_function
))
627 int count
= specpdl_ptr
- specpdl
;
628 Lisp_Object function
;
630 function
= Vbefore_change_function
;
632 record_unwind_protect (after_change_function_restore
,
633 Vafter_change_function
);
634 record_unwind_protect (before_change_function_restore
,
635 Vbefore_change_function
);
636 record_unwind_protect (after_change_functions_restore
,
637 Vafter_change_functions
);
638 record_unwind_protect (before_change_functions_restore
,
639 Vbefore_change_functions
);
640 Vafter_change_function
= Qnil
;
641 Vbefore_change_function
= Qnil
;
642 Vafter_change_functions
= Qnil
;
643 Vbefore_change_functions
= Qnil
;
645 call2 (function
, start
, end
);
646 unbind_to (count
, Qnil
);
649 /* Now in any case run the before-change-function if any. */
650 if (!NILP (Vbefore_change_functions
))
652 int count
= specpdl_ptr
- specpdl
;
653 Lisp_Object functions
;
655 functions
= Vbefore_change_functions
;
657 record_unwind_protect (after_change_function_restore
,
658 Vafter_change_function
);
659 record_unwind_protect (before_change_function_restore
,
660 Vbefore_change_function
);
661 record_unwind_protect (after_change_functions_restore
,
662 Vafter_change_functions
);
663 record_unwind_protect (before_change_functions_restore
,
664 Vbefore_change_functions
);
665 Vafter_change_function
= Qnil
;
666 Vbefore_change_function
= Qnil
;
667 Vafter_change_functions
= Qnil
;
668 Vbefore_change_functions
= Qnil
;
670 while (CONSP (functions
))
672 call2 (XCONS (functions
)->car
, start
, end
);
673 functions
= XCONS (functions
)->cdr
;
675 unbind_to (count
, Qnil
);
679 /* Signal a change immediately after it happens.
680 POS is the address of the start of the changed text.
681 LENDEL is the number of characters of the text before the change.
682 (Not the whole buffer; just the part that was changed.)
683 LENINS is the number of characters in the changed text. */
685 signal_after_change (pos
, lendel
, lenins
)
686 int pos
, lendel
, lenins
;
688 if (!NILP (Vafter_change_function
))
690 int count
= specpdl_ptr
- specpdl
;
691 Lisp_Object function
;
692 function
= Vafter_change_function
;
694 record_unwind_protect (after_change_function_restore
,
695 Vafter_change_function
);
696 record_unwind_protect (before_change_function_restore
,
697 Vbefore_change_function
);
698 record_unwind_protect (after_change_functions_restore
,
699 Vafter_change_functions
);
700 record_unwind_protect (before_change_functions_restore
,
701 Vbefore_change_functions
);
702 Vafter_change_function
= Qnil
;
703 Vbefore_change_function
= Qnil
;
704 Vafter_change_functions
= Qnil
;
705 Vbefore_change_functions
= Qnil
;
707 call3 (function
, make_number (pos
), make_number (pos
+ lenins
),
708 make_number (lendel
));
709 unbind_to (count
, Qnil
);
711 if (!NILP (Vafter_change_functions
))
713 int count
= specpdl_ptr
- specpdl
;
714 Lisp_Object functions
;
715 functions
= Vafter_change_functions
;
717 record_unwind_protect (after_change_function_restore
,
718 Vafter_change_function
);
719 record_unwind_protect (before_change_function_restore
,
720 Vbefore_change_function
);
721 record_unwind_protect (after_change_functions_restore
,
722 Vafter_change_functions
);
723 record_unwind_protect (before_change_functions_restore
,
724 Vbefore_change_functions
);
725 Vafter_change_function
= Qnil
;
726 Vbefore_change_function
= Qnil
;
727 Vafter_change_functions
= Qnil
;
728 Vbefore_change_functions
= Qnil
;
730 while (CONSP (functions
))
732 call3 (XCONS (functions
)->car
,
733 make_number (pos
), make_number (pos
+ lenins
),
734 make_number (lendel
));
735 functions
= XCONS (functions
)->cdr
;
737 unbind_to (count
, Qnil
);