aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
authorLuuk van Baal <luukvbaal@gmail.com>2023-04-27 19:40:00 +0200
committerLuuk van Baal <luukvbaal@gmail.com>2023-05-02 13:11:47 +0200
commit46646a9bb81b72d5579beade64006d6f3dc64d19 (patch)
tree2b4448c2fad12ea7fdd56f30ceb623d1fb73d5d8 /src/nvim
parent26a9f0e94eb62047f0c2bb99401a8ac09840d0dd (diff)
downloadrneovim-46646a9bb81b72d5579beade64006d6f3dc64d19.tar.gz
rneovim-46646a9bb81b72d5579beade64006d6f3dc64d19.tar.bz2
rneovim-46646a9bb81b72d5579beade64006d6f3dc64d19.zip
vim-patch:9.0.0908: with 'smoothscroll' cursor may end up in wrong position
Problem: With 'smoothscroll' cursor may end up in wrong position. Solution: Correct the computation of screen lines. (Yee Cheng Chin, closes vim/vim#11502) https://github.com/vim/vim/commit/361895d2a15b4b0bbbb4c009261eab5b3d69ebf1 Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/move.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c
index b0a4a3848a..abe908cfa0 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -1877,18 +1877,43 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
// The lines of the cursor line itself are always used.
used = plines_win_nofill(curwin, cln, true);
- // If the cursor is below botline, we will at least scroll by the height
- // of the cursor line. Correct for empty lines, which are really part of
- // botline.
+ // If the cursor is on or below botline, we will at least scroll by the
+ // height of the cursor line, which is "used". Correct for empty lines,
+ // which are really part of botline.
if (cln >= curwin->w_botline) {
scrolled = used;
if (cln == curwin->w_botline) {
scrolled -= curwin->w_empty_rows;
}
min_scrolled = scrolled;
- if (cln > curwin->w_botline && curwin->w_p_sms && curwin->w_p_wrap) {
- for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; lnum++) {
- min_scrolled += plines_win_nofill(curwin, lnum, true);
+ if (curwin->w_p_sms && curwin->w_p_wrap) {
+ // 'smoothscroll' and 'wrap' are set
+ if (cln > curwin->w_botline) {
+ // add screen lines below w_botline
+ for (linenr_T lnum = curwin->w_botline + 1; lnum <= cln; lnum++) {
+ min_scrolled += plines_win_nofill(curwin, lnum, true);
+ }
+ }
+
+ // Calculate how many screen lines the current top line of window
+ // occupies. If it is occupying more than the entire window, we
+ // need to scroll the additional clipped lines to scroll past the
+ // top line before we can move on to the other lines.
+ int top_plines = plines_win_nofill(curwin, curwin->w_topline, false);
+ int skip_lines = 0;
+ int width1 = curwin->w_width - curwin_col_off();
+ int width2 = width1 + curwin_col_off2();
+ // similar formula is used in curs_columns()
+ if (curwin->w_skipcol > width1) {
+ skip_lines += (curwin->w_skipcol - width1) / width2 + 1;
+ } else if (curwin->w_skipcol > 0) {
+ skip_lines = 1;
+ }
+
+ top_plines -= skip_lines;
+ if (top_plines > curwin->w_height) {
+ scrolled += (top_plines - curwin->w_height);
+ min_scrolled += (top_plines - curwin->w_height);
}
}
}