# HG changeset patch # User Bram Moolenaar # Date 1666294204 -7200 # Node ID 1819fe895aeaf5269de32aaf9c0f7e629d07c8b9 # Parent a806b9047812f2b51bdcbb7f53295917324a3062 patch 9.0.0807: with 'smoothscroll' typing "0" may not go to the first column Commit: https://github.com/vim/vim/commit/d5337efece7c68e9b4ce864532ea49b02453b674 Author: Bram Moolenaar Date: Thu Oct 20 20:15:47 2022 +0100 patch 9.0.0807: with 'smoothscroll' typing "0" may not go to the first column Problem: With 'smoothscroll' typing "0" may not go to the first column. Solution: Recompute w_cline_height when needed. Do not scroll up when it would move the cursor. diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -62,6 +62,28 @@ adjust_plines_for_skipcol(win_T *wp, int } /* + * Return how many lines "lnum" will take on the screen, taking into account + * whether it is the first line, whether w_skipcol is non-zero and limiting to + * the window height. + */ + static int +plines_correct_topline(win_T *wp, linenr_T lnum) +{ + int n; +#ifdef FEAT_DIFF + if (lnum == wp->w_topline) + n = plines_win_nofill(wp, lnum, FALSE) + wp->w_topfill; + else +#endif + n = plines_win(wp, lnum, FALSE); + if (lnum == wp->w_topline) + n = adjust_plines_for_skipcol(wp, n); + if (n > wp->w_height) + n = wp->w_height; + return n; +} + +/* * Compute wp->w_botline for the current wp->w_topline. Can be called after * wp->w_topline changed. */ @@ -105,14 +127,7 @@ comp_botline(win_T *wp) else #endif { -#ifdef FEAT_DIFF - if (lnum == wp->w_topline) - n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill; - else -#endif - n = plines_win(wp, lnum, TRUE); - if (lnum == wp->w_topline) - n = adjust_plines_for_skipcol(wp, n); + n = plines_correct_topline(wp, lnum); } if ( #ifdef FEAT_FOLDING @@ -833,16 +848,8 @@ curs_rows(win_T *wp) else #endif { - int n; -#ifdef FEAT_DIFF - if (lnum == wp->w_topline) - n = plines_win_nofill(wp, lnum, TRUE) + wp->w_topfill; - else -#endif - n = plines_win(wp, lnum, TRUE); - if (lnum++ == wp->w_topline) - n = adjust_plines_for_skipcol(wp, n); - wp->w_cline_row += n; + wp->w_cline_row += plines_correct_topline(wp, lnum); + ++lnum; } } } @@ -1660,6 +1667,22 @@ scrolldown( } /* + * Return TRUE if scrollup() will scroll by screen line rather than text line. + */ + static int +scrolling_screenlines(int byfold UNUSED) +{ + return (curwin->w_p_wrap && curwin->w_p_sms) +# ifdef FEAT_FOLDING + || (byfold && hasAnyFolding(curwin)) +# endif +# ifdef FEAT_DIFF + || curwin->w_p_diff +# endif + ; +} + +/* * Scroll the current window up by "line_count" logical lines. "CTRL-E" */ void @@ -1669,14 +1692,7 @@ scrollup( { int do_sms = curwin->w_p_wrap && curwin->w_p_sms; - if (do_sms -# ifdef FEAT_FOLDING - || (byfold && hasAnyFolding(curwin)) -# endif -# ifdef FEAT_DIFF - || curwin->w_p_diff -# endif - ) + if (scrolling_screenlines(byfold)) { int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); @@ -1829,7 +1845,7 @@ adjust_skipcol(void) int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; int scrolled = FALSE; - validate_virtcol(); + validate_cheight(); if (curwin->w_cline_height == curwin->w_height) { // the line just fits in the window, don't scroll @@ -1841,6 +1857,7 @@ adjust_skipcol(void) return; } + validate_virtcol(); while (curwin->w_skipcol > 0 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { @@ -2539,10 +2556,20 @@ scroll_cursor_bot(int min_scroll, int se scroll_cursor_halfway(FALSE); else { - // With 'smoothscroll' scroll at least the height of the cursor line. - if (curwin->w_p_wrap && curwin->w_p_sms && line_count < min_scrolled) + // With 'smoothscroll' scroll at least the height of the cursor line, + // unless it would move the cursor. + if (curwin->w_p_wrap && curwin->w_p_sms && line_count < min_scrolled + && (curwin->w_cursor.lnum < curwin->w_topline + || (curwin->w_virtcol - curwin->w_skipcol >= + curwin->w_width - curwin_col_off()))) line_count = min_scrolled; - scrollup(line_count, TRUE); + if (line_count > 0) + { + if (scrolling_screenlines(TRUE)) + scrollup(scrolled, TRUE); // TODO + else + scrollup(line_count, TRUE); + } } /* diff --git a/src/testdir/dumps/Test_smooth_long_9.dump b/src/testdir/dumps/Test_smooth_long_9.dump --- a/src/testdir/dumps/Test_smooth_long_9.dump +++ b/src/testdir/dumps/Test_smooth_long_9.dump @@ -1,6 +1,6 @@ -|<+0#4040ff13#ffffff0@2|t+0#0000000&|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t -|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o -|t|s| |o|f| |t|e|x>t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o -|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e +|<+0#4040ff13#ffffff0@2|o+0#0000000&|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o +|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o +|f| |t|e|x|t| |w|i>t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e |x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w -|:|s|e|t| |s|c|r|o|l@1|o| @9|3|,|1|3|0| @8|B|o|t| +|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| |l|o|t|s| |o|f| |t|e|x|t| |w|i|t|h| +@22|3|,|1|7|0| @8|B|o|t| diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 807, +/**/ 806, /**/ 805,