To: vim_dev@googlegroups.com Subject: Patch 9.0.0734 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0734 Problem: Cursor position invalid when scrolling with 'smoothscroll' set. (Ernie Rael) Solution: Add w_valid_skipcol and clear flags when it changes. Adjust w_skipcol after moving the cursor. Files: src/structs.h, src/move.c, src/proto/move.pro, src/edit.c, src/normal.c, src/testdir/test_scroll_opt.vim, src/testdir/dumps/Test_smooth_one_long_1.dump, src/testdir/dumps/Test_smooth_one_long_2.dump, src/testdir/dumps/Test_smooth_long_8.dump, src/testdir/dumps/Test_smooth_long_9.dump *** ../vim-9.0.0733/src/structs.h 2022-10-04 14:34:42.116964799 +0100 --- src/structs.h 2022-10-12 15:20:42.922768340 +0100 *************** *** 3714,3719 **** --- 3714,3720 ---- pos_T w_valid_cursor; // last known position of w_cursor, used // to adjust w_valid colnr_T w_valid_leftcol; // last known w_leftcol + colnr_T w_valid_skipcol; // last known w_skipcol /* * w_cline_height is the number of physical lines taken by the buffer line *** ../vim-9.0.0733/src/move.c 2022-10-09 17:19:04.445451418 +0100 --- src/move.c 2022-10-12 19:51:13.493613754 +0100 *************** *** 552,557 **** --- 552,567 ---- |VALID_BOTLINE|VALID_BOTLINE_AP); wp->w_valid_cursor = wp->w_cursor; wp->w_valid_leftcol = wp->w_leftcol; + wp->w_valid_skipcol = wp->w_skipcol; + } + else if (wp->w_skipcol != wp->w_valid_skipcol) + { + wp->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL + |VALID_CHEIGHT|VALID_CROW + |VALID_BOTLINE|VALID_BOTLINE_AP); + wp->w_valid_cursor = wp->w_cursor; + wp->w_valid_leftcol = wp->w_leftcol; + wp->w_valid_skipcol = wp->w_skipcol; } else if (wp->w_cursor.col != wp->w_valid_cursor.col || wp->w_leftcol != wp->w_valid_leftcol *************** *** 878,884 **** redraw_for_cursorline(curwin); wp->w_valid |= VALID_CROW|VALID_CHEIGHT; - } /* --- 888,893 ---- *************** *** 1092,1097 **** --- 1101,1111 ---- { width = textwidth + curwin_col_off2(); + // skip columns that are not visible + if (curwin->w_cursor.lnum == curwin->w_topline + && curwin->w_wcol >= curwin->w_skipcol) + curwin->w_wcol -= curwin->w_skipcol; + // long line wrapping, adjust curwin->w_wrow if (curwin->w_wcol >= curwin->w_width) { *************** *** 1265,1274 **** while (endcol > curwin->w_virtcol) endcol -= width; if (endcol > curwin->w_skipcol) curwin->w_skipcol = endcol; } - curwin->w_wrow -= curwin->w_skipcol / width; if (curwin->w_wrow >= curwin->w_height) { // small window, make sure cursor is in it --- 1279,1290 ---- while (endcol > curwin->w_virtcol) endcol -= width; if (endcol > curwin->w_skipcol) + { + curwin->w_wrow -= (endcol - curwin->w_skipcol) / width; curwin->w_skipcol = endcol; + } } if (curwin->w_wrow >= curwin->w_height) { // small window, make sure cursor is in it *************** *** 1302,1309 **** curwin->w_flags &= ~(WFLAG_WCOL_OFF_ADDED + WFLAG_WROW_OFF_ADDED); #endif ! // now w_leftcol is valid, avoid check_cursor_moved() thinking otherwise curwin->w_valid_leftcol = curwin->w_leftcol; curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; } --- 1318,1327 ---- curwin->w_flags &= ~(WFLAG_WCOL_OFF_ADDED + WFLAG_WROW_OFF_ADDED); #endif ! // now w_leftcol and w_skipcol are valid, avoid check_cursor_moved() ! // thinking otherwise curwin->w_valid_leftcol = curwin->w_leftcol; + curwin->w_valid_skipcol = curwin->w_skipcol; curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; } *************** *** 1772,1778 **** --- 1790,1860 ---- col += width2; curwin->w_curswant = col; coladvance(curwin->w_curswant); + + // validate_virtcol() marked various things as valid, but after + // moving the cursor they need to be recomputed + curwin->w_valid &= + ~(VALID_WROW|VALID_WCOL|VALID_CHEIGHT|VALID_CROW|VALID_VIRTCOL); + } + } + } + + /* + * Called after changing the cursor column: make sure that curwin->w_skipcol is + * valid for 'smoothscroll'. + */ + void + adjust_skipcol(void) + { + if (!curwin->w_p_wrap + || !curwin->w_p_sms + || curwin->w_cursor.lnum != curwin->w_topline) + return; + + int width1 = curwin->w_width - curwin_col_off(); + int width2 = width1 + curwin_col_off2(); + long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; + int scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; + int scrolled = FALSE; + + validate_virtcol(); + while (curwin->w_skipcol > 0 + && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) + { + // scroll a screen line down + if (curwin->w_skipcol >= width1 + width2) + curwin->w_skipcol -= width2; + else + curwin->w_skipcol -= width1; + redraw_later(UPD_NOT_VALID); + scrolled = TRUE; + validate_virtcol(); + } + if (scrolled) + return; // don't scroll in the other direction now + + int col = curwin->w_virtcol - curwin->w_skipcol + scrolloff_cols; + int row = 0; + if (col >= width1) + { + col -= width1; + ++row; + } + if (col > width2) + { + row += col / width2; + col = col % width2; + } + if (row >= curwin->w_height) + { + if (curwin->w_skipcol == 0) + { + curwin->w_skipcol += width1; + --row; } + if (row >= curwin->w_height) + curwin->w_skipcol += (row - curwin->w_height) * width2; + redraw_later(UPD_NOT_VALID); } } *** ../vim-9.0.0733/src/proto/move.pro 2022-09-16 20:50:44.968907925 +0100 --- src/proto/move.pro 2022-10-12 16:03:04.083284789 +0100 *************** *** 35,40 **** --- 35,41 ---- void f_virtcol2col(typval_T *argvars, typval_T *rettv); void scrolldown(long line_count, int byfold); void scrollup(long line_count, int byfold); + void adjust_skipcol(void); void check_topfill(win_T *wp, int down); void scrolldown_clamp(void); void scrollup_clamp(void); *** ../vim-9.0.0733/src/edit.c 2022-10-05 13:28:53.957039865 +0100 --- src/edit.c 2022-10-12 15:56:51.989713494 +0100 *************** *** 2636,2641 **** --- 2636,2642 ---- } curwin->w_set_curswant = TRUE; } + adjust_skipcol(); } /* *************** *** 2683,2688 **** --- 2684,2690 ---- curwin->w_cursor.col += l; curwin->w_set_curswant = TRUE; + adjust_skipcol(); return OK; } *************** *** 2742,2747 **** --- 2744,2750 ---- // character, move to its first byte if (has_mbyte) mb_adjust_cursor(); + adjust_skipcol(); return OK; } *** ../vim-9.0.0733/src/normal.c 2022-10-04 16:23:39.018042176 +0100 --- src/normal.c 2022-10-12 16:31:32.598104987 +0100 *************** *** 2448,2453 **** --- 2448,2454 ---- if (atend) curwin->w_curswant = MAXCOL; // stick in the last column + adjust_skipcol(); return retval; } *** ../vim-9.0.0733/src/testdir/test_scroll_opt.vim 2022-10-09 17:19:04.445451418 +0100 --- src/testdir/test_scroll_opt.vim 2022-10-12 17:01:30.695134892 +0100 *************** *** 248,252 **** --- 248,273 ---- call StopVimInTerminal(buf) endfunc + func Test_smoothscroll_one_long_line() + CheckScreendump + + let lines =<< trim END + vim9script + setline(1, 'with lots of text '->repeat(7)) + set smoothscroll scrolloff=0 + END + call writefile(lines, 'XSmoothOneLong', 'D') + let buf = RunVimInTerminal('-S XSmoothOneLong', #{rows: 6, cols: 40}) + call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {}) + + call term_sendkeys(buf, "\") + call VerifyScreenDump(buf, 'Test_smooth_one_long_2', {}) + + call term_sendkeys(buf, "0") + call VerifyScreenDump(buf, 'Test_smooth_one_long_1', {}) + + call StopVimInTerminal(buf) + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-9.0.0733/src/testdir/dumps/Test_smooth_one_long_1.dump 2022-10-12 19:49:37.429515619 +0100 --- src/testdir/dumps/Test_smooth_one_long_1.dump 2022-10-12 17:00:11.695262022 +0100 *************** *** 0 **** --- 1,6 ---- + >w+0&#ffffff0|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| @34 + |~+0#4040ff13&| @38 + | +0#0000000&@21|1|,|1| @10|A|l@1| *** ../vim-9.0.0733/src/testdir/dumps/Test_smooth_one_long_2.dump 2022-10-12 19:49:37.433515622 +0100 --- src/testdir/dumps/Test_smooth_one_long_2.dump 2022-10-12 17:00:12.847260168 +0100 *************** *** 0 **** --- 1,6 ---- + |<+0#4040ff13#ffffff0@2|t+0#0000000&|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| @34 + |~+0#4040ff13&| @38 + |~| @38 + | +0#0000000&@21|1|,|8|1| @9|A|l@1| *** ../vim-9.0.0733/src/testdir/dumps/Test_smooth_long_8.dump 2022-10-09 17:19:04.445451418 +0100 --- src/testdir/dumps/Test_smooth_long_8.dump 2022-10-12 19:38:32.260587351 +0100 *************** *** 3,6 **** |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 ! | @21|3|,|1|3|0| @8|B|o|t| --- 3,6 ---- |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| *** ../vim-9.0.0733/src/testdir/dumps/Test_smooth_long_9.dump 2022-10-09 17:19:04.445451418 +0100 --- src/testdir/dumps/Test_smooth_long_9.dump 2022-10-12 19:38:33.404589549 +0100 *************** *** 1,6 **** ! |<+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 ! |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| --- 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 |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| *** ../vim-9.0.0733/src/version.c 2022-10-12 13:30:21.778239564 +0100 --- src/version.c 2022-10-12 17:02:24.851047789 +0100 *************** *** 701,702 **** --- 701,704 ---- { /* Add new patch number below this line */ + /**/ + 734, /**/ -- Trees moving back and forth is what makes the wind blow. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///