it->dpvec = NULL;
it->current.dpvec_index = -1;
+ it->add_overlay_start = 0;
do
{
for (p = it_props; p->handler; ++p)
{
handled = p->handler (it);
-
+
if (handled == HANDLED_RECOMPUTE_PROPS)
break;
else if (handled == HANDLED_RETURN)
= TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (prop);
handled = HANDLED_RECOMPUTE_PROPS;
+ it->add_overlay_start = IT_CHARPOS (*it);
/* Loop skipping over invisible text. The loop is left at
ZV or with IT on the first char being visible again. */
struct overlay_entry
{
+ Lisp_Object overlay;
Lisp_Object string;
int priority;
int after_string_p;
handle_overlay_change (it)
struct it *it;
{
- /* Overlays are handled in current_buffer only. */
- if (STRINGP (it->string))
- return HANDLED_NORMALLY;
+ if (!STRINGP (it->string) && get_overlay_strings (it))
+ return HANDLED_RECOMPUTE_PROPS;
else
- return (get_overlay_strings (it)
- ? HANDLED_RECOMPUTE_PROPS
- : HANDLED_NORMALLY);
+ return HANDLED_NORMALLY;
}
SET_TEXT_POS (it->current.string_pos, -1, -1);
it->n_overlay_strings = 0;
it->method = next_element_from_buffer;
+
+ /* If we're at the end of the buffer, record that we have
+ processed the overlay strings there already, so that
+ next_element_from_buffer doesn't try it again. */
+ if (IT_CHARPOS (*it) >= it->end_charpos)
+ it->overlay_strings_at_end_processed_p = 1;
}
else
{
comparison function for qsort in load_overlay_strings. Overlay
strings for the same position are sorted so that
- 1. All after-strings come in front of before-strings.
+ 1. All after-strings come in front of before-strings, except
+ when they come from the same overlay.
2. Within after-strings, strings are sorted so that overlay strings
from overlays with higher priorities come first.
int result;
if (entry1->after_string_p != entry2->after_string_p)
- /* Let after-strings appear in front of before-strings. */
- result = entry1->after_string_p ? -1 : 1;
+ {
+ /* Let after-strings appear in front of before-strings if
+ they come from different overlays. */
+ if (EQ (entry1->overlay, entry2->overlay))
+ result = entry1->after_string_p ? 1 : -1;
+ else
+ result = entry1->after_string_p ? -1 : 1;
+ }
else if (entry1->after_string_p)
/* After-strings sorted in order of decreasing priority. */
result = entry2->priority - entry1->priority;
strings that have already been loaded by previous calls to this
function.
+ IT->add_overlay_start contains an additional overlay start
+ position to consider for taking overlay strings from, if non-zero.
+ This position comes into play when the overlay has an `invisible'
+ property, and both before and after-strings. When we've skipped to
+ the end of the overlay, because of its `invisible' property, we
+ nevertheless want its before-string to appear.
+ IT->add_overlay_start will contain the overlay start position
+ in this case.
+
Overlay strings are sorted so that after-string strings come in
front of before-string strings. Within before and after-strings,
strings are sorted by overlay priority. See also function
} \
\
entries[n].string = (STRING); \
+ entries[n].overlay = (OVERLAY); \
priority = Foverlay_get ((OVERLAY), Qpriority); \
- entries[n].priority \
- = INTEGERP (priority) ? XFASTINT (priority) : 0; \
+ entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
entries[n].after_string_p = (AFTER_P); \
++n; \
} \
while (0)
/* Process overlay before the overlay center. */
- for (ov = current_buffer->overlays_before;
- CONSP (ov);
- ov = XCDR (ov))
+ for (ov = current_buffer->overlays_before; CONSP (ov); ov = XCDR (ov))
{
overlay = XCAR (ov);
xassert (OVERLAYP (overlay));
/* Skip this overlay if it doesn't start or end at IT's current
position. */
- if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
+ if (end != IT_CHARPOS (*it)
+ && start != IT_CHARPOS (*it)
+ && it->add_overlay_start != IT_CHARPOS (*it))
continue;
/* Skip this overlay if it doesn't apply to IT->w. */
continue;
/* If overlay has a non-empty before-string, record it. */
- if (start == IT_CHARPOS (*it)
+ if ((start == IT_CHARPOS (*it)
+ || start == it->add_overlay_start)
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
&& XSTRING (str)->size)
RECORD_OVERLAY_STRING (overlay, str, 0);
}
/* Process overlays after the overlay center. */
- for (ov = current_buffer->overlays_after;
- CONSP (ov);
- ov = XCDR (ov))
+ for (ov = current_buffer->overlays_after; CONSP (ov); ov = XCDR (ov))
{
overlay = XCAR (ov);
xassert (OVERLAYP (overlay));
/* Skip this overlay if it doesn't start or end at IT's current
position. */
- if (end != IT_CHARPOS (*it) && start != IT_CHARPOS (*it))
+ if (end != IT_CHARPOS (*it)
+ && start != IT_CHARPOS (*it)
+ && it->add_overlay_start != IT_CHARPOS (*it))
continue;
/* Skip this overlay if it doesn't apply to IT->w. */
continue;
/* If overlay has a non-empty before-string, record it. */
- if (start == IT_CHARPOS (*it)
+ if ((start == IT_CHARPOS (*it)
+ || start == it->add_overlay_start)
&& (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
&& XSTRING (str)->size)
RECORD_OVERLAY_STRING (overlay, str, 0);
#undef RECORD_OVERLAY_STRING
/* Sort entries. */
- qsort (entries, n, sizeof *entries, compare_overlay_entries);
+ if (n)
+ qsort (entries, n, sizeof *entries, compare_overlay_entries);
/* Record the total number of strings to process. */
it->n_overlay_strings = n;
j = it->current.overlay_string_index;
while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
it->overlay_strings[i++] = entries[j++].string;
-
+
CHECK_IT (it);
}