summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/move.c113
-rw-r--r--src/testdir/test_scroll_opt.vim15
-rw-r--r--src/version.c2
3 files changed, 77 insertions, 53 deletions
diff --git a/src/move.c b/src/move.c
index 43e3273e2..0c2f23a7d 100644
--- a/src/move.c
+++ b/src/move.c
@@ -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;
+ if (lnum == curwin->w_topline
+ && curwin->w_p_wrap && curwin->w_p_sms)
+ {
+ // '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;
+ }
- // '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_skipcol -= add;
- break;
+ // 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);
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 876ccf203..e23068f8a 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 0cf367ea6..22d431cef 100644
--- a/src/version.c
+++ b/src/version.c
@@ -700,6 +700,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 646,
+/**/
645,
/**/
644,