Mercurial > emacs
comparison src/xdisp.c @ 29858:54f927c5f436
(handle_stop): Initialize it->add_overlay_start to zero.
(handle_invisible_prop): Record the start of invisible text in
it->add_overlay_start.
(struct overlay_entry): Add member `overlay'.
(handle_overlay_change): Simplify.
(next_overlay_string): After having processed overlay strings at the
end of the buffer, record that fact in
it->overlay_strings_at_end_processed_p.
(compare_overlay_entries): If before- and after-strings come
from the same overlay, let before-strings come first.
(RECORD_OVERLAY_STRING): Record the overlay that strings come from.
(load_overlay_strings): Take it->add_overlay_start into account
when adding overlay strings.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 22 Jun 2000 19:32:09 +0000 |
parents | 6c3a17ddb763 |
children | 8aa954de8db9 |
comparison
equal
deleted
inserted
replaced
29857:f1c1c620a093 | 29858:54f927c5f436 |
---|---|
1595 int handle_overlay_change_p = 1; | 1595 int handle_overlay_change_p = 1; |
1596 struct props *p; | 1596 struct props *p; |
1597 | 1597 |
1598 it->dpvec = NULL; | 1598 it->dpvec = NULL; |
1599 it->current.dpvec_index = -1; | 1599 it->current.dpvec_index = -1; |
1600 it->add_overlay_start = 0; | |
1600 | 1601 |
1601 do | 1602 do |
1602 { | 1603 { |
1603 handled = HANDLED_NORMALLY; | 1604 handled = HANDLED_NORMALLY; |
1604 | 1605 |
1605 /* Call text property handlers. */ | 1606 /* Call text property handlers. */ |
1606 for (p = it_props; p->handler; ++p) | 1607 for (p = it_props; p->handler; ++p) |
1607 { | 1608 { |
1608 handled = p->handler (it); | 1609 handled = p->handler (it); |
1609 | 1610 |
1610 if (handled == HANDLED_RECOMPUTE_PROPS) | 1611 if (handled == HANDLED_RECOMPUTE_PROPS) |
1611 break; | 1612 break; |
1612 else if (handled == HANDLED_RETURN) | 1613 else if (handled == HANDLED_RETURN) |
1613 return; | 1614 return; |
1614 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED) | 1615 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED) |
2113 invisible text. */ | 2114 invisible text. */ |
2114 int display_ellipsis_p | 2115 int display_ellipsis_p |
2115 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop); | 2116 = TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop); |
2116 | 2117 |
2117 handled = HANDLED_RECOMPUTE_PROPS; | 2118 handled = HANDLED_RECOMPUTE_PROPS; |
2119 it->add_overlay_start = IT_CHARPOS (*it); | |
2118 | 2120 |
2119 /* Loop skipping over invisible text. The loop is left at | 2121 /* Loop skipping over invisible text. The loop is left at |
2120 ZV or with IT on the first char being visible again. */ | 2122 ZV or with IT on the first char being visible again. */ |
2121 do | 2123 do |
2122 { | 2124 { |
2698 /* The following structure is used to record overlay strings for | 2700 /* The following structure is used to record overlay strings for |
2699 later sorting in load_overlay_strings. */ | 2701 later sorting in load_overlay_strings. */ |
2700 | 2702 |
2701 struct overlay_entry | 2703 struct overlay_entry |
2702 { | 2704 { |
2705 Lisp_Object overlay; | |
2703 Lisp_Object string; | 2706 Lisp_Object string; |
2704 int priority; | 2707 int priority; |
2705 int after_string_p; | 2708 int after_string_p; |
2706 }; | 2709 }; |
2707 | 2710 |
2711 | 2714 |
2712 static enum prop_handled | 2715 static enum prop_handled |
2713 handle_overlay_change (it) | 2716 handle_overlay_change (it) |
2714 struct it *it; | 2717 struct it *it; |
2715 { | 2718 { |
2716 /* Overlays are handled in current_buffer only. */ | 2719 if (!STRINGP (it->string) && get_overlay_strings (it)) |
2717 if (STRINGP (it->string)) | 2720 return HANDLED_RECOMPUTE_PROPS; |
2721 else | |
2718 return HANDLED_NORMALLY; | 2722 return HANDLED_NORMALLY; |
2719 else | |
2720 return (get_overlay_strings (it) | |
2721 ? HANDLED_RECOMPUTE_PROPS | |
2722 : HANDLED_NORMALLY); | |
2723 } | 2723 } |
2724 | 2724 |
2725 | 2725 |
2726 /* Set up the next overlay string for delivery by IT, if there is an | 2726 /* Set up the next overlay string for delivery by IT, if there is an |
2727 overlay string to deliver. Called by set_iterator_to_next when the | 2727 overlay string to deliver. Called by set_iterator_to_next when the |
2746 it->string = Qnil; | 2746 it->string = Qnil; |
2747 it->current.overlay_string_index = -1; | 2747 it->current.overlay_string_index = -1; |
2748 SET_TEXT_POS (it->current.string_pos, -1, -1); | 2748 SET_TEXT_POS (it->current.string_pos, -1, -1); |
2749 it->n_overlay_strings = 0; | 2749 it->n_overlay_strings = 0; |
2750 it->method = next_element_from_buffer; | 2750 it->method = next_element_from_buffer; |
2751 | |
2752 /* If we're at the end of the buffer, record that we have | |
2753 processed the overlay strings there already, so that | |
2754 next_element_from_buffer doesn't try it again. */ | |
2755 if (IT_CHARPOS (*it) >= it->end_charpos) | |
2756 it->overlay_strings_at_end_processed_p = 1; | |
2751 } | 2757 } |
2752 else | 2758 else |
2753 { | 2759 { |
2754 /* There are more overlay strings to process. If | 2760 /* There are more overlay strings to process. If |
2755 IT->current.overlay_string_index has advanced to a position | 2761 IT->current.overlay_string_index has advanced to a position |
2775 | 2781 |
2776 /* Compare two overlay_entry structures E1 and E2. Used as a | 2782 /* Compare two overlay_entry structures E1 and E2. Used as a |
2777 comparison function for qsort in load_overlay_strings. Overlay | 2783 comparison function for qsort in load_overlay_strings. Overlay |
2778 strings for the same position are sorted so that | 2784 strings for the same position are sorted so that |
2779 | 2785 |
2780 1. All after-strings come in front of before-strings. | 2786 1. All after-strings come in front of before-strings, except |
2787 when they come from the same overlay. | |
2781 | 2788 |
2782 2. Within after-strings, strings are sorted so that overlay strings | 2789 2. Within after-strings, strings are sorted so that overlay strings |
2783 from overlays with higher priorities come first. | 2790 from overlays with higher priorities come first. |
2784 | 2791 |
2785 2. Within before-strings, strings are sorted so that overlay | 2792 2. Within before-strings, strings are sorted so that overlay |
2795 struct overlay_entry *entry1 = (struct overlay_entry *) e1; | 2802 struct overlay_entry *entry1 = (struct overlay_entry *) e1; |
2796 struct overlay_entry *entry2 = (struct overlay_entry *) e2; | 2803 struct overlay_entry *entry2 = (struct overlay_entry *) e2; |
2797 int result; | 2804 int result; |
2798 | 2805 |
2799 if (entry1->after_string_p != entry2->after_string_p) | 2806 if (entry1->after_string_p != entry2->after_string_p) |
2800 /* Let after-strings appear in front of before-strings. */ | 2807 { |
2801 result = entry1->after_string_p ? -1 : 1; | 2808 /* Let after-strings appear in front of before-strings if |
2809 they come from different overlays. */ | |
2810 if (EQ (entry1->overlay, entry2->overlay)) | |
2811 result = entry1->after_string_p ? 1 : -1; | |
2812 else | |
2813 result = entry1->after_string_p ? -1 : 1; | |
2814 } | |
2802 else if (entry1->after_string_p) | 2815 else if (entry1->after_string_p) |
2803 /* After-strings sorted in order of decreasing priority. */ | 2816 /* After-strings sorted in order of decreasing priority. */ |
2804 result = entry2->priority - entry1->priority; | 2817 result = entry2->priority - entry1->priority; |
2805 else | 2818 else |
2806 /* Before-strings sorted in order of increasing priority. */ | 2819 /* Before-strings sorted in order of increasing priority. */ |
2817 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at | 2830 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at |
2818 a time. On entry into load_overlay_strings, | 2831 a time. On entry into load_overlay_strings, |
2819 IT->current.overlay_string_index gives the number of overlay | 2832 IT->current.overlay_string_index gives the number of overlay |
2820 strings that have already been loaded by previous calls to this | 2833 strings that have already been loaded by previous calls to this |
2821 function. | 2834 function. |
2835 | |
2836 IT->add_overlay_start contains an additional overlay start | |
2837 position to consider for taking overlay strings from, if non-zero. | |
2838 This position comes into play when the overlay has an `invisible' | |
2839 property, and both before and after-strings. When we've skipped to | |
2840 the end of the overlay, because of its `invisible' property, we | |
2841 nevertheless want its before-string to appear. | |
2842 IT->add_overlay_start will contain the overlay start position | |
2843 in this case. | |
2822 | 2844 |
2823 Overlay strings are sorted so that after-string strings come in | 2845 Overlay strings are sorted so that after-string strings come in |
2824 front of before-string strings. Within before and after-strings, | 2846 front of before-string strings. Within before and after-strings, |
2825 strings are sorted by overlay priority. See also function | 2847 strings are sorted by overlay priority. See also function |
2826 compare_overlay_entries. */ | 2848 compare_overlay_entries. */ |
2856 bcopy (old, entries, size * sizeof *entries); \ | 2878 bcopy (old, entries, size * sizeof *entries); \ |
2857 size = new_size; \ | 2879 size = new_size; \ |
2858 } \ | 2880 } \ |
2859 \ | 2881 \ |
2860 entries[n].string = (STRING); \ | 2882 entries[n].string = (STRING); \ |
2883 entries[n].overlay = (OVERLAY); \ | |
2861 priority = Foverlay_get ((OVERLAY), Qpriority); \ | 2884 priority = Foverlay_get ((OVERLAY), Qpriority); \ |
2862 entries[n].priority \ | 2885 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \ |
2863 = INTEGERP (priority) ? XFASTINT (priority) : 0; \ | |
2864 entries[n].after_string_p = (AFTER_P); \ | 2886 entries[n].after_string_p = (AFTER_P); \ |
2865 ++n; \ | 2887 ++n; \ |
2866 } \ | 2888 } \ |
2867 while (0) | 2889 while (0) |
2868 | 2890 |
2869 /* Process overlay before the overlay center. */ | 2891 /* Process overlay before the overlay center. */ |
2870 for (ov = current_buffer->overlays_before; | 2892 for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov)) |
2871 CONSP (ov); | |
2872 ov = XCDR (ov)) | |
2873 { | 2893 { |
2874 overlay = XCAR (ov); | 2894 overlay = XCAR (ov); |
2875 xassert (OVERLAYP (overlay)); | 2895 xassert (OVERLAYP (overlay)); |
2876 start = OVERLAY_POSITION (OVERLAY_START (overlay)); | 2896 start = OVERLAY_POSITION (OVERLAY_START (overlay)); |
2877 end = OVERLAY_POSITION (OVERLAY_END (overlay)); | 2897 end = OVERLAY_POSITION (OVERLAY_END (overlay)); |
2879 if (end < IT_CHARPOS (*it)) | 2899 if (end < IT_CHARPOS (*it)) |
2880 break; | 2900 break; |
2881 | 2901 |
2882 /* Skip this overlay if it doesn't start or end at IT's current | 2902 /* Skip this overlay if it doesn't start or end at IT's current |
2883 position. */ | 2903 position. */ |
2884 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it)) | 2904 if (end != IT_CHARPOS (*it) |
2905 && start != IT_CHARPOS (*it) | |
2906 && it->add_overlay_start != IT_CHARPOS (*it)) | |
2885 continue; | 2907 continue; |
2886 | 2908 |
2887 /* Skip this overlay if it doesn't apply to IT->w. */ | 2909 /* Skip this overlay if it doesn't apply to IT->w. */ |
2888 window = Foverlay_get (overlay, Qwindow); | 2910 window = Foverlay_get (overlay, Qwindow); |
2889 if (WINDOWP (window) && XWINDOW (window) != it->w) | 2911 if (WINDOWP (window) && XWINDOW (window) != it->w) |
2890 continue; | 2912 continue; |
2891 | 2913 |
2892 /* If overlay has a non-empty before-string, record it. */ | 2914 /* If overlay has a non-empty before-string, record it. */ |
2893 if (start == IT_CHARPOS (*it) | 2915 if ((start == IT_CHARPOS (*it) |
2916 || start == it->add_overlay_start) | |
2894 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) | 2917 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) |
2895 && XSTRING (str)->size) | 2918 && XSTRING (str)->size) |
2896 RECORD_OVERLAY_STRING (overlay, str, 0); | 2919 RECORD_OVERLAY_STRING (overlay, str, 0); |
2897 | 2920 |
2898 /* If overlay has a non-empty after-string, record it. */ | 2921 /* If overlay has a non-empty after-string, record it. */ |
2901 && XSTRING (str)->size) | 2924 && XSTRING (str)->size) |
2902 RECORD_OVERLAY_STRING (overlay, str, 1); | 2925 RECORD_OVERLAY_STRING (overlay, str, 1); |
2903 } | 2926 } |
2904 | 2927 |
2905 /* Process overlays after the overlay center. */ | 2928 /* Process overlays after the overlay center. */ |
2906 for (ov = current_buffer->overlays_after; | 2929 for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov)) |
2907 CONSP (ov); | |
2908 ov = XCDR (ov)) | |
2909 { | 2930 { |
2910 overlay = XCAR (ov); | 2931 overlay = XCAR (ov); |
2911 xassert (OVERLAYP (overlay)); | 2932 xassert (OVERLAYP (overlay)); |
2912 start = OVERLAY_POSITION (OVERLAY_START (overlay)); | 2933 start = OVERLAY_POSITION (OVERLAY_START (overlay)); |
2913 end = OVERLAY_POSITION (OVERLAY_END (overlay)); | 2934 end = OVERLAY_POSITION (OVERLAY_END (overlay)); |
2915 if (start > IT_CHARPOS (*it)) | 2936 if (start > IT_CHARPOS (*it)) |
2916 break; | 2937 break; |
2917 | 2938 |
2918 /* Skip this overlay if it doesn't start or end at IT's current | 2939 /* Skip this overlay if it doesn't start or end at IT's current |
2919 position. */ | 2940 position. */ |
2920 if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it)) | 2941 if (end != IT_CHARPOS (*it) |
2942 && start != IT_CHARPOS (*it) | |
2943 && it->add_overlay_start != IT_CHARPOS (*it)) | |
2921 continue; | 2944 continue; |
2922 | 2945 |
2923 /* Skip this overlay if it doesn't apply to IT->w. */ | 2946 /* Skip this overlay if it doesn't apply to IT->w. */ |
2924 window = Foverlay_get (overlay, Qwindow); | 2947 window = Foverlay_get (overlay, Qwindow); |
2925 if (WINDOWP (window) && XWINDOW (window) != it->w) | 2948 if (WINDOWP (window) && XWINDOW (window) != it->w) |
2926 continue; | 2949 continue; |
2927 | 2950 |
2928 /* If overlay has a non-empty before-string, record it. */ | 2951 /* If overlay has a non-empty before-string, record it. */ |
2929 if (start == IT_CHARPOS (*it) | 2952 if ((start == IT_CHARPOS (*it) |
2953 || start == it->add_overlay_start) | |
2930 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) | 2954 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str)) |
2931 && XSTRING (str)->size) | 2955 && XSTRING (str)->size) |
2932 RECORD_OVERLAY_STRING (overlay, str, 0); | 2956 RECORD_OVERLAY_STRING (overlay, str, 0); |
2933 | 2957 |
2934 /* If overlay has a non-empty after-string, record it. */ | 2958 /* If overlay has a non-empty after-string, record it. */ |
2939 } | 2963 } |
2940 | 2964 |
2941 #undef RECORD_OVERLAY_STRING | 2965 #undef RECORD_OVERLAY_STRING |
2942 | 2966 |
2943 /* Sort entries. */ | 2967 /* Sort entries. */ |
2944 qsort (entries, n, sizeof *entries, compare_overlay_entries); | 2968 if (n) |
2969 qsort (entries, n, sizeof *entries, compare_overlay_entries); | |
2945 | 2970 |
2946 /* Record the total number of strings to process. */ | 2971 /* Record the total number of strings to process. */ |
2947 it->n_overlay_strings = n; | 2972 it->n_overlay_strings = n; |
2948 | 2973 |
2949 /* IT->current.overlay_string_index is the number of overlay strings | 2974 /* IT->current.overlay_string_index is the number of overlay strings |
2951 remaining overlay strings to IT->overlay_strings. */ | 2976 remaining overlay strings to IT->overlay_strings. */ |
2952 i = 0; | 2977 i = 0; |
2953 j = it->current.overlay_string_index; | 2978 j = it->current.overlay_string_index; |
2954 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n) | 2979 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n) |
2955 it->overlay_strings[i++] = entries[j++].string; | 2980 it->overlay_strings[i++] = entries[j++].string; |
2956 | 2981 |
2957 CHECK_IT (it); | 2982 CHECK_IT (it); |
2958 } | 2983 } |
2959 | 2984 |
2960 | 2985 |
2961 /* Get the first chunk of overlay strings at IT's current buffer | 2986 /* Get the first chunk of overlay strings at IT's current buffer |