# HG changeset patch # User Bram Moolenaar # Date 1683558004 -7200 # Node ID 1ddef52ea7861d457bf8332c3591754d8848fe2b # Parent 1714bba63e87d868b27b4ed4aefedc0dde0425e5 patch 9.0.1525: 'smoothscroll' does not always work properly Commit: https://github.com/vim/vim/commit/3ce8c389155fc1257082cdb0cef7801b49f6aaf9 Author: Luuk van Baal Date: Mon May 8 15:51:14 2023 +0100 patch 9.0.1525: 'smoothscroll' does not always work properly Problem: 'smoothscroll' does not always work properly. Solution: Do not reset w_skipcol after it was intentionally set. (Luuk van Baal, closes #12360, closes #12199, closes #12323) diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -276,10 +276,6 @@ update_topline(void) long line_count; int halfheight; int n; - linenr_T old_topline; -#ifdef FEAT_DIFF - int old_topfill; -#endif #ifdef FEAT_FOLDING linenr_T lnum; #endif @@ -311,9 +307,10 @@ update_topline(void) if (mouse_dragging > 0) *so_ptr = mouse_dragging - 1; - old_topline = curwin->w_topline; + linenr_T old_topline = curwin->w_topline; + colnr_T old_skipcol = curwin->w_skipcol; #ifdef FEAT_DIFF - old_topfill = curwin->w_topfill; + int old_topfill = curwin->w_topfill; #endif /* @@ -516,7 +513,10 @@ update_topline(void) { dollar_vcol = -1; redraw_later(UPD_VALID); - reset_skipcol(); + + // Only reset w_skipcol if it was not just set to make cursor visible. + if (curwin->w_skipcol == old_skipcol) + reset_skipcol(); // May need to set w_skipcol when cursor in w_topline. if (curwin->w_cursor.lnum == curwin->w_topline) @@ -2769,7 +2769,6 @@ scroll_cursor_halfway(int atend, int pre int above = 0; linenr_T topline; colnr_T skipcol = 0; - int set_skipcol = FALSE; #ifdef FEAT_DIFF int topfill = 0; #endif @@ -2798,14 +2797,19 @@ scroll_cursor_halfway(int atend, int pre #endif topline = loff.lnum; - int half_height = 0; + int want_height; int smooth_scroll = FALSE; if (curwin->w_p_sms && curwin->w_p_wrap) { // 'smoothscroll' and 'wrap' are set smooth_scroll = TRUE; - half_height = (curwin->w_height - used) / 2; - used = 0; + if (atend) + { + want_height = (curwin->w_height - used) / 2; + used = 0; + } + else + want_height = curwin->w_height; } while (topline > 1) @@ -2817,22 +2821,21 @@ scroll_cursor_halfway(int atend, int pre topline_back_winheight(&loff, FALSE); if (loff.height == MAXCOL) break; - else - used += loff.height; - if (used > half_height) + used += loff.height; + if (!atend && boff.lnum < curbuf->b_ml.ml_line_count) { - if (used - loff.height < half_height) + botline_forw(&boff); + used += boff.height; + } + if (used > want_height) + { + if (used - loff.height < want_height) { - int plines_offset = used - half_height; - loff.height -= plines_offset; - used = half_height; - topline = loff.lnum; #ifdef FEAT_DIFF topfill = loff.fill; #endif - skipcol = skipcol_from_plines(curwin, plines_offset); - set_skipcol = TRUE; + skipcol = skipcol_from_plines(curwin, used - want_height); } break; } @@ -2906,11 +2909,11 @@ scroll_cursor_halfway(int atend, int pre #endif { if (curwin->w_topline != topline - || set_skipcol + || skipcol != 0 || curwin->w_skipcol != 0) { curwin->w_topline = topline; - if (set_skipcol) + if (skipcol != 0) { curwin->w_skipcol = skipcol; redraw_later(UPD_NOT_VALID); diff --git a/src/testdir/dumps/Test_smooth_cursormoved_line.dump b/src/testdir/dumps/Test_smooth_cursormoved_line.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_smooth_cursormoved_line.dump @@ -0,0 +1,6 @@ +|<+0#4040ff13#ffffff0@2|_+0#0000000&@71 +@75 +@73>x@1 +@1|_@72|x +@2| @72 +@57|3|,|7|4| @9|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_eob_1.dump b/src/testdir/dumps/Test_smooth_eob_1.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_smooth_eob_1.dump @@ -0,0 +1,10 @@ +| +0&#ffffff0@74 +@75 +@75 +@75 +@75 +@75 +@75 +@75 +> @74 +@57|1|0@1|,|0|-|1| @6|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_eob_2.dump b/src/testdir/dumps/Test_smooth_eob_2.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_smooth_eob_2.dump @@ -0,0 +1,10 @@ +|<+0#4040ff13#ffffff0@2|a+0#0000000&@21| @49 +@75 +@75 +@75 +@75 +@75 +@75 +@75 +> @74 +@57|1|0@1|,|0|-|1| @6|B|o|t| diff --git a/src/testdir/dumps/Test_smooth_long_10.dump b/src/testdir/dumps/Test_smooth_long_10.dump --- a/src/testdir/dumps/Test_smooth_long_10.dump +++ b/src/testdir/dumps/Test_smooth_long_10.dump @@ -1,6 +1,6 @@ -|<+0#4040ff13#ffffff0@2|o+0#0000000&|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 +|<+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| |e|n|d| @11 >f|o|u|r| @35 -|~+0#4040ff13&| @38 -|~| @38 -|:+0#0000000&|s|e|t| |s|c|r|o|l@1|o| @9|4|,|1| @10|B|o|t| +|:|s|e|t| |s|c|r|o|l@1|o| @9|4|,|1| @10|B|o|t| diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -638,4 +638,47 @@ func Test_smoothscroll_ins_lines() call StopVimInTerminal(buf) endfunc +" this placed the cursor in the command line +func Test_smoothscroll_cursormoved_line() + CheckScreendump + + let lines =<< trim END + set smoothscroll + call setline(1, [ + \'', + \'_'->repeat(&lines * &columns), + \(('_')->repeat(&columns - 2) .. 'xxx')->repeat(2) + \]) + autocmd CursorMoved * eval [line('w0'), line('w$')] + call search('xxx') + END + call writefile(lines, 'XSmoothCursorMovedLine', 'D') + let buf = RunVimInTerminal('-S XSmoothCursorMovedLine', #{rows: 6}) + + call VerifyScreenDump(buf, 'Test_smooth_cursormoved_line', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_smoothscroll_eob() + CheckScreendump + + let lines =<< trim END + set smoothscroll + call setline(1, ['']->repeat(100)) + norm G + END + call writefile(lines, 'XSmoothEob', 'D') + let buf = RunVimInTerminal('-S XSmoothEob', #{rows: 10}) + + " does not scroll halfway when scrolling to end of buffer + call VerifyScreenDump(buf, 'Test_smooth_eob_1', {}) + + " cursor is not placed below window + call term_sendkeys(buf, ":call setline(92, 'a'->repeat(100))\\G") + call VerifyScreenDump(buf, 'Test_smooth_eob_2', {}) + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab 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 */ /**/ + 1525, +/**/ 1524, /**/ 1523,