1
0
forked from aniani/vim

patch 9.0.0646: with 'smoothscroll' CTRL-E is wrong when 'foldmethod' set

Problem:    with 'smoothscroll' set CTRL-E does not work properly when
            'foldmethod' is set to "indent". (Yee Cheng Chin)
Solution:   Merge the code for scroling with folds and 'smoothscroll'.
            (closes #11262)
This commit is contained in:
Bram Moolenaar
2022-10-03 14:06:02 +01:00
parent 8df9748edb
commit 6b2d4ff714
3 changed files with 78 additions and 54 deletions

View File

@@ -984,8 +984,8 @@ curwin_col_off(void)
/*
* Return the difference in column offset for the second screen line of a
* wrapped line. It's 8 if 'number' or 'relativenumber' is on and 'n' is in
* 'cpoptions'.
* wrapped line. It's positive if 'number' or 'relativenumber' is on and 'n'
* is in 'cpoptions'.
*/
int
win_col_off2(win_T *wp)
@@ -1463,7 +1463,7 @@ scrolldown(
if (curwin->w_p_wrap && curwin->w_p_sms)
{
width1 = curwin->w_width - curwin_col_off();
width2 = width1 - curwin_col_off2();
width2 = width1 + curwin_col_off2();
}
#ifdef FEAT_FOLDING
@@ -1601,24 +1601,31 @@ scrollup(
long line_count,
int byfold UNUSED) // TRUE: count a closed fold as one line
{
#if defined(FEAT_FOLDING) || defined(FEAT_DIFF)
linenr_T lnum;
int do_smoothscroll = curwin->w_p_wrap && curwin->w_p_sms;
if (
if (do_smoothscroll
# ifdef FEAT_FOLDING
(byfold && hasAnyFolding(curwin))
# ifdef FEAT_DIFF
||
# endif
|| (byfold && hasAnyFolding(curwin))
# endif
# ifdef FEAT_DIFF
curwin->w_p_diff
|| curwin->w_p_diff
# endif
)
{
// count each sequence of folded lines as one logical line
lnum = curwin->w_topline;
while (line_count--)
int width1 = curwin->w_width - curwin_col_off();
int width2 = width1 + curwin_col_off2();
int size = 0;
linenr_T prev_topline = curwin->w_topline;
if (do_smoothscroll)
size = win_linetabsize(curwin, curwin->w_topline,
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
// diff mode: first consume "topfill"
// 'smoothscroll': increase "w_skipcol" until it goes over the end of
// the line, then advance to the next line.
// folding: count each sequence of folded lines as one logical line.
for (int todo = line_count; todo > 0; --todo)
{
# ifdef FEAT_DIFF
if (curwin->w_topfill > 0)
@@ -1626,54 +1633,54 @@ scrollup(
else
# endif
{
linenr_T lnum = curwin->w_topline;
# ifdef FEAT_FOLDING
if (byfold)
// for a closed fold: go to the last line in the fold
(void)hasFolding(lnum, NULL, &lnum);
# endif
if (lnum >= curbuf->b_ml.ml_line_count)
break;
++lnum;
# ifdef FEAT_DIFF
curwin->w_topfill = diff_check_fill(curwin, lnum);
# endif
}
}
// approximate w_botline
curwin->w_botline += lnum - curwin->w_topline;
curwin->w_topline = lnum;
}
else
#endif
if (curwin->w_p_wrap && curwin->w_p_sms)
{
int off1 = curwin_col_off();
int off2 = off1 + curwin_col_off2();
int add;
int size = win_linetabsize(curwin, curwin->w_topline,
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
linenr_T prev_topline = curwin->w_topline;
// 'smoothscroll': increase "w_skipcol" until it goes over the end of
// the line, then advance to the next line.
for (int todo = line_count; todo > 0; --todo)
{
add = curwin->w_width - (curwin->w_skipcol > 0 ? off2 : off1);
curwin->w_skipcol += add;
if (curwin->w_skipcol >= size)
{
if (curwin->w_topline == curbuf->b_ml.ml_line_count)
if (lnum == curwin->w_topline
&& curwin->w_p_wrap && curwin->w_p_sms)
{
curwin->w_skipcol -= add;
break;
// 'smoothscroll': increase "w_skipcol" until it goes over
// the end of the line, then advance to the next line.
int add = curwin->w_skipcol > 0 ? width2 : width1;
curwin->w_skipcol += add;
if (curwin->w_skipcol >= size)
{
if (lnum == curbuf->b_ml.ml_line_count)
{
// at the last screen line, can't scroll further
curwin->w_skipcol -= add;
break;
}
++lnum;
}
}
else
{
if (lnum >= curbuf->b_ml.ml_line_count)
break;
++lnum;
}
if (lnum > curwin->w_topline)
{
// approximate w_botline
curwin->w_botline += lnum - curwin->w_topline;
curwin->w_topline = lnum;
# ifdef FEAT_DIFF
curwin->w_topfill = diff_check_fill(curwin, lnum);
# endif
curwin->w_skipcol = 0;
if (todo > 1 && do_smoothscroll)
size = win_linetabsize(curwin, curwin->w_topline,
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
}
++curwin->w_topline;
++curwin->w_botline; // approximate w_botline
curwin->w_skipcol = 0;
if (todo > 1)
size = win_linetabsize(curwin, curwin->w_topline,
ml_get(curwin->w_topline), (colnr_T)MAXCOL);
}
}
if (curwin->w_topline == prev_topline)
// need to redraw even though w_topline didn't change
redraw_later(UPD_NOT_VALID);

View File

@@ -88,6 +88,21 @@ func Test_smoothscroll_CtrlE_CtrlY()
call term_sendkeys(buf, "\<C-Y>")
call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
if has('folding')
call term_sendkeys(buf, ":set foldmethod=indent\<CR>")
" move the cursor so we can reuse the same dumps
call term_sendkeys(buf, "5G")
call term_sendkeys(buf, "\<C-E>")
call VerifyScreenDump(buf, 'Test_smoothscroll_1', {})
call term_sendkeys(buf, "\<C-E>")
call VerifyScreenDump(buf, 'Test_smoothscroll_2', {})
call term_sendkeys(buf, "7G")
call term_sendkeys(buf, "\<C-Y>")
call VerifyScreenDump(buf, 'Test_smoothscroll_7', {})
call term_sendkeys(buf, "\<C-Y>")
call VerifyScreenDump(buf, 'Test_smoothscroll_8', {})
endif
call StopVimInTerminal(buf)
endfunc

View File

@@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
646,
/**/
645,
/**/