From: Bram Moolenaar Date: Mon, 3 Oct 2022 13:06:02 +0000 (+0100) Subject: patch 9.0.0646: with 'smoothscroll' CTRL-E is wrong when 'foldmethod' set X-Git-Tag: v9.0.0646 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6b2d4ff7148e0b416ba745d20d061e6f7bb53ee7;p=vim patch 9.0.0646: with 'smoothscroll' CTRL-E is wrong when 'foldmethod' set Problem: with 'smoothscroll' set CTRL-E does not work properly when 'foldmethod' is set to "indent". (Yee Cheng Chin) Solution: Merge the code for scroling with folds and 'smoothscroll'. (closes #11262) --- diff --git a/src/move.c b/src/move.c index 43e3273e2..0c2f23a7d 100644 --- a/src/move.c +++ b/src/move.c @@ -984,8 +984,8 @@ curwin_col_off(void) /* * Return the difference in column offset for the second screen line of a - * wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in - * 'cpoptions'. + * wrapped line. It's positive if 'number' or 'relativenumber' is on and 'n' + * is in 'cpoptions'. */ int win_col_off2(win_T *wp) @@ -1463,7 +1463,7 @@ scrolldown( if (curwin->w_p_wrap && curwin->w_p_sms) { width1 = curwin->w_width - curwin_col_off(); - width2 = width1 - curwin_col_off2(); + width2 = width1 + curwin_col_off2(); } #ifdef FEAT_FOLDING @@ -1601,24 +1601,31 @@ scrollup( long line_count, int byfold UNUSED) // TRUE: count a closed fold as one line { -#if defined(FEAT_FOLDING) || defined(FEAT_DIFF) - linenr_T lnum; + int do_smoothscroll = curwin->w_p_wrap && curwin->w_p_sms; - if ( + if (do_smoothscroll # ifdef FEAT_FOLDING - (byfold && hasAnyFolding(curwin)) -# ifdef FEAT_DIFF - || -# endif + || (byfold && hasAnyFolding(curwin)) # endif # ifdef FEAT_DIFF - curwin->w_p_diff + || curwin->w_p_diff # endif ) { - // count each sequence of folded lines as one logical line - lnum = curwin->w_topline; - while (line_count--) + int width1 = curwin->w_width - curwin_col_off(); + int width2 = width1 + curwin_col_off2(); + int size = 0; + linenr_T prev_topline = curwin->w_topline; + + if (do_smoothscroll) + size = win_linetabsize(curwin, curwin->w_topline, + ml_get(curwin->w_topline), (colnr_T)MAXCOL); + + // diff mode: first consume "topfill" + // 'smoothscroll': increase "w_skipcol" until it goes over the end of + // the line, then advance to the next line. + // folding: count each sequence of folded lines as one logical line. + for (int todo = line_count; todo > 0; --todo) { # ifdef FEAT_DIFF if (curwin->w_topfill > 0) @@ -1626,54 +1633,54 @@ scrollup( else # endif { + linenr_T lnum = curwin->w_topline; + # ifdef FEAT_FOLDING if (byfold) + // for a closed fold: go to the last line in the fold (void)hasFolding(lnum, NULL, &lnum); # endif - if (lnum >= curbuf->b_ml.ml_line_count) - break; - ++lnum; -# ifdef FEAT_DIFF - curwin->w_topfill = diff_check_fill(curwin, lnum); -# endif - } - } - // approximate w_botline - curwin->w_botline += lnum - curwin->w_topline; - curwin->w_topline = lnum; - } - else -#endif - if (curwin->w_p_wrap && curwin->w_p_sms) - { - int off1 = curwin_col_off(); - int off2 = off1 + curwin_col_off2(); - int add; - int size = win_linetabsize(curwin, curwin->w_topline, - ml_get(curwin->w_topline), (colnr_T)MAXCOL); - linenr_T prev_topline = curwin->w_topline; + if (lnum == curwin->w_topline + && curwin->w_p_wrap && curwin->w_p_sms) + { + // 'smoothscroll': increase "w_skipcol" until it goes over + // the end of the line, then advance to the next line. + int add = curwin->w_skipcol > 0 ? width2 : width1; + curwin->w_skipcol += add; + if (curwin->w_skipcol >= size) + { + if (lnum == curbuf->b_ml.ml_line_count) + { + // at the last screen line, can't scroll further + curwin->w_skipcol -= add; + break; + } + ++lnum; + } + } + else + { + if (lnum >= curbuf->b_ml.ml_line_count) + break; + ++lnum; + } - // 'smoothscroll': increase "w_skipcol" until it goes over the end of - // the line, then advance to the next line. - for (int todo = line_count; todo > 0; --todo) - { - add = curwin->w_width - (curwin->w_skipcol > 0 ? off2 : off1); - curwin->w_skipcol += add; - if (curwin->w_skipcol >= size) - { - if (curwin->w_topline == curbuf->b_ml.ml_line_count) + if (lnum > curwin->w_topline) { - curwin->w_skipcol -= add; - break; + // approximate w_botline + curwin->w_botline += lnum - curwin->w_topline; + curwin->w_topline = lnum; +# ifdef FEAT_DIFF + curwin->w_topfill = diff_check_fill(curwin, lnum); +# endif + curwin->w_skipcol = 0; + if (todo > 1 && do_smoothscroll) + size = win_linetabsize(curwin, curwin->w_topline, + ml_get(curwin->w_topline), (colnr_T)MAXCOL); } - ++curwin->w_topline; - ++curwin->w_botline; // approximate w_botline - curwin->w_skipcol = 0; - if (todo > 1) - size = win_linetabsize(curwin, curwin->w_topline, - ml_get(curwin->w_topline), (colnr_T)MAXCOL); } } + if (curwin->w_topline == prev_topline) // need to redraw even though w_topline didn't change redraw_later(UPD_NOT_VALID); diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim index 876ccf203..e23068f8a 100644 --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -88,6 +88,21 @@ func Test_smoothscroll_CtrlE_CtrlY() call term_sendkeys(buf, "\") call VerifyScreenDump(buf, 'Test_smoothscroll_8', {}) + if has('folding') + call term_sendkeys(buf, ":set foldmethod=indent\") + " move the cursor so we can reuse the same dumps + call term_sendkeys(buf, "5G") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smoothscroll_1', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smoothscroll_2', {}) + call term_sendkeys(buf, "7G") + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smoothscroll_7', {}) + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smoothscroll_8', {}) + endif + call StopVimInTerminal(buf) endfunc diff --git a/src/version.c b/src/version.c index 0cf367ea6..22d431cef 100644 --- a/src/version.c +++ b/src/version.c @@ -699,6 +699,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 646, /**/ 645, /**/