From ca26e1c813aed5337aa2322e70beeba5f6eb8503 Mon Sep 17 00:00:00 2001 From: Karl Heuer Date: Thu, 18 May 1995 22:49:59 +0000 Subject: [PATCH] (zv_strings_seen): New variable. (redisplay, try_window, try_window_id): Clear zv_strings_seen. (display_text_line): Handle overlay strings. --- src/xdisp.c | 225 ++++++++++++++++++++++++++++------------------------ 1 file changed, 123 insertions(+), 102 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 1cf979bd6cc..9568a37ef84 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -122,6 +122,11 @@ Lisp_Object Qmenu_bar_update_hook; /* Nonzero if overlay arrow has been displayed once in this window. */ static int overlay_arrow_seen; +/* Nonzero if visible end of buffer has already been displayed once + in this window. (We need this variable in case there are overlay + strings that get displayed there.) */ +static int zv_strings_seen; + /* Nonzero means highlight the region even in nonselected windows. */ static int highlight_nonselected_windows; @@ -877,6 +882,7 @@ redisplay () { cursor_vpos = -1; overlay_arrow_seen = 0; + zv_strings_seen = 0; display_text_line (w, tlbufpos, this_line_vpos, this_line_start_hpos, pos_tab_offset (w, tlbufpos)); /* If line contains point, is not continued, @@ -932,6 +938,7 @@ redisplay () { pos = *compute_motion (tlbufpos, 0, XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0, + 0, PT, 2, - (1 << (SHORTBITS - 1)), window_internal_width (w) - 1, XINT (w->hscroll), @@ -1433,13 +1440,14 @@ redisplay_window (window, just_this_one) { /* If point does not appear, move point so it does appear */ pos = *compute_motion (startp, 0, - ((EQ (window, minibuf_window) && startp == 1) - ? minibuf_prompt_width : 0) - + - (hscroll ? 1 - hscroll : 0), - ZV, height / 2, - - (1 << (SHORTBITS - 1)), - width, hscroll, pos_tab_offset (w, startp), w); + (((EQ (window, minibuf_window) + && startp == BEG) + ? minibuf_prompt_width : 0) + + (hscroll ? 1 - hscroll : 0)), + 0, + ZV, height / 2, + - (1 << (SHORTBITS - 1)), + width, hscroll, pos_tab_offset (w, startp), w); BUF_PT (current_buffer) = pos.bufpos; if (w != XWINDOW (selected_window)) Fset_marker (w->pointm, make_number (PT), Qnil); @@ -1488,7 +1496,7 @@ redisplay_window (window, just_this_one) && XFASTINT (w->window_end_vpos) < XFASTINT (w->height) && !EQ (window, minibuf_window)) { - pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), + pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0, PT, height, 0, width, hscroll, pos_tab_offset (w, startp), w); @@ -1615,7 +1623,7 @@ recenter: try_window (window, pos.bufpos); startp = marker_position (w->start); - w->start_at_line_beg + w->start_at_line_beg = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; done: @@ -1707,6 +1715,7 @@ try_window (window, pos) Fset_marker (w->start, make_number (pos), Qnil); cursor_vpos = -1; overlay_arrow_seen = 0; + zv_strings_seen = 0; val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; while (--height >= 0) @@ -1777,6 +1786,7 @@ try_window_id (window) int width = window_internal_width (w) - 1; int hscroll = XINT (w->hscroll); int lmargin = hscroll > 0 ? 1 - hscroll : 0; + int did_motion; register int vpos; register int i, tem; int last_text_vpos = 0; @@ -1799,7 +1809,7 @@ try_window_id (window) return 0; /* Give up if changes go above top of window */ /* Find position before which nothing is changed. */ - bp = *compute_motion (start, 0, lmargin, + bp = *compute_motion (start, 0, lmargin, 0, min (ZV, beg_unchanged + BEG), height, 0, width, hscroll, pos_tab_offset (w, start), w); if (bp.vpos >= height) @@ -1810,7 +1820,7 @@ try_window_id (window) We don't need to change the frame at all. But we need to update window_end_pos to account for any change in buffer size. */ - bp = *compute_motion (start, 0, lmargin, + bp = *compute_motion (start, 0, lmargin, 0, Z, height, 0, width, hscroll, pos_tab_offset (w, start), w); XSETFASTINT (w->window_end_vpos, height); @@ -1830,6 +1840,7 @@ try_window_id (window) if (pos < start) return -1; + did_motion = 0; /* If about to start displaying at the beginning of a continuation line, really start with previous frame line, in case it was not continued when last redisplayed */ @@ -1846,6 +1857,7 @@ try_window_id (window) if (bp.contin && bp.hpos != lmargin) { val.hpos = bp.prevhpos - width + lmargin; + did_motion = 1; pos--; } @@ -1858,7 +1870,7 @@ try_window_id (window) tem = find_next_newline (tem, 1); /* Compute the cursor position after that newline. */ - ep = *compute_motion (pos, vpos, val.hpos, tem, + ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem, height, - (1 << (SHORTBITS - 1)), width, hscroll, pos_tab_offset (w, bp.bufpos), w); @@ -1882,6 +1894,7 @@ try_window_id (window) cursor_vpos = -1; overlay_arrow_seen = 0; + zv_strings_seen = 0; /* If changes do not reach to bottom of window, figure out how much to scroll the rest of the window */ @@ -1889,7 +1902,7 @@ try_window_id (window) { /* Now determine how far up or down the rest of the window has moved */ epto = pos_tab_offset (w, ep.bufpos); - xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, + xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1, Z - XFASTINT (w->window_end_pos), 10000, 0, width, hscroll, epto, w); scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos); @@ -1913,13 +1926,13 @@ try_window_id (window) { if (PT <= xp.bufpos) { - pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, + pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1, PT, height, - (1 << (SHORTBITS - 1)), width, hscroll, epto, w); } else { - pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, + pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1, PT, height, - (1 << (SHORTBITS - 1)), width, hscroll, pos_tab_offset (w, xp.bufpos), w); @@ -2122,7 +2135,7 @@ try_window_id (window) if (cursor_vpos < 0) { findpoint: - val = *compute_motion (start, 0, lmargin, PT, 10000, 10000, + val = *compute_motion (start, 0, lmargin, 0, PT, 10000, 10000, width, hscroll, pos_tab_offset (w, start), w); /* Admit failure if point is off frame now */ if (val.vpos >= height) @@ -2140,7 +2153,7 @@ try_window_id (window) if (debug_end_pos) { - val = *compute_motion (start, 0, lmargin, ZV, + val = *compute_motion (start, 0, lmargin, 0, ZV, height, - (1 << (SHORTBITS - 1)), width, hscroll, pos_tab_offset (w, start), w); if (val.vpos != XFASTINT (w->window_end_vpos)) @@ -2331,13 +2344,13 @@ display_text_line (w, start, vpos, hpos, taboffset) register int pos = start; register int c; register GLYPH *p1; - int end; register int pause; register unsigned char *p; GLYPH *endp; register GLYPH *leftmargin; - register GLYPH *p1prev = 0; + register GLYPH *p1prev; register GLYPH *p1start; + int prevpos; int *charstart; FRAME_PTR f = XFRAME (w->frame); int tab_width = XINT (current_buffer->tab_width); @@ -2390,11 +2403,10 @@ display_text_line (w, start, vpos, hpos, taboffset) to overlays or text property changes. */ int next_face_change; -#ifdef USE_TEXT_PROPERTIES - /* The next location where the `invisible' property changes */ - int next_invisible; -#endif - + /* The next location where the `invisible' property changes, or an + overlay starts or ends. */ + int next_boundary; + /* The face we're currently using. */ int current_face = 0; int i; @@ -2426,7 +2438,7 @@ display_text_line (w, start, vpos, hpos, taboffset) region_beg = region_end = -1; if (MINI_WINDOW_P (w) - && start == 1 + && start == BEG && vpos == XFASTINT (w->top)) { if (! NILP (minibuf_prompt)) @@ -2449,16 +2461,14 @@ display_text_line (w, start, vpos, hpos, taboffset) minibuf_prompt_width = 0; } - end = ZV; - /* If we're hscrolled at all, use compute_motion to skip over any text off the left edge of the window. compute_motion may know tricks to do this faster than we can. */ if (hpos < 0) { struct position *left_edge - = compute_motion (pos, vpos, hpos, - end, vpos, 0, + = compute_motion (pos, vpos, hpos, 0, + ZV, vpos, 0, width, hscroll, taboffset, w); /* Retrieve the buffer position and column provided by @@ -2504,70 +2514,82 @@ display_text_line (w, start, vpos, hpos, taboffset) or at face change. */ pause = pos; next_face_change = pos; -#ifdef USE_TEXT_PROPERTIES - next_invisible = pos; -#endif + next_boundary = pos; + p1prev = p1; + prevpos = pos; while (1) { - /* Record which glyph starts a character, - and the character position of that character. */ - if (p1 >= leftmargin) - charstart[p1 - p1start] = pos; - - if (p1 >= endp) - break; - - p1prev = p1; if (pos >= pause) { - /* Did we hit the end of the visible region of the buffer? - Stop here. */ - if (pos >= end) - break; - - /* Did we reach point? Record the cursor location. */ - if (pos == PT && cursor_vpos < 0) + while (pos == next_boundary) { - cursor_vpos = vpos; - cursor_hpos = p1 - leftmargin; - } + Lisp_Object position, limit, prop, ww; + + /* Display the overlay strings here, unless we're at ZV + and have already displayed the appropriate strings + on an earlier line. */ + if (pos < ZV || !zv_strings_seen++) + { + int ovlen; + char *ovstr; + ovlen = overlay_strings (pos, w, &ovstr); + for (; ovlen; ovlen--, ovstr++) + { + if (p1 >= leftmargin && p1 < endp) + *p1 = MAKE_GLYPH (f, *ovstr, current_face); + p1++; + } + } + + /* Did we reach point? Record the cursor location. */ + if (pos == PT && cursor_vpos < 0) + { + cursor_vpos = vpos; + cursor_hpos = p1 - leftmargin; + } + + if (pos >= ZV) + break; -#ifdef USE_TEXT_PROPERTIES - /* if the `invisible' property is set to t, we can skip to - the next property change */ - while (pos == next_invisible && pos < end) - { - Lisp_Object position, limit, endpos, prop, ww; XSETFASTINT (position, pos); - XSETWINDOW (ww, w); - prop = Fget_char_property (position, Qinvisible, ww); + limit = Fnext_overlay_change (position); +#ifdef USE_TEXT_PROPERTIES /* This is just an estimate to give reasonable performance; nothing should go wrong if it is too small. */ - limit = Fnext_overlay_change (position); if (XFASTINT (limit) > pos + 50) XSETFASTINT (limit, pos + 50); - endpos = Fnext_single_property_change (position, Qinvisible, - Fcurrent_buffer (), - limit); - if (INTEGERP (endpos)) - next_invisible = XINT (endpos); - else - next_invisible = end; + limit = Fnext_single_property_change (position, Qinvisible, + Fcurrent_buffer (), limit); +#endif + next_boundary = XFASTINT (limit); + /* if the `invisible' property is set, we can skip to + the next property change. */ + XSETWINDOW (ww, w); + prop = Fget_char_property (position, Qinvisible, ww); if (TEXT_PROP_MEANS_INVISIBLE (prop)) { - if (pos < PT && next_invisible >= PT) + if (pos < PT && next_boundary >= PT) { cursor_vpos = vpos; cursor_hpos = p1 - leftmargin; } - pos = next_invisible; + pos = next_boundary; last_invis_skip = pos; last_invis_prop = prop; } } - if (pos >= end) + + /* Did we reach point? Record the cursor location. */ + if (pos == PT && cursor_vpos < 0) + { + cursor_vpos = vpos; + cursor_hpos = p1 - leftmargin; + } + + /* Did we hit the end of the visible region of the buffer? + Stop here. */ + if (pos >= ZV) break; -#endif #ifdef HAVE_FACES /* Did we hit a face change? Figure out what face we should @@ -2579,12 +2601,10 @@ display_text_line (w, start, vpos, hpos, taboffset) &next_face_change, pos + 50, 0); #endif - pause = end; + pause = ZV; -#ifdef USE_TEXT_PROPERTIES - if (pos < next_invisible && next_invisible < pause) - pause = next_invisible; -#endif + if (pos < next_boundary && next_boundary < pause) + pause = next_boundary; if (pos < next_face_change && next_face_change < pause) pause = next_face_change; @@ -2597,6 +2617,31 @@ display_text_line (w, start, vpos, hpos, taboffset) p = &FETCH_CHAR (pos); } + + /* Do nothing here for a char that's entirely off the left edge. */ + if (p1 >= leftmargin) + { + /* For all the glyphs occupied by this character, except for the + first, store -1 in charstarts. */ + if (p1 != p1prev) + { + int *p2x = &charstart[(p1prev < leftmargin + ? leftmargin : p1prev) + - p1start]; + int *p2 = &charstart[(p1 < endp ? p1 : endp) - p1start]; + + if (p2x < p2) + *p2x++ = prevpos; + while (p2x < p2) + *p2x++ = -1; + } + } + + if (p1 >= endp) + break; + + p1prev = p1; + c = *p++; /* Let a display table override all standard display methods. */ if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) @@ -2618,7 +2663,7 @@ display_text_line (w, start, vpos, hpos, taboffset) if (last_invis_skip == pos && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop)) invis = 1; - while (pos + 1 < end + while (pos + 1 < ZV && selective > 0 && indented_beyond_p (pos + 1, selective)) { @@ -2714,31 +2759,7 @@ display_text_line (w, start, vpos, hpos, taboffset) p1++; } - /* Do nothing here for a char that's entirely off the left edge. */ - if (p1 >= leftmargin) - { - /* For all the glyphs occupied by this character, except for the - first, store -1 in charstarts. */ - if (p1 != p1prev) - { - int *p2x = &charstart[p1prev - p1start]; - int *p2 = &charstart[(p1 < endp ? p1 : endp) - p1start]; - - /* The window's left column should always - contain a character position. - And don't clobber anything to the left of that. */ - if (p1prev < leftmargin) - { - p2x = charstart + (leftmargin - p1start); - *p2x = pos; - } - - /* This loop skips over the char p2x initially points to. */ - while (++p2x < p2) - *p2x = -1; - } - } - + prevpos = pos; pos++; } -- 2.39.2