summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2016-08-08 18:15:55 +0300
committerEli Zaretskii <eliz@gnu.org>2016-08-08 18:15:55 +0300
commit9fc22fb932599fe4fecffffa920abe509ab5cbb0 (patch)
tree96b2bd8d9348ebcc2f817b5cb683030838587324
parente2b7fe4e5ad532085d8f3a0227be9f37d7f8e1a7 (diff)
downloademacs-9fc22fb932599fe4fecffffa920abe509ab5cbb0.tar.gz
emacs-9fc22fb932599fe4fecffffa920abe509ab5cbb0.tar.bz2
emacs-9fc22fb932599fe4fecffffa920abe509ab5cbb0.zip
Fix cursor position under scroll-conservatively and overlay strings
* src/xdisp.c (try_scrolling): Handle the case where the last visible screen line of a window displays a before- or after-string that takes up the whole screen line, and therefore there's no place to display the cursor, even though the window does seem to include the position of point. (Bug#24179)
-rw-r--r--src/xdisp.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index efd5f54fa39..21fc01f1e69 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15313,6 +15313,40 @@ try_scrolling (Lisp_Object window, bool just_this_one_p,
if (dy > 0)
scroll_down_p = true;
}
+ else if (PT == IT_CHARPOS (it)
+ && IT_CHARPOS (it) < ZV
+ && it.method == GET_FROM_STRING
+ && arg_scroll_conservatively > scroll_limit
+ && it.current_x == 0)
+ {
+ enum move_it_result skip;
+ int y1 = it.current_y;
+ int vpos;
+
+ /* A before-string that includes newlines and is displayed
+ on the last visible screen line could fail us under
+ scroll-conservatively > 100, because we will be unable to
+ position the cursor on that last visible line. Try to
+ recover by finding the first screen line that has some
+ glyphs coming from the buffer text. */
+ do {
+ skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
+ if (skip != MOVE_NEWLINE_OR_CR
+ || IT_CHARPOS (it) != PT
+ || it.method == GET_FROM_BUFFER)
+ break;
+ vpos = it.vpos;
+ move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
+ } while (it.vpos > vpos);
+
+ dy = it.current_y - y1;
+
+ if (dy > scroll_max)
+ return SCROLLING_FAILED;
+
+ if (dy > 0)
+ scroll_down_p = true;
+ }
}
if (scroll_down_p)