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 * 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 * wrapped line. It's positive if 'number' or 'relativenumber' is on and 'n'
* 'cpoptions'. * is in 'cpoptions'.
*/ */
int int
win_col_off2(win_T *wp) win_col_off2(win_T *wp)
@@ -1463,7 +1463,7 @@ scrolldown(
if (curwin->w_p_wrap && curwin->w_p_sms) if (curwin->w_p_wrap && curwin->w_p_sms)
{ {
width1 = curwin->w_width - curwin_col_off(); width1 = curwin->w_width - curwin_col_off();
width2 = width1 - curwin_col_off2(); width2 = width1 + curwin_col_off2();
} }
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
@@ -1601,24 +1601,31 @@ scrollup(
long line_count, long line_count,
int byfold UNUSED) // TRUE: count a closed fold as one line int byfold UNUSED) // TRUE: count a closed fold as one line
{ {
#if defined(FEAT_FOLDING) || defined(FEAT_DIFF) int do_smoothscroll = curwin->w_p_wrap && curwin->w_p_sms;
linenr_T lnum;
if ( if (do_smoothscroll
# ifdef FEAT_FOLDING # ifdef FEAT_FOLDING
(byfold && hasAnyFolding(curwin)) || (byfold && hasAnyFolding(curwin))
# ifdef FEAT_DIFF
||
# endif
# endif # endif
# ifdef FEAT_DIFF # ifdef FEAT_DIFF
curwin->w_p_diff || curwin->w_p_diff
# endif # endif
) )
{ {
// count each sequence of folded lines as one logical line int width1 = curwin->w_width - curwin_col_off();
lnum = curwin->w_topline; int width2 = width1 + curwin_col_off2();
while (line_count--) 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 # ifdef FEAT_DIFF
if (curwin->w_topfill > 0) if (curwin->w_topfill > 0)
@@ -1626,54 +1633,54 @@ scrollup(
else else
# endif # endif
{ {
linenr_T lnum = curwin->w_topline;
# ifdef FEAT_FOLDING # ifdef FEAT_FOLDING
if (byfold) if (byfold)
// for a closed fold: go to the last line in the fold
(void)hasFolding(lnum, NULL, &lnum); (void)hasFolding(lnum, NULL, &lnum);
# endif # endif
if (lnum >= curbuf->b_ml.ml_line_count) if (lnum == curwin->w_topline
break; && curwin->w_p_wrap && curwin->w_p_sms)
++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)
{ {
curwin->w_skipcol -= add; // 'smoothscroll': increase "w_skipcol" until it goes over
break; // 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) if (curwin->w_topline == prev_topline)
// need to redraw even though w_topline didn't change // need to redraw even though w_topline didn't change
redraw_later(UPD_NOT_VALID); redraw_later(UPD_NOT_VALID);

View File

@@ -88,6 +88,21 @@ func Test_smoothscroll_CtrlE_CtrlY()
call term_sendkeys(buf, "\<C-Y>") call term_sendkeys(buf, "\<C-Y>")
call VerifyScreenDump(buf, 'Test_smoothscroll_8', {}) 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) call StopVimInTerminal(buf)
endfunc endfunc

View File

@@ -699,6 +699,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 */
/**/
646,
/**/ /**/
645, 645,
/**/ /**/