comparison src/insdel.c @ 18446:59d2f2a0a36e

(prepare_to_modify_buffer, signal_before_change): New argument PRESERVE_PTR. (del_range_1): Use PRESERVE_PTR to preserve FROM. Save the length of the range separately. (NULL): Define if not defined.
author Richard M. Stallman <rms@gnu.org>
date Wed, 25 Jun 1997 06:50:16 +0000
parents 8f167ece7e39
children ac0f5f1912c0
comparison
equal deleted inserted replaced
18445:2b1d3330e750 18446:59d2f2a0a36e
24 #include "intervals.h" 24 #include "intervals.h"
25 #include "buffer.h" 25 #include "buffer.h"
26 #include "charset.h" 26 #include "charset.h"
27 #include "window.h" 27 #include "window.h"
28 #include "blockinput.h" 28 #include "blockinput.h"
29
30 #ifndef NULL
31 #define NULL 0
32 #endif
29 33
30 #define min(x, y) ((x) < (y) ? (x) : (y)) 34 #define min(x, y) ((x) < (y) ? (x) : (y))
31 35
32 static void insert_from_string_1 (); 36 static void insert_from_string_1 ();
33 static void insert_from_buffer_1 (); 37 static void insert_from_buffer_1 ();
439 int inherit, prepare; 443 int inherit, prepare;
440 { 444 {
441 register Lisp_Object temp; 445 register Lisp_Object temp;
442 446
443 if (prepare) 447 if (prepare)
444 prepare_to_modify_buffer (PT, PT); 448 prepare_to_modify_buffer (PT, PT, NULL);
445 449
446 if (PT != GPT) 450 if (PT != GPT)
447 move_gap (PT); 451 move_gap (PT);
448 if (GAP_SIZE < length) 452 if (GAP_SIZE < length)
449 make_gap (length - GAP_SIZE); 453 make_gap (length - GAP_SIZE);
510 XSETINT (temp, length + Z); 514 XSETINT (temp, length + Z);
511 if (length + Z != XINT (temp)) 515 if (length + Z != XINT (temp))
512 error ("maximum buffer size exceeded"); 516 error ("maximum buffer size exceeded");
513 517
514 GCPRO1 (string); 518 GCPRO1 (string);
515 prepare_to_modify_buffer (PT, PT); 519 prepare_to_modify_buffer (PT, PT, NULL);
516 520
517 if (PT != GPT) 521 if (PT != GPT)
518 move_gap (PT); 522 move_gap (PT);
519 if (GAP_SIZE < length) 523 if (GAP_SIZE < length)
520 make_gap (length - GAP_SIZE); 524 make_gap (length - GAP_SIZE);
575 /* Make sure point-max won't overflow after this insertion. */ 579 /* Make sure point-max won't overflow after this insertion. */
576 XSETINT (temp, length + Z); 580 XSETINT (temp, length + Z);
577 if (length + Z != XINT (temp)) 581 if (length + Z != XINT (temp))
578 error ("maximum buffer size exceeded"); 582 error ("maximum buffer size exceeded");
579 583
580 prepare_to_modify_buffer (PT, PT); 584 prepare_to_modify_buffer (PT, PT, NULL);
581 585
582 if (PT != GPT) 586 if (PT != GPT)
583 move_gap (PT); 587 move_gap (PT);
584 if (GAP_SIZE < length) 588 if (GAP_SIZE < length)
585 make_gap (length - GAP_SIZE); 589 make_gap (length - GAP_SIZE);
703 707
704 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */ 708 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
705 709
706 void 710 void
707 del_range_1 (from, to, prepare) 711 del_range_1 (from, to, prepare)
708 register int from, to, prepare; 712 int from, to, prepare;
709 { 713 {
710 register int numdel; 714 register int numdel;
715
716 if (prepare)
717 {
718 int range_length = to - from;
719 prepare_to_modify_buffer (from, to, &from);
720 to = from + range_length;
721 }
711 722
712 /* Make args be valid */ 723 /* Make args be valid */
713 if (from < BEGV) 724 if (from < BEGV)
714 from = BEGV; 725 from = BEGV;
715 if (to > ZV) 726 if (to > ZV)
722 if (from > GPT) 733 if (from > GPT)
723 gap_right (from); 734 gap_right (from);
724 if (to < GPT) 735 if (to < GPT)
725 gap_left (to, 0); 736 gap_left (to, 0);
726 737
727 if (prepare)
728 prepare_to_modify_buffer (from, to);
729
730 /* Relocate all markers pointing into the new, larger gap 738 /* Relocate all markers pointing into the new, larger gap
731 to point at the end of the text before the gap. 739 to point at the end of the text before the gap.
732 This has to be done before recording the deletion, 740 This has to be done before recording the deletion,
733 so undo handles this after reinserting the text. */ 741 so undo handles this after reinserting the text. */
734 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); 742 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
774 struct buffer *old_buffer = current_buffer; 782 struct buffer *old_buffer = current_buffer;
775 783
776 if (buffer != old_buffer) 784 if (buffer != old_buffer)
777 set_buffer_internal (buffer); 785 set_buffer_internal (buffer);
778 786
779 prepare_to_modify_buffer (start, end); 787 prepare_to_modify_buffer (start, end, NULL);
780 788
781 if (start - 1 < beg_unchanged 789 if (start - 1 < beg_unchanged
782 || (unchanged_modified == MODIFF 790 || (unchanged_modified == MODIFF
783 && overlay_unchanged_modified == OVERLAY_MODIFF)) 791 && overlay_unchanged_modified == OVERLAY_MODIFF))
784 beg_unchanged = start - 1; 792 beg_unchanged = start - 1;
794 buffer->point_before_scroll = Qnil; 802 buffer->point_before_scroll = Qnil;
795 803
796 if (buffer != old_buffer) 804 if (buffer != old_buffer)
797 set_buffer_internal (old_buffer); 805 set_buffer_internal (old_buffer);
798 } 806 }
799 807
800 /* Check that it is okay to modify the buffer between START and END. 808 /* Check that it is okay to modify the buffer between START and END.
801 Run the before-change-function, if any. If intervals are in use, 809 Run the before-change-function, if any. If intervals are in use,
802 verify that the text to be modified is not read-only, and call 810 verify that the text to be modified is not read-only, and call
803 any modification properties the text may have. */ 811 any modification properties the text may have.
804 812
805 void 813 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
806 prepare_to_modify_buffer (start, end) 814 by holding its value temporarily in a marker. */
815
816 void
817 prepare_to_modify_buffer (start, end, preserve_ptr)
807 int start, end; 818 int start, end;
819 int *preserve_ptr;
808 { 820 {
809 if (!NILP (current_buffer->read_only)) 821 if (!NILP (current_buffer->read_only))
810 Fbarf_if_buffer_read_only (); 822 Fbarf_if_buffer_read_only ();
811 823
812 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ 824 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
813 if (BUF_INTERVALS (current_buffer) != 0) 825 if (BUF_INTERVALS (current_buffer) != 0)
814 verify_interval_modification (current_buffer, start, end); 826 {
827 if (preserve_ptr)
828 {
829 Lisp_Object preserve_marker;
830 struct gcpro gcpro1;
831 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
832 GCPRO1 (preserve_marker);
833 verify_interval_modification (current_buffer, start, end);
834 *preserve_ptr = marker_position (preserve_marker);
835 unchain_marker (preserve_marker);
836 UNGCPRO;
837 }
838 else
839 verify_interval_modification (current_buffer, start, end);
840 }
815 841
816 #ifdef CLASH_DETECTION 842 #ifdef CLASH_DETECTION
817 if (!NILP (current_buffer->file_truename) 843 if (!NILP (current_buffer->file_truename)
818 /* Make binding buffer-file-name to nil effective. */ 844 /* Make binding buffer-file-name to nil effective. */
819 && !NILP (current_buffer->filename) 845 && !NILP (current_buffer->filename)
827 && !NILP (Ffile_exists_p (current_buffer->filename))) 853 && !NILP (Ffile_exists_p (current_buffer->filename)))
828 call1 (intern ("ask-user-about-supersession-threat"), 854 call1 (intern ("ask-user-about-supersession-threat"),
829 current_buffer->filename); 855 current_buffer->filename);
830 #endif /* not CLASH_DETECTION */ 856 #endif /* not CLASH_DETECTION */
831 857
832 signal_before_change (start, end); 858 signal_before_change (start, end, preserve_ptr);
833 859
834 if (current_buffer->newline_cache) 860 if (current_buffer->newline_cache)
835 invalidate_region_cache (current_buffer, 861 invalidate_region_cache (current_buffer,
836 current_buffer->newline_cache, 862 current_buffer->newline_cache,
837 start - BEG, Z - end); 863 start - BEG, Z - end);
841 start - BEG, Z - end); 867 start - BEG, Z - end);
842 868
843 Vdeactivate_mark = Qt; 869 Vdeactivate_mark = Qt;
844 } 870 }
845 871
872 /* These macros work with an argument named `preserve_ptr'
873 and a local variable named `preserve_marker'. */
874
875 #define PRESERVE_VALUE \
876 if (preserve_ptr && NILP (preserve_marker)) \
877 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
878
879 #define RESTORE_VALUE \
880 if (! NILP (preserve_marker)) \
881 { \
882 *preserve_ptr = marker_position (preserve_marker); \
883 unchain_marker (preserve_marker); \
884 }
885
846 /* Signal a change to the buffer immediately before it happens. 886 /* Signal a change to the buffer immediately before it happens.
847 START_INT and END_INT are the bounds of the text to be changed. */ 887 START_INT and END_INT are the bounds of the text to be changed.
848 888
849 void 889 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
850 signal_before_change (start_int, end_int) 890 by holding its value temporarily in a marker. */
891
892 void
893 signal_before_change (start_int, end_int, preserve_ptr)
851 int start_int, end_int; 894 int start_int, end_int;
895 int *preserve_ptr;
852 { 896 {
853 Lisp_Object start, end; 897 Lisp_Object start, end;
898 Lisp_Object preserve_marker;
899 struct gcpro gcpro1;
854 900
855 start = make_number (start_int); 901 start = make_number (start_int);
856 end = make_number (end_int); 902 end = make_number (end_int);
903 preserve_marker = Qnil;
904 GCPRO1 (preserve_marker);
857 905
858 /* If buffer is unmodified, run a special hook for that case. */ 906 /* If buffer is unmodified, run a special hook for that case. */
859 if (SAVE_MODIFF >= MODIFF 907 if (SAVE_MODIFF >= MODIFF
860 && !NILP (Vfirst_change_hook) 908 && !NILP (Vfirst_change_hook)
861 && !NILP (Vrun_hooks)) 909 && !NILP (Vrun_hooks))
862 call1 (Vrun_hooks, Qfirst_change_hook); 910 {
911 PRESERVE_VALUE;
912 call1 (Vrun_hooks, Qfirst_change_hook);
913 }
863 914
864 /* Run the before-change-function if any. 915 /* Run the before-change-function if any.
865 We don't bother "binding" this variable to nil 916 We don't bother "binding" this variable to nil
866 because it is obsolete anyway and new code should not use it. */ 917 because it is obsolete anyway and new code should not use it. */
867 if (!NILP (Vbefore_change_function)) 918 if (!NILP (Vbefore_change_function))
868 call2 (Vbefore_change_function, start, end); 919 {
920 PRESERVE_VALUE;
921 call2 (Vbefore_change_function, start, end);
922 }
869 923
870 /* Now run the before-change-functions if any. */ 924 /* Now run the before-change-functions if any. */
871 if (!NILP (Vbefore_change_functions)) 925 if (!NILP (Vbefore_change_functions))
872 { 926 {
873 Lisp_Object args[3]; 927 Lisp_Object args[3];
874 Lisp_Object before_change_functions; 928 Lisp_Object before_change_functions;
875 Lisp_Object after_change_functions; 929 Lisp_Object after_change_functions;
876 struct gcpro gcpro1, gcpro2; 930 struct gcpro gcpro1, gcpro2;
931
932 PRESERVE_VALUE;
877 933
878 /* "Bind" before-change-functions and after-change-functions 934 /* "Bind" before-change-functions and after-change-functions
879 to nil--but in a way that errors don't know about. 935 to nil--but in a way that errors don't know about.
880 That way, if there's an error in them, they will stay nil. */ 936 That way, if there's an error in them, they will stay nil. */
881 before_change_functions = Vbefore_change_functions; 937 before_change_functions = Vbefore_change_functions;
896 UNGCPRO; 952 UNGCPRO;
897 } 953 }
898 954
899 if (!NILP (current_buffer->overlays_before) 955 if (!NILP (current_buffer->overlays_before)
900 || !NILP (current_buffer->overlays_after)) 956 || !NILP (current_buffer->overlays_after))
901 report_overlay_modification (start, end, 0, start, end, Qnil); 957 {
958 PRESERVE_VALUE;
959 report_overlay_modification (start, end, 0, start, end, Qnil);
960 }
961
962 RESTORE_VALUE;
963 UNGCPRO;
902 } 964 }
903 965
904 /* Signal a change immediately after it happens. 966 /* Signal a change immediately after it happens.
905 POS is the address of the start of the changed text. 967 POS is the address of the start of the changed text.
906 LENDEL is the number of characters of the text before the change. 968 LENDEL is the number of characters of the text before the change.