diff options
| author | Joakim Verona | 2012-12-04 01:46:34 +0100 |
|---|---|---|
| committer | Joakim Verona | 2012-12-04 01:46:34 +0100 |
| commit | d28fde00abbbf26b7c80700b1c9bc18b5079a30e (patch) | |
| tree | 3bf606901b01f67d6b2eed3998ac6fae9f4518a8 /src/editfns.c | |
| parent | fa8510a9aabe34d367d935b960eab0abbf060e18 (diff) | |
| parent | c38a186c2e06e0a351d166c5ef06d7307e145f45 (diff) | |
| download | emacs-d28fde00abbbf26b7c80700b1c9bc18b5079a30e.tar.gz emacs-d28fde00abbbf26b7c80700b1c9bc18b5079a30e.zip | |
auto upstream
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 91 |
1 files changed, 42 insertions, 49 deletions
diff --git a/src/editfns.c b/src/editfns.c index 8122ffdd0d4..d60f417e561 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -813,38 +813,43 @@ This function does not move point. */) | |||
| 813 | Qnil, Qt, Qnil); | 813 | Qnil, Qt, Qnil); |
| 814 | } | 814 | } |
| 815 | 815 | ||
| 816 | 816 | /* Save current buffer state for `save-excursion' special form. | |
| 817 | We (ab)use Lisp_Misc_Save_Value to allow explicit free and so | ||
| 818 | offload some work from GC. */ | ||
| 819 | |||
| 817 | Lisp_Object | 820 | Lisp_Object |
| 818 | save_excursion_save (void) | 821 | save_excursion_save (void) |
| 819 | { | 822 | { |
| 820 | bool visible = (XBUFFER (XWINDOW (selected_window)->buffer) | 823 | Lisp_Object save, *data = xmalloc (word_size * 4); |
| 821 | == current_buffer); | 824 | |
| 825 | data[0] = Fpoint_marker (); | ||
| 822 | /* Do not copy the mark if it points to nowhere. */ | 826 | /* Do not copy the mark if it points to nowhere. */ |
| 823 | Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer | 827 | data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer |
| 824 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) | 828 | ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) |
| 825 | : Qnil); | 829 | : Qnil); |
| 826 | 830 | /* Selected window if current buffer is shown in it, nil otherwise. */ | |
| 827 | return Fcons (Fpoint_marker (), | 831 | data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer) |
| 828 | Fcons (mark, | 832 | ? selected_window : Qnil); |
| 829 | Fcons (visible ? Qt : Qnil, | 833 | data[3] = BVAR (current_buffer, mark_active); |
| 830 | Fcons (BVAR (current_buffer, mark_active), | 834 | |
| 831 | selected_window)))); | 835 | save = make_save_value (data, 4); |
| 836 | XSAVE_VALUE (save)->dogc = 1; | ||
| 837 | return save; | ||
| 832 | } | 838 | } |
| 833 | 839 | ||
| 840 | /* Restore saved buffer before leaving `save-excursion' special form. */ | ||
| 841 | |||
| 834 | Lisp_Object | 842 | Lisp_Object |
| 835 | save_excursion_restore (Lisp_Object info) | 843 | save_excursion_restore (Lisp_Object info) |
| 836 | { | 844 | { |
| 837 | Lisp_Object tem, tem1, omark, nmark; | 845 | Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer; |
| 838 | struct gcpro gcpro1, gcpro2, gcpro3; | 846 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 839 | bool visible_p; | ||
| 840 | 847 | ||
| 841 | tem = Fmarker_buffer (XCAR (info)); | 848 | tem = Fmarker_buffer (data[0]); |
| 842 | /* If buffer being returned to is now deleted, avoid error */ | 849 | /* If we're unwinding to top level, saved buffer may be deleted. This |
| 843 | /* Otherwise could get error here while unwinding to top level | 850 | means that all of its markers are unchained and so tem is nil. */ |
| 844 | and crash */ | ||
| 845 | /* In that case, Fmarker_buffer returns nil now. */ | ||
| 846 | if (NILP (tem)) | 851 | if (NILP (tem)) |
| 847 | return Qnil; | 852 | goto out; |
| 848 | 853 | ||
| 849 | omark = nmark = Qnil; | 854 | omark = nmark = Qnil; |
| 850 | GCPRO3 (info, omark, nmark); | 855 | GCPRO3 (info, omark, nmark); |
| @@ -852,13 +857,12 @@ save_excursion_restore (Lisp_Object info) | |||
| 852 | Fset_buffer (tem); | 857 | Fset_buffer (tem); |
| 853 | 858 | ||
| 854 | /* Point marker. */ | 859 | /* Point marker. */ |
| 855 | tem = XCAR (info); | 860 | tem = data[0]; |
| 856 | Fgoto_char (tem); | 861 | Fgoto_char (tem); |
| 857 | unchain_marker (XMARKER (tem)); | 862 | unchain_marker (XMARKER (tem)); |
| 858 | 863 | ||
| 859 | /* Mark marker. */ | 864 | /* Mark marker. */ |
| 860 | info = XCDR (info); | 865 | tem = data[1]; |
| 861 | tem = XCAR (info); | ||
| 862 | omark = Fmarker_position (BVAR (current_buffer, mark)); | 866 | omark = Fmarker_position (BVAR (current_buffer, mark)); |
| 863 | if (NILP (tem)) | 867 | if (NILP (tem)) |
| 864 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); | 868 | unchain_marker (XMARKER (BVAR (current_buffer, mark))); |
| @@ -869,23 +873,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 869 | unchain_marker (XMARKER (tem)); | 873 | unchain_marker (XMARKER (tem)); |
| 870 | } | 874 | } |
| 871 | 875 | ||
| 872 | /* visible */ | 876 | /* Mark active. */ |
| 873 | info = XCDR (info); | 877 | tem = data[3]; |
| 874 | visible_p = !NILP (XCAR (info)); | ||
| 875 | |||
| 876 | #if 0 /* We used to make the current buffer visible in the selected window | ||
| 877 | if that was true previously. That avoids some anomalies. | ||
| 878 | But it creates others, and it wasn't documented, and it is simpler | ||
| 879 | and cleaner never to alter the window/buffer connections. */ | ||
| 880 | tem1 = Fcar (tem); | ||
| 881 | if (!NILP (tem1) | ||
| 882 | && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer)) | ||
| 883 | Fswitch_to_buffer (Fcurrent_buffer (), Qnil); | ||
| 884 | #endif /* 0 */ | ||
| 885 | |||
| 886 | /* Mark active */ | ||
| 887 | info = XCDR (info); | ||
| 888 | tem = XCAR (info); | ||
| 889 | tem1 = BVAR (current_buffer, mark_active); | 878 | tem1 = BVAR (current_buffer, mark_active); |
| 890 | bset_mark_active (current_buffer, tem); | 879 | bset_mark_active (current_buffer, tem); |
| 891 | 880 | ||
| @@ -909,8 +898,8 @@ save_excursion_restore (Lisp_Object info) | |||
| 909 | /* If buffer was visible in a window, and a different window was | 898 | /* If buffer was visible in a window, and a different window was |
| 910 | selected, and the old selected window is still showing this | 899 | selected, and the old selected window is still showing this |
| 911 | buffer, restore point in that window. */ | 900 | buffer, restore point in that window. */ |
| 912 | tem = XCDR (info); | 901 | tem = data[2]; |
| 913 | if (visible_p | 902 | if (WINDOWP (tem) |
| 914 | && !EQ (tem, selected_window) | 903 | && !EQ (tem, selected_window) |
| 915 | && (tem1 = XWINDOW (tem)->buffer, | 904 | && (tem1 = XWINDOW (tem)->buffer, |
| 916 | (/* Window is live... */ | 905 | (/* Window is live... */ |
| @@ -920,6 +909,10 @@ save_excursion_restore (Lisp_Object info) | |||
| 920 | Fset_window_point (tem, make_number (PT)); | 909 | Fset_window_point (tem, make_number (PT)); |
| 921 | 910 | ||
| 922 | UNGCPRO; | 911 | UNGCPRO; |
| 912 | |||
| 913 | out: | ||
| 914 | |||
| 915 | free_save_value (info); | ||
| 923 | return Qnil; | 916 | return Qnil; |
| 924 | } | 917 | } |
| 925 | 918 | ||
| @@ -2929,7 +2922,7 @@ Both characters must have the same length of multi-byte form. */) | |||
| 2929 | else if (!changed) | 2922 | else if (!changed) |
| 2930 | { | 2923 | { |
| 2931 | changed = -1; | 2924 | changed = -1; |
| 2932 | modify_region (current_buffer, pos, XINT (end), 0); | 2925 | modify_region_1 (pos, XINT (end), false); |
| 2933 | 2926 | ||
| 2934 | if (! NILP (noundo)) | 2927 | if (! NILP (noundo)) |
| 2935 | { | 2928 | { |
| @@ -3105,7 +3098,7 @@ It returns the number of characters changed. */) | |||
| 3105 | pos = XINT (start); | 3098 | pos = XINT (start); |
| 3106 | pos_byte = CHAR_TO_BYTE (pos); | 3099 | pos_byte = CHAR_TO_BYTE (pos); |
| 3107 | end_pos = XINT (end); | 3100 | end_pos = XINT (end); |
| 3108 | modify_region (current_buffer, pos, end_pos, 0); | 3101 | modify_region_1 (pos, end_pos, false); |
| 3109 | 3102 | ||
| 3110 | cnt = 0; | 3103 | cnt = 0; |
| 3111 | for (; pos < end_pos; ) | 3104 | for (; pos < end_pos; ) |
| @@ -4629,7 +4622,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4629 | 4622 | ||
| 4630 | if (end1 == start2) /* adjacent regions */ | 4623 | if (end1 == start2) /* adjacent regions */ |
| 4631 | { | 4624 | { |
| 4632 | modify_region (current_buffer, start1, end2, 0); | 4625 | modify_region_1 (start1, end2, false); |
| 4633 | record_change (start1, len1 + len2); | 4626 | record_change (start1, len1 + len2); |
| 4634 | 4627 | ||
| 4635 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4628 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4688,8 +4681,8 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4688 | { | 4681 | { |
| 4689 | USE_SAFE_ALLOCA; | 4682 | USE_SAFE_ALLOCA; |
| 4690 | 4683 | ||
| 4691 | modify_region (current_buffer, start1, end1, 0); | 4684 | modify_region_1 (start1, end1, false); |
| 4692 | modify_region (current_buffer, start2, end2, 0); | 4685 | modify_region_1 (start2, end2, false); |
| 4693 | record_change (start1, len1); | 4686 | record_change (start1, len1); |
| 4694 | record_change (start2, len2); | 4687 | record_change (start2, len2); |
| 4695 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4688 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| @@ -4722,7 +4715,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4722 | { | 4715 | { |
| 4723 | USE_SAFE_ALLOCA; | 4716 | USE_SAFE_ALLOCA; |
| 4724 | 4717 | ||
| 4725 | modify_region (current_buffer, start1, end2, 0); | 4718 | modify_region_1 (start1, end2, false); |
| 4726 | record_change (start1, (end2 - start1)); | 4719 | record_change (start1, (end2 - start1)); |
| 4727 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4720 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4728 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4721 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |
| @@ -4755,7 +4748,7 @@ Transposing beyond buffer boundaries is an error. */) | |||
| 4755 | USE_SAFE_ALLOCA; | 4748 | USE_SAFE_ALLOCA; |
| 4756 | 4749 | ||
| 4757 | record_change (start1, (end2 - start1)); | 4750 | record_change (start1, (end2 - start1)); |
| 4758 | modify_region (current_buffer, start1, end2, 0); | 4751 | modify_region_1 (start1, end2, false); |
| 4759 | 4752 | ||
| 4760 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); | 4753 | tmp_interval1 = copy_intervals (cur_intv, start1, len1); |
| 4761 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); | 4754 | tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); |