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