vim-patch:9.0.0893: 'smoothscroll' cursor calculations wrong when 'number' is set

Problem:    'smoothscroll' cursor calculations wrong when 'number' is set.
Solution:   Correct the code that computes the width. (closes vim/vim#11492)

01ee52bab6

Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
This commit is contained in:
Luuk van Baal 2023-04-27 17:51:47 +02:00
parent 5e4df766f6
commit a2f3855291
3 changed files with 73 additions and 6 deletions

View File

@ -815,13 +815,14 @@ void curs_columns(win_T *wp, int may_scroll)
if (wp->w_cursor.lnum == wp->w_topline if (wp->w_cursor.lnum == wp->w_topline
&& wp->w_skipcol > 0 && wp->w_skipcol > 0
&& wp->w_wcol >= wp->w_skipcol) { && wp->w_wcol >= wp->w_skipcol) {
// w_skipcol excludes win_col_off(). Include it here, since w_wcol // Deduct by multiples of width2. This allows the long line wrapping
// counts actual screen columns. // formula below to correctly calculate the w_wcol value when wrapping.
if (wp->w_skipcol <= width1) { if (wp->w_skipcol <= width1) {
wp->w_wcol -= wp->w_width; wp->w_wcol -= width2;
} else { } else {
wp->w_wcol -= wp->w_width * (((wp->w_skipcol - width1) / width2) + 1); wp->w_wcol -= width2 * (((wp->w_skipcol - width1) / width2) + 1);
} }
did_sub_skipcol = true; did_sub_skipcol = true;
} }

View File

@ -279,8 +279,8 @@ describe('smoothscroll', function()
]]) ]])
exec('call DoRel()') exec('call DoRel()')
screen:expect([[ screen:expect([[
2<<<ong text very long text very lon^g te| 2<<<ong text very long text very long te|
xt very long text very long text ver| ^xt very long text very long text ver|
y long text very long text very long| y long text very long text very long|
text very long text very long text | text very long text very long text |
1 three | 1 three |

View File

@ -325,5 +325,71 @@ func Test_smoothscroll_one_long_line()
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
endfunc endfunc
" Test that if the current cursor is on a smooth scrolled line, we correctly
" reposition it. Also check that we don't miscalculate the values by checking
" the consistency between wincol() and col('.') as they are calculated
" separately in code.
func Test_smoothscroll_cursor_position()
call NewWindow(10, 20)
setl smoothscroll wrap
call setline(1, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func s:check_col_calc(win_col, win_line, buf_col)
call assert_equal(a:win_col, wincol())
call assert_equal(a:win_line, winline())
call assert_equal(a:buf_col, col('.'))
endfunc
call s:check_col_calc(1, 1, 1)
exe "normal \<C-E>"
" Move down another line to avoid blocking the <<< display
call s:check_col_calc(1, 2, 41)
exe "normal \<C-Y>"
call s:check_col_calc(1, 3, 41)
normal ggg$
exe "normal \<C-E>"
" Move down only 1 line when we are out of the range of the <<< display
call s:check_col_calc(20, 1, 40)
exe "normal \<C-Y>"
call s:check_col_calc(20, 2, 40)
normal gg
" Test number, where we have indented lines
setl number
call s:check_col_calc(5, 1, 1)
exe "normal \<C-E>"
call s:check_col_calc(5, 2, 33)
exe "normal \<C-Y>"
call s:check_col_calc(5, 3, 33)
normal ggg$
exe "normal \<C-E>"
call s:check_col_calc(20, 1, 32)
exe "normal \<C-Y>"
call s:check_col_calc(20, 2, 32)
normal gg
" Test number + showbreak, so test that the additional indentation works
setl number showbreak=+++
call s:check_col_calc(5, 1, 1)
exe "normal \<C-E>"
call s:check_col_calc(8, 2, 30)
exe "normal \<C-Y>"
call s:check_col_calc(8, 3, 30)
normal gg
" Test number + cpo+=n mode, where wrapped lines aren't indented
setl number cpo+=n showbreak=
call s:check_col_calc(5, 1, 1)
exe "normal \<C-E>"
call s:check_col_calc(1, 2, 37)
exe "normal \<C-Y>"
call s:check_col_calc(1, 3, 37)
normal gg
bwipeout!
endfunc
" vim: shiftwidth=2 sts=2 expandtab " vim: shiftwidth=2 sts=2 expandtab