From 842b3d7412eaed6b2c9f90c3361abb4932ec0b1d Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 30 Mar 2018 15:57:57 +0300 Subject: [PATCH] Fix C-p and C-n when wrap-prefix is too wide * src/xdisp.c (move_it_in_display_line_to): Avoid looping in previous/next-line when wrap-prefix is set to a too-wide stretch of whitespace. (Bug#30432) --- src/xdisp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/xdisp.c b/src/xdisp.c index df5335e4acc..50fd6857784 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9209,9 +9209,25 @@ move_it_in_display_line_to (struct it *it, prev_method = it->method; if (it->method == GET_FROM_BUFFER) prev_pos = IT_CHARPOS (*it); + + /* Detect overly-wide wrap-prefixes made of (space ...) display + properties. When such a wrap prefix reaches past the right + margin of the window, we need to avoid the call to + set_iterator_to_next below, so that it->line_wrap is left at + its TRUNCATE value wisely set by handle_line_prefix. + Otherwise, set_iterator_to_next will pop the iterator stack, + restore it->line_wrap, and we might miss the opportunity to + exit the loop and return. */ + bool overwide_wrap_prefix = + CONSP (it->object) && EQ (XCAR (it->object), Qspace) + && it->sp > 0 && it->method == GET_FROM_STRETCH + && it->current_x >= it->last_visible_x + && it->continuation_lines_width > 0 + && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE; /* The current display element has been consumed. Advance to the next. */ - set_iterator_to_next (it, true); + if (!overwide_wrap_prefix) + set_iterator_to_next (it, true); if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); if (IT_CHARPOS (*it) < to_charpos) -- 2.39.2