mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-25 07:28:20 +00:00
(zv_strings_seen): New variable.
(redisplay, try_window, try_window_id): Clear zv_strings_seen. (display_text_line): Handle overlay strings.
This commit is contained in:
parent
2ab90d49d6
commit
ca26e1c813
243
src/xdisp.c
243
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 @@ redisplay_window (window, just_this_one)
|
||||
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,26 +2514,70 @@ 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;
|
||||
while (pos == next_boundary)
|
||||
{
|
||||
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;
|
||||
|
||||
XSETFASTINT (position, pos);
|
||||
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. */
|
||||
if (XFASTINT (limit) > pos + 50)
|
||||
XSETFASTINT (limit, pos + 50);
|
||||
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_boundary >= PT)
|
||||
{
|
||||
cursor_vpos = vpos;
|
||||
cursor_hpos = p1 - leftmargin;
|
||||
}
|
||||
pos = next_boundary;
|
||||
last_invis_skip = pos;
|
||||
last_invis_prop = prop;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we reach point? Record the cursor location. */
|
||||
if (pos == PT && cursor_vpos < 0)
|
||||
@ -2532,42 +2586,10 @@ display_text_line (w, start, vpos, hpos, taboffset)
|
||||
cursor_hpos = p1 - leftmargin;
|
||||
}
|
||||
|
||||
#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);
|
||||
/* 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;
|
||||
if (TEXT_PROP_MEANS_INVISIBLE (prop))
|
||||
{
|
||||
if (pos < PT && next_invisible >= PT)
|
||||
{
|
||||
cursor_vpos = vpos;
|
||||
cursor_hpos = p1 - leftmargin;
|
||||
}
|
||||
pos = next_invisible;
|
||||
last_invis_skip = pos;
|
||||
last_invis_prop = prop;
|
||||
}
|
||||
}
|
||||
if (pos >= end)
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user