mirror of
https://github.com/vim/vim.git
synced 2025-09-28 04:24:06 -04:00
patch 9.1.0260: Problems with "zb" and scrolling to new topline with 'smoothscroll'
Problem: "zb" does not reveal filler lines at the start of a buffer. Scrolled cursor position with 'smoothscroll' is unpredictable, and may reset skipcol later if it is not visible (after v9.1.258) Solution: Replace confusing for loop that reaches final control value too early with while loop. Set "w_curswant" accordingly so cursor will be placed in visible part of topline. (Luuk van Baal) closes: #14394 Signed-off-by: Luuk van Baal <luukvbaal@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
08d2401fbc
commit
bd28cae1f1
35
src/move.c
35
src/move.c
@@ -1663,6 +1663,9 @@ scrolldown(
|
|||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
curwin->w_topfill = 0;
|
curwin->w_topfill = 0;
|
||||||
#endif
|
#endif
|
||||||
|
// Adjusting the cursor later should not adjust skipcol.
|
||||||
|
if (do_sms)
|
||||||
|
curwin->w_curswant = MAXCOL;
|
||||||
#ifdef FEAT_FOLDING
|
#ifdef FEAT_FOLDING
|
||||||
// A sequence of folded lines only counts for one logical line
|
// A sequence of folded lines only counts for one logical line
|
||||||
if (hasFolding(curwin->w_topline, &first, NULL))
|
if (hasFolding(curwin->w_topline, &first, NULL))
|
||||||
@@ -1856,9 +1859,9 @@ scrollup(
|
|||||||
curwin->w_topfill = diff_check_fill(curwin, lnum);
|
curwin->w_topfill = diff_check_fill(curwin, lnum);
|
||||||
# endif
|
# endif
|
||||||
curwin->w_skipcol = 0;
|
curwin->w_skipcol = 0;
|
||||||
// Adjusting the cursor later should not adjust skipcol:
|
// Adjusting the cursor later should not adjust skipcol.
|
||||||
// bring it to the first screenline on this new topline.
|
if (do_sms)
|
||||||
curwin->w_curswant %= width1;
|
curwin->w_curswant = 0;
|
||||||
if (todo > 1 && do_sms)
|
if (todo > 1 && do_sms)
|
||||||
size = linetabsize(curwin, curwin->w_topline);
|
size = linetabsize(curwin, curwin->w_topline);
|
||||||
}
|
}
|
||||||
@@ -2464,18 +2467,14 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
|
|||||||
cln = curwin->w_cursor.lnum;
|
cln = curwin->w_cursor.lnum;
|
||||||
if (set_topbot)
|
if (set_topbot)
|
||||||
{
|
{
|
||||||
int set_skipcol = FALSE;
|
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
curwin->w_botline = cln + 1;
|
curwin->w_botline = cln + 1;
|
||||||
|
loff.lnum = cln + 1;
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
loff.fill = 0;
|
loff.fill = 0;
|
||||||
#endif
|
#endif
|
||||||
for (curwin->w_topline = curwin->w_botline;
|
while (TRUE)
|
||||||
curwin->w_topline > 1;
|
|
||||||
curwin->w_topline = loff.lnum)
|
|
||||||
{
|
{
|
||||||
loff.lnum = curwin->w_topline;
|
|
||||||
topline_back_winheight(&loff, FALSE);
|
topline_back_winheight(&loff, FALSE);
|
||||||
if (loff.height == MAXCOL)
|
if (loff.height == MAXCOL)
|
||||||
break;
|
break;
|
||||||
@@ -2499,29 +2498,28 @@ scroll_cursor_bot(int min_scroll, int set_topbot)
|
|||||||
curwin->w_skipcol = skipcol_from_plines(
|
curwin->w_skipcol = skipcol_from_plines(
|
||||||
curwin, plines_offset);
|
curwin, plines_offset);
|
||||||
curwin->w_cursor.col = curwin->w_skipcol + overlap;
|
curwin->w_cursor.col = curwin->w_skipcol + overlap;
|
||||||
set_skipcol = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
used += loff.height;
|
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
curwin->w_topfill = loff.fill;
|
curwin->w_topfill = loff.fill;
|
||||||
#endif
|
#endif
|
||||||
|
curwin->w_topline = loff.lnum;
|
||||||
|
used += loff.height;
|
||||||
}
|
}
|
||||||
if (curwin->w_topline > curbuf->b_ml.ml_line_count)
|
|
||||||
curwin->w_topline = curbuf->b_ml.ml_line_count;
|
|
||||||
set_empty_rows(curwin, used);
|
set_empty_rows(curwin, used);
|
||||||
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
|
||||||
if (curwin->w_topline != old_topline
|
if (curwin->w_topline != old_topline
|
||||||
#ifdef FEAT_DIFF
|
#ifdef FEAT_DIFF
|
||||||
|| curwin->w_topfill != old_topfill
|
|| curwin->w_topfill != old_topfill
|
||||||
#endif
|
#endif
|
||||||
|| set_skipcol
|
|| curwin->w_skipcol != old_skipcol
|
||||||
|| curwin->w_skipcol != 0)
|
|| curwin->w_skipcol != 0)
|
||||||
{
|
{
|
||||||
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
|
curwin->w_valid &= ~(VALID_WROW|VALID_CROW);
|
||||||
if (set_skipcol)
|
if (curwin->w_skipcol != old_skipcol)
|
||||||
redraw_later(UPD_NOT_VALID);
|
redraw_later(UPD_NOT_VALID);
|
||||||
else
|
else
|
||||||
reset_skipcol();
|
reset_skipcol();
|
||||||
@@ -3051,7 +3049,8 @@ static int get_scroll_overlap(int dir)
|
|||||||
int min_height = curwin->w_height - 2;
|
int min_height = curwin->w_height - 2;
|
||||||
|
|
||||||
validate_botline();
|
validate_botline();
|
||||||
if (dir == FORWARD && curwin->w_botline > curbuf->b_ml.ml_line_count)
|
if ((dir == BACKWARD && curwin->w_topline == 1)
|
||||||
|
|| (dir == FORWARD && curwin->w_botline > curbuf->b_ml.ml_line_count))
|
||||||
return min_height + 2; // no overlap, still handle 'smoothscroll'
|
return min_height + 2; // no overlap, still handle 'smoothscroll'
|
||||||
|
|
||||||
loff.lnum = dir == FORWARD ? curwin->w_botline : curwin->w_topline - 1;
|
loff.lnum = dir == FORWARD ? curwin->w_botline : curwin->w_topline - 1;
|
||||||
@@ -3189,7 +3188,6 @@ pagescroll(int dir, long count, int half)
|
|||||||
cursor_down_inner(curwin, count);
|
cursor_down_inner(curwin, count);
|
||||||
else
|
else
|
||||||
cursor_up_inner(curwin, count);
|
cursor_up_inner(curwin, count);
|
||||||
curwin->w_curswant = prev_curswant;
|
|
||||||
|
|
||||||
if (get_scrolloff_value())
|
if (get_scrolloff_value())
|
||||||
cursor_correct();
|
cursor_correct();
|
||||||
@@ -3210,12 +3208,13 @@ pagescroll(int dir, long count, int half)
|
|||||||
nochange = scroll_with_sms(dir, &count);
|
nochange = scroll_with_sms(dir, &count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curwin->w_curswant = prev_curswant;
|
||||||
// Error if both the viewport and cursor did not change.
|
// Error if both the viewport and cursor did not change.
|
||||||
if (nochange)
|
if (nochange)
|
||||||
beep_flush();
|
beep_flush();
|
||||||
else if (!curwin->w_p_sms)
|
else if (!curwin->w_p_sms)
|
||||||
beginline(BL_SOL | BL_FIX);
|
beginline(BL_SOL | BL_FIX);
|
||||||
else if (p_sol)
|
else if (p_sol || curwin->w_skipcol)
|
||||||
nv_g_home_m_cmd(&ca);
|
nv_g_home_m_cmd(&ca);
|
||||||
|
|
||||||
return nochange;
|
return nochange;
|
||||||
|
@@ -4210,4 +4210,19 @@ func Test_single_line_scroll()
|
|||||||
call prop_type_delete(vt)
|
call prop_type_delete(vt)
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Test for zb in buffer with a single line and filler lines
|
||||||
|
func Test_single_line_filler_zb()
|
||||||
|
call setline(1, ['', 'foobar one two three'])
|
||||||
|
diffthis
|
||||||
|
new
|
||||||
|
call setline(1, ['foobar one two three'])
|
||||||
|
diffthis
|
||||||
|
|
||||||
|
" zb scrolls to reveal filler lines at the start of the buffer.
|
||||||
|
exe "normal \<C-E>zb"
|
||||||
|
call assert_equal(1, winsaveview().topfill)
|
||||||
|
|
||||||
|
bw!
|
||||||
|
endfunc
|
||||||
|
|
||||||
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
|
" vim: shiftwidth=2 sts=2 expandtab nofoldenable
|
||||||
|
@@ -1018,6 +1018,8 @@ func Test_smoothscroll_page()
|
|||||||
call assert_equal(0, winsaveview().skipcol)
|
call assert_equal(0, winsaveview().skipcol)
|
||||||
|
|
||||||
" Half-page scrolling does not go beyond end of buffer and moves the cursor.
|
" Half-page scrolling does not go beyond end of buffer and moves the cursor.
|
||||||
|
" Even with 'nostartofline', the correct amount of lines is scrolled.
|
||||||
|
setl nostartofline
|
||||||
exe "norm! 0\<C-D>"
|
exe "norm! 0\<C-D>"
|
||||||
call assert_equal(200, winsaveview().skipcol)
|
call assert_equal(200, winsaveview().skipcol)
|
||||||
call assert_equal(204, col('.'))
|
call assert_equal(204, col('.'))
|
||||||
@@ -1041,7 +1043,7 @@ func Test_smoothscroll_page()
|
|||||||
call assert_equal(204, col('.'))
|
call assert_equal(204, col('.'))
|
||||||
exe "norm! \<C-U>"
|
exe "norm! \<C-U>"
|
||||||
call assert_equal(0, winsaveview().skipcol)
|
call assert_equal(0, winsaveview().skipcol)
|
||||||
call assert_equal(1, col('.'))
|
call assert_equal(40, col('.'))
|
||||||
|
|
||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
endfunc
|
||||||
@@ -1059,6 +1061,11 @@ func Test_smoothscroll_next_topline()
|
|||||||
redraw
|
redraw
|
||||||
call assert_equal(0, winsaveview().skipcol)
|
call assert_equal(0, winsaveview().skipcol)
|
||||||
|
|
||||||
|
" Also when scrolling back.
|
||||||
|
exe "norm! G\<C-Y>"
|
||||||
|
redraw
|
||||||
|
call assert_equal(880, winsaveview().skipcol)
|
||||||
|
|
||||||
" Cursor in correct place when not in the first screenline of a buffer line.
|
" Cursor in correct place when not in the first screenline of a buffer line.
|
||||||
exe "norm! gg4gj20\<C-D>\<C-D>"
|
exe "norm! gg4gj20\<C-D>\<C-D>"
|
||||||
redraw
|
redraw
|
||||||
|
@@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
260,
|
||||||
/**/
|
/**/
|
||||||
259,
|
259,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user