diff options
author | Eli Zaretskii <eliz@gnu.org> | 2016-08-08 18:15:55 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2016-08-08 18:15:55 +0300 |
commit | 9fc22fb932599fe4fecffffa920abe509ab5cbb0 (patch) | |
tree | 96b2bd8d9348ebcc2f817b5cb683030838587324 | |
parent | e2b7fe4e5ad532085d8f3a0227be9f37d7f8e1a7 (diff) | |
download | emacs-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.c | 34 |
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) |