]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix C-p and C-n when wrap-prefix is too wide
authorEli Zaretskii <eliz@gnu.org>
Fri, 30 Mar 2018 12:57:57 +0000 (15:57 +0300)
committerEli Zaretskii <eliz@gnu.org>
Fri, 30 Mar 2018 12:57:57 +0000 (15:57 +0300)
* 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

index df5335e4accecd175ccc439bada62458516b62d9..50fd6857784b7537a43bfbcb47dcedc14a9df59e 100644 (file)
@@ -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)