From 361895d2a15b4b0bbbb4c009261eab5b3d69ebf1 Mon Sep 17 00:00:00 2001 From: Yee Cheng Chin Date: Sat, 19 Nov 2022 12:25:16 +0000 Subject: 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 #11502) --- src/move.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'src/move.c') diff --git a/src/move.c b/src/move.c index 66e8c18c5..42054455b 100644 --- a/src/move.c +++ b/src/move.c @@ -2460,18 +2460,50 @@ scroll_cursor_bot(int min_scroll, int set_topbot) used = curwin->w_cline_height; #endif - // 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_NOFILL(lnum); + 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_NOFILL(lnum); + + // 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 = +#ifdef FEAT_DIFF + plines_win_nofill +#else + plines_win +#endif + (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); + } + } } /* -- cgit v1.2.1