# HG changeset patch # User Christian Brabandt # Date 1712084406 -7200 # Node ID b20609f4ab379688e1cd26174754343318995f01 # Parent d14cb0d9988c4efb571a5f597a5f6be355e78839 patch 9.1.0258: half-page scrolling broke backward compatibility Commit: https://github.com/vim/vim/commit/cb204e688e5c9d56a78b621ef27c35d91860cb09 Author: Luuk van Baal Date: Tue Apr 2 20:49:45 2024 +0200 patch 9.1.0258: half-page scrolling broke backward compatibility Problem: Support for 'smoothscroll' in (half-)page scrolling broke backward compatibility and can be made to work better. (after v9.1.215) Solution: Restore the previous cursor and end-of-buffer behavior for half-page scrolling and improve 'smoothscroll' support. (Luuk van Baal) fixes: #14338 closes: #14377 Signed-off-by: Luuk van Baal Signed-off-by: Christian Brabandt diff --git a/src/change.c b/src/change.c --- a/src/change.c +++ b/src/change.c @@ -574,8 +574,7 @@ changed_common( && wp->w_topline < lnume && win_linetabsize(wp, wp->w_topline, ml_get(wp->w_topline), (colnr_T)MAXCOL) - <= wp->w_skipcol + sms_marker_overlap(wp, - win_col_off(wp) - win_col_off2(wp))))) + <= wp->w_skipcol + sms_marker_overlap(wp, -1)))) wp->w_skipcol = 0; // Check if a change in the buffer has invalidated the cached diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -197,13 +197,15 @@ redraw_for_cursorcolumn(win_T *wp) * Calculates how much the 'listchars' "precedes" or 'smoothscroll' "<<<" * marker overlaps with buffer text for window "wp". * Parameter "extra2" should be the padding on the 2nd line, not the first - * line. + * line. When "extra2" is -1 calculate the padding. * Returns the number of columns of overlap with buffer text, excluding the * extra padding on the ledge. */ int sms_marker_overlap(win_T *wp, int extra2) { + if (extra2 == -1) + extra2 = win_col_off(wp) - win_col_off2(wp); #if defined(FEAT_LINEBREAK) // There is no marker overlap when in showbreak mode, thus no need to // account for it. See wlv_screen_line(). @@ -340,12 +342,12 @@ update_topline(void) && curwin->w_cursor.lnum == curwin->w_topline) { colnr_T vcol; + int overlap; // Check that the cursor position is visible. Add columns for // the marker displayed in the top-left if needed. getvvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL); - int overlap = sms_marker_overlap(curwin, curwin_col_off() - - curwin_col_off2()); + overlap = sms_marker_overlap(curwin, -1); if (curwin->w_skipcol + overlap > vcol) check_topline = TRUE; } @@ -1854,6 +1856,9 @@ scrollup( curwin->w_topfill = diff_check_fill(curwin, lnum); # endif curwin->w_skipcol = 0; + // Adjusting the cursor later should not adjust skipcol: + // bring it to the first screenline on this new topline. + curwin->w_curswant %= width1; if (todo > 1 && do_sms) size = linetabsize(curwin, curwin->w_topline); } @@ -1971,8 +1976,7 @@ adjust_skipcol(void) } validate_virtcol(); - int overlap = sms_marker_overlap(curwin, - curwin_col_off() - curwin_col_off2()); + int overlap = sms_marker_overlap(curwin, -1); while (curwin->w_skipcol > 0 && curwin->w_virtcol < curwin->w_skipcol + overlap + scrolloff_cols) { @@ -2486,6 +2490,7 @@ scroll_cursor_bot(int min_scroll, int se { int plines_offset = used + loff.height - curwin->w_height; + int overlap = sms_marker_overlap(curwin, -1); used = curwin->w_height; #ifdef FEAT_DIFF curwin->w_topfill = loff.fill; @@ -2493,6 +2498,7 @@ scroll_cursor_bot(int min_scroll, int se curwin->w_topline = loff.lnum; curwin->w_skipcol = skipcol_from_plines( curwin, plines_offset); + curwin->w_cursor.col = curwin->w_skipcol + overlap; set_skipcol = TRUE; } } @@ -2503,6 +2509,8 @@ scroll_cursor_bot(int min_scroll, int se curwin->w_topfill = loff.fill; #endif } + if (curwin->w_topline > curbuf->b_ml.ml_line_count) + curwin->w_topline = curbuf->b_ml.ml_line_count; set_empty_rows(curwin, used); curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP; if (curwin->w_topline != old_topline @@ -3087,19 +3095,66 @@ static int get_scroll_overlap(int dir) } /* - * Move screen "count" pages up ("dir" is BACKWARD) or down ("dir" is FORWARD) - * and update the screen. + * Scroll "count" lines with 'smoothscroll' in direction "dir". Adjust "count" + * when scrolling more than "count" and return TRUE when scrolling happened. + */ +static int scroll_with_sms(int dir, long *count) +{ + int prev_sms = curwin->w_p_sms; + colnr_T prev_skipcol = curwin->w_skipcol; + linenr_T prev_topline = curwin->w_topline; +#ifdef FEAT_DIFF + int prev_topfill = curwin->w_topfill; +#endif + + curwin->w_p_sms = TRUE; + scroll_redraw(dir == FORWARD, *count); + + // Not actually smoothscrolling but ended up with partially visible line. + // Continue scrolling and update "count" so that cursor can be moved + // accordingly for half-page scrolling. + if (!prev_sms && curwin->w_skipcol > 0) + { + int fixdir = dir; + // Reverse the scroll direction when topline already changed. One line + // extra for scrolling backward so that consuming skipcol is symmetric. + if (labs(curwin->w_topline - prev_topline) > (dir == BACKWARD)) + fixdir = dir * -1; + validate_cursor(); + while (curwin->w_skipcol > 0 + && curwin->w_topline < curbuf->b_ml.ml_line_count) + { + scroll_redraw(fixdir == FORWARD, 1); + *count += (fixdir == dir ? 1 : -1); + } + } + curwin->w_p_sms = prev_sms; + + return curwin->w_topline == prev_topline +#ifdef FEAT_DIFF + && curwin->w_topfill == prev_topfill +#endif + && curwin->w_skipcol == prev_skipcol; +} + +/* + * Move screen "count" (half) pages up ("dir" is BACKWARD) or down ("dir" is + * FORWARD) and update the screen. Handle moving the cursor and not scrolling + * to reveal end of buffer lines for half-page scrolling with CTRL-D and CTRL-U. * * Return FAIL for failure, OK otherwise. */ int pagescroll(int dir, long count, int half) { -#ifdef FEAT_DIFF - int prev_topfill = curwin->w_topfill; -#endif - linenr_T prev_topline = curwin->w_topline; - colnr_T prev_skipcol = curwin->w_skipcol; + int nochange = TRUE; + int buflen = curbuf->b_ml.ml_line_count; + colnr_T prev_col = curwin->w_cursor.col; + colnr_T prev_curswant = curwin->w_curswant; + linenr_T prev_lnum = curwin->w_cursor.lnum; + oparg_T oa = { 0 }; + cmdarg_T ca = { 0 }; + ca.oap = &oa; if (half) { @@ -3107,54 +3162,61 @@ pagescroll(int dir, long count, int half if (count) curwin->w_p_scr = MIN(curwin->w_height, count); count = MIN(curwin->w_height, curwin->w_p_scr); - } - else - // Scroll 'window' or current window height lines. - count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1) ? - p_window - 2 : get_scroll_overlap(dir)); - if (curwin->w_p_sms) - scroll_redraw(dir == FORWARD, count); - else - { - // Scroll at least one full line without 'smoothscroll'. -#ifdef FEAT_DIFF - count -= plines_nofill(curwin->w_topline); -#else - count -= plines(curwin->w_topline); -#endif - scroll_redraw(dir == FORWARD, 1); + // Don't scroll if we already know that it will reveal end of buffer lines. + if (dir == BACKWARD + || (curwin->w_botline - 1 < buflen) + || (curwin->w_p_sms && curwin->w_botline - 1 == buflen + && curwin->w_skipcol < linetabsize(curwin, buflen))) + { + nochange = scroll_with_sms(dir, &count); + validate_botline(); + // Hide any potentially revealed end of buffer lines. + if (!nochange && curwin->w_botline - 1 == buflen) + { + curwin->w_cursor.lnum = buflen; + scroll_cursor_bot(0, TRUE); + } + } - // Temporarily set 'smoothscroll' so that scrolling count lines - // does not skip over parts of the buffer with wrapped lines. - curwin->w_p_sms = TRUE; - if (count > 0) - scroll_redraw(dir == FORWARD, count); - curwin->w_p_sms = FALSE; - } + // Move the cursor "count" screen lines. + curwin->w_curswant = MAXCOL; + curwin->w_cursor.col = prev_col; + curwin->w_cursor.lnum = prev_lnum; + if (curwin->w_p_wrap) + nv_screengo(&oa, dir, count); + else if (dir == FORWARD) + cursor_down_inner(curwin, count); + else + cursor_up_inner(curwin, count); + curwin->w_curswant = prev_curswant; + + if (get_scrolloff_value()) + cursor_correct(); #ifdef FEAT_FOLDING // Move cursor to first line of closed fold. foldAdjustCursor(); #endif - int nochange = curwin->w_topline == prev_topline -#ifdef FEAT_DIFF - && curwin->w_topfill == prev_topfill -#endif - && curwin->w_skipcol == prev_skipcol; + nochange = nochange + && prev_col == curwin->w_cursor.col + && prev_lnum == curwin->w_cursor.lnum; + } + else + { + // Scroll [count] times 'window' or current window height lines. + count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1) ? + MAX(1, p_window - 2) : get_scroll_overlap(dir)); + nochange = scroll_with_sms(dir, &count); + } - // Error if the viewport did not change and the cursor is already - // at the boundary. + // Error if both the viewport and cursor did not change. if (nochange) - { - int prev_cursor = curwin->w_cursor.lnum; - curwin->w_cursor.lnum += (count + 1) * (dir == FORWARD ? 1 : -1); - check_cursor(); - if (curwin->w_cursor.lnum == prev_cursor) - beep_flush(); - } - else if (!curwin->w_p_sms || curwin->w_skipcol == prev_skipcol) + beep_flush(); + else if (!curwin->w_p_sms) beginline(BL_SOL | BL_FIX); + else if (p_sol) + nv_g_home_m_cmd(&ca); return nochange; } diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -2303,7 +2303,7 @@ find_decl( * * Return OK if able to move cursor, FAIL otherwise. */ - static int + int nv_screengo(oparg_T *oap, int dir, long dist) { @@ -5745,7 +5745,7 @@ nv_gv_cmd(cmdarg_T *cap) * "g0", "g^" : Like "0" and "^" but for screen lines. * "gm": middle of "g0" and "g$". */ - static void + void nv_g_home_m_cmd(cmdarg_T *cap) { int i; @@ -5771,6 +5771,15 @@ nv_g_home_m_cmd(cmdarg_T *cap) i = 0; if (virtcol >= (colnr_T)width1 && width2 > 0) i = (virtcol - width1) / width2 * width2 + width1; + + // When ending up below 'smoothscroll' marker, move just beyond it so + // that skipcol is not adjusted later. + if (curwin->w_skipcol > 0 && curwin->w_cursor.lnum == curwin->w_topline) + { + int overlap = sms_marker_overlap(curwin, -1); + if (overlap > 0 && i == curwin->w_skipcol) + i += overlap; + } } else i = curwin->w_leftcol; @@ -7263,8 +7272,9 @@ nv_at(cmdarg_T *cap) static void nv_halfpage(cmdarg_T *cap) { + int dir = cap->cmdchar == Ctrl_D ? FORWARD : BACKWARD; if (!checkclearop(cap->oap)) - pagescroll(cap->cmdchar == Ctrl_D, cap->count0, TRUE); + pagescroll(dir, cap->count0, TRUE); } /* diff --git a/src/proto/normal.pro b/src/proto/normal.pro --- a/src/proto/normal.pro +++ b/src/proto/normal.pro @@ -22,6 +22,8 @@ void pop_showcmd(void); void do_check_scrollbind(int check); void check_scrollbind(linenr_T topline_diff, long leftcol_diff); int find_decl(char_u *ptr, int len, int locally, int thisblock, int flags_arg); +void nv_g_home_m_cmd(cmdarg_T *cap); +int nv_screengo(oparg_T *oap, int dir, long dist); void nv_scroll_line(cmdarg_T *cap); void scroll_redraw(int up, long count); void handle_tabmenu(void); diff --git a/src/testdir/dumps/Test_cursorline_redraw_2.dump b/src/testdir/dumps/Test_cursorline_redraw_2.dump --- a/src/testdir/dumps/Test_cursorline_redraw_2.dump +++ b/src/testdir/dumps/Test_cursorline_redraw_2.dump @@ -1,20 +1,20 @@ -|T+0&#ffffff0|h|e| |{|o|p|t|i|o|n|}| |a|r|g|u|m|e|n|t|s| |t|o| |"|:|s|e|t|"| |m|a|y| |b|e| +| +0&#ffffff0@39 +|T|h|e| |{|o|p|t|i|o|n|}| |a|r|g|u|m|e|n|t|s| |t|o| |"|:|s|e|t|"| |m|a|y| |b|e| |r|e|p|e|a|t|e|d|.| @1|F|o|r| |e|x|a|m|p|l|e|:| |>| @14 -@8|:|s|e|t| |a|i| |n|o|s|i| |s|w|=|3| |t|s|=|3| @9 -|I|f| |y|o|u| |m|a|k|e| |a|n| |e|r@1|o|r| |i|n| |o|n|e| |o|f| |t|h|e| |a|r|g|u|m +| +8&&@7>:|s|e|t| |a|i| |n|o|s|i| |s|w|=|3| |t|s|=|3| @9 +|I+0&&|f| |y|o|u| |m|a|k|e| |a|n| |e|r@1|o|r| |i|n| |o|n|e| |o|f| |t|h|e| |a|r|g|u|m |e|n|t|s|,| |a|n| |e|r@1|o|r| |m|e|s@1|a|g|e| |w|i|l@1| |b|e| |g|i|v|e|n| @3 |a|n|d| |t|h|e| |f|o|l@1|o|w|i|n|g| |a|r|g|u|m|e|n|t|s| |w|i|l@1| |b|e| |i|g|n|o |r|e|d|.| @35 @40 @40 @16|*|:|s|e|t|-|v|e|r|b|o|s|e|*| @9 ->W+8&&|h|e|n| |'|v|e|r|b|o|s|e|'| |i|s| |n|o|n|-|z|e|r|o|,| |d|i|s|p|l|a|y|i|n|g| |a +|W|h|e|n| |'|v|e|r|b|o|s|e|'| |i|s| |n|o|n|-|z|e|r|o|,| |d|i|s|p|l|a|y|i|n|g| |a |n| |o|p|t|i|o|n| |v|a|l|u|e| |w|i|l@1| |a|l|s|o| |t|e|l@1| |w|h|e|r|e| |i|t| @1 -|w+0&&|a|s| |l|a|s|t| |s|e|t|.| @1|E|x|a|m|p|l|e|:| |>| @14 +|w|a|s| |l|a|s|t| |s|e|t|.| @1|E|x|a|m|p|l|e|:| |>| @14 @8|:|v|e|r|b|o|s|e| |s|e|t| |s|h|i|f|t|w|i|d|t|h| |c|i|n|d|e|n|t|? |<| @1|s|h|i|f|t|w|i|d|t|h|=|4| |~| @22 @10|L|a|s|t| |s|e|t| |f|r|o|m| |m|o|d|e|l|i|n|e| |l|i|n|e| |1| |~| @38 @2|c|i|n|d|e|n|t| |~| @28 -|@+0#4040ff13&@2| @36 -| +0#0000000&@21|1|2|,|1| @9|5|0|%| +@22|7|,|2|-|9| @8|4@1|%| diff --git a/src/testdir/dumps/Test_display_visual_block_scroll.dump b/src/testdir/dumps/Test_display_visual_block_scroll.dump --- a/src/testdir/dumps/Test_display_visual_block_scroll.dump +++ b/src/testdir/dumps/Test_display_visual_block_scroll.dump @@ -1,7 +1,7 @@ |{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 ->}+0(ffff15| +0#0000001#a8a8a8255| +0#0000000#ffffff0@72 -|{| @73 -|f| @73 -|g| @73 +|}+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 +|{+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 +|f+0#0000001#a8a8a8255| | +0#0000000#ffffff0@72 +>g| +0#0000001#a8a8a8255| +0#0000000#ffffff0@72 |}| @73 -|-+2&&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@29|4| @8|8|,|1| @10|B|o|t| +|-+2&&@1| |V|I|S|U|A|L| |L|I|N|E| |-@1| +0&&@29|7| @8|1@1|,|1| @9|B|o|t| diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim --- a/src/testdir/test_diffmode.vim +++ b/src/testdir/test_diffmode.vim @@ -1679,8 +1679,7 @@ func Test_diff_scroll_many_filler() endfor set smoothscroll& - bwipe! - bwipe! + %bwipe! endfunc " This was trying to update diffs for a buffer being closed diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1302,7 +1302,7 @@ func Test_edit_PAGEUP_PAGEDOWN() call feedkeys("A\\", 'tnix') call assert_equal([0, 10, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') - call assert_equal([0, 2, 11, 0], getpos('.')) + call assert_equal([0, 10, 11, 0], getpos('.')) " is the same as " is the same as call cursor(1, 1) @@ -1325,7 +1325,7 @@ func Test_edit_PAGEUP_PAGEDOWN() call feedkeys("A\\", 'tnix') call assert_equal([0, 10, 1, 0], getpos('.')) call feedkeys("A\\", 'tnix') - call assert_equal([0, 2, 11, 0], getpos('.')) + call assert_equal([0, 10, 11, 0], getpos('.')) set nostartofline call cursor(30, 11) norm! zt @@ -1338,7 +1338,7 @@ func Test_edit_PAGEUP_PAGEDOWN() call feedkeys("A\\", 'tnix') call assert_equal([0, 10, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') - call assert_equal([0, 2, 11, 0], getpos('.')) + call assert_equal([0, 10, 11, 0], getpos('.')) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal([0, 9, 11, 0], getpos('.')) @@ -1363,7 +1363,7 @@ func Test_edit_PAGEUP_PAGEDOWN() call feedkeys("A\\", 'tnix') call assert_equal([0, 10, 11, 0], getpos('.')) call feedkeys("A\\", 'tnix') - call assert_equal([0, 2, 11, 0], getpos('.')) + call assert_equal([0, 10, 11, 0], getpos('.')) call cursor(1, 1) call feedkeys("A\\", 'tnix') call assert_equal([0, 9, 11, 0], getpos('.')) diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -1280,13 +1280,9 @@ func Test_vert_scroll_cmds() exe "normal \" call assert_equal(46, line('.')) exe "normal \" - call assert_equal(36, line('w0')) - call assert_equal(46, line('.')) + call assert_equal(36, line('.')) exe "normal \" - call assert_equal(1, line('w0')) - call assert_equal(40, line('.')) - exe "normal \" - call assert_equal(30, line('.')) + call assert_equal(1, line('.')) exe "normal \" call assert_equal(1, line('.')) set scroll& @@ -1307,8 +1303,9 @@ func Test_vert_scroll_cmds() call assert_equal(50, line('.')) call assert_equal(100, line('w$')) normal z. + let lnum = winline() exe "normal \" - call assert_equal(1, winline()) + call assert_equal(lnum, winline()) call assert_equal(50, line('.')) normal zt exe "normal \" @@ -3069,8 +3066,7 @@ func Test_normal42_halfpage() call assert_equal(2, &scroll) set scroll=5 exe "norm! \" - call assert_equal('3', getline('w0')) - call assert_equal('8', getline('.')) + call assert_equal('3', getline('.')) 1 set scrolloff=5 exe "norm! \" @@ -3818,7 +3814,7 @@ func Test_normal_vert_scroll_longline() call assert_equal(1, winline()) exe "normal \" call assert_equal(10, line('.')) - call assert_equal(10, winline()) + call assert_equal(4, winline()) exe "normal \\" call assert_equal(5, line('.')) call assert_equal(5, winline()) 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 @@ -552,11 +552,11 @@ func Test_smoothscroll_cursor_position() " Test "g0/g" exe "normal gg\" norm $gkg0 - call s:check_col_calc(1, 2, 21) + call s:check_col_calc(4, 1, 24) " Test moving the cursor behind the <<< display with 'virtualedit' set virtualedit=all - exe "normal \3lgkh" + exe "normal \gkh" call s:check_col_calc(3, 2, 23) set virtualedit& @@ -1017,26 +1017,72 @@ func Test_smoothscroll_page() exe "norm! \" call assert_equal(0, winsaveview().skipcol) - exe "norm! \" + " Half-page scrolling does not go beyond end of buffer and moves the cursor. + exe "norm! 0\" call assert_equal(200, winsaveview().skipcol) + call assert_equal(204, col('.')) exe "norm! \" call assert_equal(400, winsaveview().skipcol) - exe "norm! \" - call assert_equal(600, winsaveview().skipcol) + call assert_equal(404, col('.')) exe "norm! \" - call assert_equal(800, winsaveview().skipcol) + call assert_equal(520, winsaveview().skipcol) + call assert_equal(601, col('.')) exe "norm! \" - call assert_equal(880, winsaveview().skipcol) + call assert_equal(520, winsaveview().skipcol) + call assert_equal(801, col('.')) exe "norm! \" - call assert_equal(680, winsaveview().skipcol) - exe "norm! \" - call assert_equal(480, winsaveview().skipcol) + call assert_equal(520, winsaveview().skipcol) + call assert_equal(601, col('.')) exe "norm! \" - call assert_equal(280, winsaveview().skipcol) + call assert_equal(400, winsaveview().skipcol) + call assert_equal(404, col('.')) exe "norm! \" - call assert_equal(80, winsaveview().skipcol) + call assert_equal(200, winsaveview().skipcol) + call assert_equal(204, col('.')) exe "norm! \" call assert_equal(0, winsaveview().skipcol) + call assert_equal(1, col('.')) + + bwipe! +endfunc + +func Test_smoothscroll_next_topline() + call NewWindow(10, 40) + setlocal smoothscroll + call setline(1, ['abcde '->repeat(150)]->repeat(2)) + + " Scrolling a screenline that causes the cursor to move to the next buffer + " line should not skip part of that line to bring the cursor into view. + exe "norm! 22\" + call assert_equal(880, winsaveview().skipcol) + exe "norm! \" + redraw + call assert_equal(0, winsaveview().skipcol) + + " Cursor in correct place when not in the first screenline of a buffer line. + exe "norm! gg4gj20\\" + redraw + call assert_equal(2, line('w0')) + + bwipe! +endfunc + +func Test_smoothscroll_long_line_zb() + call NewWindow(10, 40) + call setline(1, 'abcde '->repeat(150)) + + " Also works without 'smoothscroll' when last line of buffer doesn't fit. + " Used to set topline to buffer line count plus one, causing an empty screen. + norm zb + redraw + call assert_equal(1, winsaveview().topline) + + " Moving cursor to bottom works on line that doesn't fit with 'smoothscroll'. + " Skipcol was adjusted later for cursor being on not visible part of line. + setlocal smoothscroll + norm zb + redraw + call assert_equal(520, winsaveview().skipcol) bwipe! endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 258, +/**/ 257, /**/ 256,