vim-patch:9.1.0215: Half-page scrolling does not support smooth-scrolling

Problem:  Page-wise scrolling with Ctrl-D/Ctrl-U implements
          it's own logic to change the topline and cursor.
          More logic than necessary for scrolling with Ctrl-F/Ctrl-B
          was removed in patch 9.1.0211.
Solution: Re-use the logic from Ctrl-E/Ctrl-Y/Ctrl-F/Ctrl-B while
          staying backward compatible as much as possible.
          Restore some of the logic that determined how many lines will
          be scrolled (Luuk van Baal)

5a2e3ec9ac
This commit is contained in:
Luuk van Baal
2024-03-28 10:20:45 +01:00
parent 4147302f4b
commit 2f638c0ac6
11 changed files with 159 additions and 178 deletions

View File

@@ -5694,7 +5694,7 @@ A jump table for the options with a short description can be found at |Q_op|.
You may also want to add "lastline" to the 'display' option to show as You may also want to add "lastline" to the 'display' option to show as
much of the last line as possible. much of the last line as possible.
NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y, NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y,
CTRL-B, CTRL-F and scrolling with the mouse. CTRL-D, CTRL-U, CTRL-F, CTRL-B and scrolling with the mouse.
*'softtabstop'* *'sts'* *'softtabstop'* *'sts'*
'softtabstop' 'sts' number (default 0) 'softtabstop' 'sts' number (default 0)
@@ -7164,8 +7164,8 @@ A jump table for the options with a short description can be found at |Q_op|.
will scroll 'window' minus two lines, with a minimum of one. will scroll 'window' minus two lines, with a minimum of one.
When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll
in a much smarter way, taking care of wrapping lines. in a much smarter way, taking care of wrapping lines.
When resizing the Vim window, the value is smaller than 1 or more than When resizing the Vim window, and the value is smaller than 1 or more
or equal to 'lines' it will be set to 'lines' minus 1. than or equal to 'lines' it will be set to 'lines' minus 1.
Note: Do not confuse this with the height of the Vim window, use Note: Do not confuse this with the height of the Vim window, use
'lines' for that. 'lines' for that.

View File

@@ -6076,7 +6076,7 @@ vim.go.sta = vim.go.smarttab
--- You may also want to add "lastline" to the 'display' option to show as --- You may also want to add "lastline" to the 'display' option to show as
--- much of the last line as possible. --- much of the last line as possible.
--- NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y, --- NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y,
--- CTRL-B, CTRL-F and scrolling with the mouse. --- CTRL-D, CTRL-U, CTRL-F, CTRL-B and scrolling with the mouse.
--- ---
--- @type boolean --- @type boolean
vim.o.smoothscroll = false vim.o.smoothscroll = false
@@ -7861,8 +7861,8 @@ vim.wo.winbl = vim.wo.winblend
--- will scroll 'window' minus two lines, with a minimum of one. --- will scroll 'window' minus two lines, with a minimum of one.
--- When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll --- When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll
--- in a much smarter way, taking care of wrapping lines. --- in a much smarter way, taking care of wrapping lines.
--- When resizing the Vim window, the value is smaller than 1 or more than --- When resizing the Vim window, and the value is smaller than 1 or more
--- or equal to 'lines' it will be set to 'lines' minus 1. --- than or equal to 'lines' it will be set to 'lines' minus 1.
--- Note: Do not confuse this with the height of the Vim window, use --- Note: Do not confuse this with the height of the Vim window, use
--- 'lines' for that. --- 'lines' for that.
--- ---

View File

@@ -4193,7 +4193,7 @@ static void ins_pageup(void)
} }
pos_T tpos = curwin->w_cursor; pos_T tpos = curwin->w_cursor;
if (onepage(BACKWARD, 1) == OK) { if (pagescroll(BACKWARD, 1, false) == OK) {
start_arrow(&tpos); start_arrow(&tpos);
can_cindent = true; can_cindent = true;
} else { } else {
@@ -4238,7 +4238,7 @@ static void ins_pagedown(void)
} }
pos_T tpos = curwin->w_cursor; pos_T tpos = curwin->w_cursor;
if (onepage(FORWARD, 1) == OK) { if (pagescroll(FORWARD, 1, false) == OK) {
start_arrow(&tpos); start_arrow(&tpos);
can_cindent = true; can_cindent = true;
} else { } else {

View File

@@ -1024,7 +1024,7 @@ void do_mousescroll(cmdarg_T *cap)
// Vertical scrolling // Vertical scrolling
if ((State & MODE_NORMAL) && shift_or_ctrl) { if ((State & MODE_NORMAL) && shift_or_ctrl) {
// whole page up or down // whole page up or down
onepage(cap->arg ? FORWARD : BACKWARD, 1); pagescroll(cap->arg ? FORWARD : BACKWARD, 1, false);
} else { } else {
if (shift_or_ctrl) { if (shift_or_ctrl) {
// whole page up or down // whole page up or down

View File

@@ -2278,19 +2278,90 @@ void cursor_correct(win_T *wp)
wp->w_viewport_invalid = true; wp->w_viewport_invalid = true;
} }
/// Decide how much overlap to use for page-up or page-down scrolling.
/// This is symmetric, so that doing both keeps the same lines displayed.
/// Three lines are examined:
///
/// before CTRL-F after CTRL-F / before CTRL-B
/// etc. l1
/// l1 last but one line ------------
/// l2 last text line l2 top text line
/// ------------- l3 second text line
/// l3 etc.
static int get_scroll_overlap(Direction dir)
{
lineoff_T loff;
int min_height = curwin->w_height_inner - 2;
validate_botline(curwin);
if (dir == FORWARD && curwin->w_botline > curbuf->b_ml.ml_line_count) {
return min_height + 2; // no overlap, still handle 'smoothscroll'
}
loff.lnum = dir == FORWARD ? curwin->w_botline : curwin->w_topline - 1;
loff.fill = win_get_fill(curwin, loff.lnum + dir == BACKWARD)
- (dir == FORWARD ? curwin->w_filler_rows : curwin->w_topfill);
loff.height = loff.fill > 0 ? 1 : plines_win_nofill(curwin, loff.lnum, true);
int h1 = loff.height;
if (h1 > min_height) {
return min_height + 2; // no overlap
}
if (dir == FORWARD) {
topline_back(curwin, &loff);
} else {
botline_forw(curwin, &loff);
}
int h2 = loff.height;
if (h2 == MAXCOL || h2 + h1 > min_height) {
return min_height + 2; // no overlap
}
if (dir == FORWARD) {
topline_back(curwin, &loff);
} else {
botline_forw(curwin, &loff);
}
int h3 = loff.height;
if (h3 == MAXCOL || h3 + h2 > min_height) {
return min_height + 2; // no overlap
}
if (dir == FORWARD) {
topline_back(curwin, &loff);
} else {
botline_forw(curwin, &loff);
}
int h4 = loff.height;
if (h4 == MAXCOL || h4 + h3 + h2 > min_height || h3 + h2 + h1 > min_height) {
return min_height + 1; // 1 line overlap
} else {
return min_height; // 2 lines overlap
}
}
/// Move screen "count" pages up ("dir" is BACKWARD) or down ("dir" is FORWARD) /// Move screen "count" pages up ("dir" is BACKWARD) or down ("dir" is FORWARD)
/// and update the screen. /// and update the screen.
/// ///
/// @return FAIL for failure, OK otherwise. /// @return FAIL for failure, OK otherwise.
int onepage(Direction dir, int count) int pagescroll(Direction dir, int count, bool half)
{ {
int prev_topfill = curwin->w_topfill; int prev_topfill = curwin->w_topfill;
linenr_T prev_topline = curwin->w_topline; linenr_T prev_topline = curwin->w_topline;
colnr_T prev_skipcol = curwin->w_skipcol; colnr_T prev_skipcol = curwin->w_skipcol;
// Scroll 'window' or current window height lines. if (half) {
count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1) // Scroll [count], 'scroll' or current window height lines.
? (int)p_window - 2 : curwin->w_height - 1); if (count) {
curwin->w_p_scr = MIN(curwin->w_height_inner, count);
}
count = MIN(curwin->w_height_inner, (int)curwin->w_p_scr);
} else {
// Scroll 'window' or current window height lines.
count *= ((ONE_WINDOW && p_window > 0 && p_window < Rows - 1)
? (int)p_window - 2 : get_scroll_overlap(dir));
}
if (curwin->w_p_sms) { if (curwin->w_p_sms) {
scroll_redraw(dir == FORWARD, count); scroll_redraw(dir == FORWARD, count);
@@ -2307,13 +2378,22 @@ int onepage(Direction dir, int count)
} }
curwin->w_p_sms = false; curwin->w_p_sms = false;
} }
// Move cursor to first line of closed fold.
foldAdjustCursor(curwin);
int nochange = curwin->w_topline == prev_topline int nochange = curwin->w_topline == prev_topline
&& curwin->w_topfill == prev_topfill && curwin->w_topfill == prev_topfill
&& curwin->w_skipcol == prev_skipcol; && curwin->w_skipcol == prev_skipcol;
// Error if the viewport did not change and the cursor is already
// at the boundary.
if (nochange) { if (nochange) {
beep_flush(); int prev_cursor = curwin->w_cursor.lnum;
curwin->w_cursor.lnum += (count + 1) * (dir == FORWARD ? 1 : -1);
check_cursor(curwin);
if (curwin->w_cursor.lnum == prev_cursor) {
beep_flush();
}
} else if (!curwin->w_p_sms || curwin->w_skipcol == prev_skipcol) { } else if (!curwin->w_p_sms || curwin->w_skipcol == prev_skipcol) {
beginline(BL_SOL | BL_FIX); beginline(BL_SOL | BL_FIX);
} }
@@ -2321,130 +2401,6 @@ int onepage(Direction dir, int count)
return nochange; return nochange;
} }
// Scroll 'scroll' lines up or down.
void halfpage(bool flag, linenr_T Prenum)
{
int scrolled = 0;
int i;
if (Prenum) {
curwin->w_p_scr = (Prenum > curwin->w_height_inner) ? curwin->w_height_inner
: Prenum;
}
assert(curwin->w_p_scr <= INT_MAX);
int n = curwin->w_p_scr <= curwin->w_height_inner ? (int)curwin->w_p_scr
: curwin->w_height_inner;
update_topline(curwin);
validate_botline(curwin);
int room = curwin->w_empty_rows + curwin->w_filler_rows;
if (flag) {
// scroll the text up
while (n > 0 && curwin->w_botline <= curbuf->b_ml.ml_line_count) {
if (curwin->w_topfill > 0) {
i = 1;
n--;
curwin->w_topfill--;
} else {
i = plines_win_nofill(curwin, curwin->w_topline, true);
n -= i;
if (n < 0 && scrolled > 0) {
break;
}
hasFolding(curwin, curwin->w_topline, NULL, &curwin->w_topline);
curwin->w_topline++;
curwin->w_topfill = win_get_fill(curwin, curwin->w_topline);
if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum++;
curwin->w_valid &=
~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
}
}
curwin->w_valid &= ~(VALID_CROW|VALID_WROW);
scrolled += i;
// Correct w_botline for changed w_topline.
// Won't work when there are filler lines.
if (win_may_fill(curwin)) {
curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP);
} else {
room += i;
do {
i = plines_win(curwin, curwin->w_botline, true);
if (i > room) {
break;
}
hasFolding(curwin, curwin->w_botline, NULL, &curwin->w_botline);
curwin->w_botline++;
room -= i;
} while (curwin->w_botline <= curbuf->b_ml.ml_line_count);
}
}
// When hit bottom of the file: move cursor down.
if (n > 0) {
if (hasAnyFolding(curwin)) {
while (--n >= 0
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
hasFolding(curwin, curwin->w_cursor.lnum, NULL,
&curwin->w_cursor.lnum);
curwin->w_cursor.lnum++;
}
} else {
curwin->w_cursor.lnum += n;
}
check_cursor_lnum(curwin);
}
} else {
// scroll the text down
while (n > 0 && curwin->w_topline > 1) {
if (curwin->w_topfill < win_get_fill(curwin, curwin->w_topline)) {
i = 1;
n--;
curwin->w_topfill++;
} else {
i = plines_win_nofill(curwin, curwin->w_topline - 1, true);
n -= i;
if (n < 0 && scrolled > 0) {
break;
}
curwin->w_topline--;
hasFolding(curwin, curwin->w_topline, &curwin->w_topline, NULL);
curwin->w_topfill = 0;
}
curwin->w_valid &= ~(VALID_CROW|VALID_WROW|
VALID_BOTLINE|VALID_BOTLINE_AP);
scrolled += i;
if (curwin->w_cursor.lnum > 1) {
curwin->w_cursor.lnum--;
curwin->w_valid &= ~(VALID_VIRTCOL|VALID_CHEIGHT|VALID_WCOL);
}
}
// When hit top of the file: move cursor up.
if (n > 0) {
if (curwin->w_cursor.lnum <= (linenr_T)n) {
curwin->w_cursor.lnum = 1;
} else if (hasAnyFolding(curwin)) {
while (--n >= 0 && curwin->w_cursor.lnum > 1) {
curwin->w_cursor.lnum--;
hasFolding(curwin, curwin->w_cursor.lnum,
&curwin->w_cursor.lnum, NULL);
}
} else {
curwin->w_cursor.lnum -= n;
}
}
}
// Move cursor to first line of closed fold.
foldAdjustCursor(curwin);
check_topfill(curwin, !flag);
cursor_correct(curwin);
beginline(BL_SOL | BL_FIX);
redraw_later(curwin, UPD_VALID);
}
void do_check_cursorbind(void) void do_check_cursorbind(void)
{ {
static win_T *prev_curwin = NULL; static win_T *prev_curwin = NULL;

View File

@@ -2258,7 +2258,7 @@ static void nv_page(cmdarg_T *cap)
goto_tabpage(cap->count0); goto_tabpage(cap->count0);
} }
} else { } else {
onepage(cap->arg, cap->count1); pagescroll(cap->arg, cap->count1, false);
} }
} }
@@ -6394,12 +6394,8 @@ static void nv_at(cmdarg_T *cap)
/// Handle the CTRL-U and CTRL-D commands. /// Handle the CTRL-U and CTRL-D commands.
static void nv_halfpage(cmdarg_T *cap) static void nv_halfpage(cmdarg_T *cap)
{ {
if ((cap->cmdchar == Ctrl_U && curwin->w_cursor.lnum == 1) if (!checkclearop(cap->oap)) {
|| (cap->cmdchar == Ctrl_D pagescroll(cap->cmdchar == Ctrl_D, cap->count0, true);
&& curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count)) {
clearopbeep(cap->oap);
} else if (!checkclearop(cap->oap)) {
halfpage(cap->cmdchar == Ctrl_D, cap->count0);
} }
} }

View File

@@ -7664,7 +7664,7 @@ return {
You may also want to add "lastline" to the 'display' option to show as You may also want to add "lastline" to the 'display' option to show as
much of the last line as possible. much of the last line as possible.
NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y, NOTE: only partly implemented, currently works with CTRL-E, CTRL-Y,
CTRL-B, CTRL-F and scrolling with the mouse. CTRL-D, CTRL-U, CTRL-F, CTRL-B and scrolling with the mouse.
]=], ]=],
full_name = 'smoothscroll', full_name = 'smoothscroll',
pv_name = 'p_sms', pv_name = 'p_sms',
@@ -9806,8 +9806,8 @@ return {
will scroll 'window' minus two lines, with a minimum of one. will scroll 'window' minus two lines, with a minimum of one.
When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll
in a much smarter way, taking care of wrapping lines. in a much smarter way, taking care of wrapping lines.
When resizing the Vim window, the value is smaller than 1 or more than When resizing the Vim window, and the value is smaller than 1 or more
or equal to 'lines' it will be set to 'lines' minus 1. than or equal to 'lines' it will be set to 'lines' minus 1.
Note: Do not confuse this with the height of the Vim window, use Note: Do not confuse this with the height of the Vim window, use
'lines' for that. 'lines' for that.
]=], ]=],

View File

@@ -19,7 +19,7 @@ describe('matchparen', function()
call cursor(5, 1) call cursor(5, 1)
]]) ]])
feed('V<c-d><c-d>') feed('V<c-d><c-d>3j')
screen:expect([[ screen:expect([[
{17:{} | {17:{} |
{17:}} | {17:}} |

View File

@@ -1312,15 +1312,15 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("i\<PageDown>\<esc>", 'tnix') call feedkeys("i\<PageDown>\<esc>", 'tnix')
call assert_equal([0, 30, 1, 0], getpos('.')) call assert_equal([0, 30, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 30, 1, 0], getpos('.')) call assert_equal([0, 29, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 23, 1, 0], getpos('.')) call assert_equal([0, 21, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 15, 1, 0], getpos('.')) call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 10, 1, 0], getpos('.')) call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 2, 11, 0], getpos('.'))
" <S-Up> is the same as <PageUp> " <S-Up> is the same as <PageUp>
" <S-Down> is the same as <PageDown> " <S-Down> is the same as <PageDown>
call cursor(1, 1) call cursor(1, 1)
@@ -1335,28 +1335,28 @@ func Test_edit_PAGEUP_PAGEDOWN()
call feedkeys("i\<S-Down>\<esc>", 'tnix') call feedkeys("i\<S-Down>\<esc>", 'tnix')
call assert_equal([0, 30, 1, 0], getpos('.')) call assert_equal([0, 30, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 30, 1, 0], getpos('.')) call assert_equal([0, 29, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 23, 1, 0], getpos('.')) call assert_equal([0, 21, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 15, 1, 0], getpos('.')) call assert_equal([0, 13, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 10, 1, 0], getpos('.')) call assert_equal([0, 10, 1, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 2, 11, 0], getpos('.'))
set nostartofline set nostartofline
call cursor(30, 11) call cursor(30, 11)
norm! zt norm! zt
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 30, 11, 0], getpos('.')) call assert_equal([0, 29, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 23, 11, 0], getpos('.')) call assert_equal([0, 21, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 15, 11, 0], getpos('.')) call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<PageUp>\<esc>", 'tnix') call feedkeys("A\<PageUp>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 2, 11, 0], getpos('.'))
call cursor(1, 1) call cursor(1, 1)
call feedkeys("A\<PageDown>\<esc>", 'tnix') call feedkeys("A\<PageDown>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.')) call assert_equal([0, 9, 11, 0], getpos('.'))
@@ -1373,15 +1373,15 @@ func Test_edit_PAGEUP_PAGEDOWN()
call cursor(30, 11) call cursor(30, 11)
norm! zt norm! zt
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 30, 11, 0], getpos('.')) call assert_equal([0, 29, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 23, 11, 0], getpos('.')) call assert_equal([0, 21, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 15, 11, 0], getpos('.')) call assert_equal([0, 13, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 10, 11, 0], getpos('.'))
call feedkeys("A\<S-Up>\<esc>", 'tnix') call feedkeys("A\<S-Up>\<esc>", 'tnix')
call assert_equal([0, 10, 11, 0], getpos('.')) call assert_equal([0, 2, 11, 0], getpos('.'))
call cursor(1, 1) call cursor(1, 1)
call feedkeys("A\<S-Down>\<esc>", 'tnix') call feedkeys("A\<S-Down>\<esc>", 'tnix')
call assert_equal([0, 9, 11, 0], getpos('.')) call assert_equal([0, 9, 11, 0], getpos('.'))

View File

@@ -1283,9 +1283,13 @@ func Test_vert_scroll_cmds()
exe "normal \<C-D>" exe "normal \<C-D>"
call assert_equal(46, line('.')) call assert_equal(46, line('.'))
exe "normal \<C-U>" exe "normal \<C-U>"
call assert_equal(36, line('.')) call assert_equal(36, line('w0'))
call assert_equal(46, line('.'))
exe "normal \<C-U>" exe "normal \<C-U>"
call assert_equal(10, line('.')) call assert_equal(1, line('w0'))
call assert_equal(40, line('.'))
exe "normal \<C-U>"
call assert_equal(30, line('.'))
exe "normal \<C-U>" exe "normal \<C-U>"
call assert_equal(1, line('.')) call assert_equal(1, line('.'))
set scroll& set scroll&
@@ -1306,9 +1310,8 @@ func Test_vert_scroll_cmds()
call assert_equal(50, line('.')) call assert_equal(50, line('.'))
call assert_equal(100, line('w$')) call assert_equal(100, line('w$'))
normal z. normal z.
let lnum = winline()
exe "normal \<C-D>" exe "normal \<C-D>"
call assert_equal(lnum, winline()) call assert_equal(1, winline())
call assert_equal(50, line('.')) call assert_equal(50, line('.'))
normal zt normal zt
exe "normal \<C-D>" exe "normal \<C-D>"
@@ -3077,7 +3080,8 @@ func Test_normal42_halfpage()
call assert_equal(2, &scroll) call assert_equal(2, &scroll)
set scroll=5 set scroll=5
exe "norm! \<c-u>" exe "norm! \<c-u>"
call assert_equal('3', getline('.')) call assert_equal('3', getline('w0'))
call assert_equal('8', getline('.'))
1 1
set scrolloff=5 set scrolloff=5
exe "norm! \<c-d>" exe "norm! \<c-d>"
@@ -3823,11 +3827,11 @@ func Test_normal_vert_scroll_longline()
call assert_equal(11, line('.')) call assert_equal(11, line('.'))
call assert_equal(1, winline()) call assert_equal(1, winline())
exe "normal \<C-B>" exe "normal \<C-B>"
call assert_equal(11, line('.')) call assert_equal(10, line('.'))
call assert_equal(9, winline()) call assert_equal(10, winline())
exe "normal \<C-B>\<C-B>" exe "normal \<C-B>\<C-B>"
call assert_equal(5, line('.')) call assert_equal(5, line('.'))
call assert_equal(1, winline()) call assert_equal(5, winline())
bwipe! bwipe!
endfunc endfunc
@@ -4196,12 +4200,16 @@ func Test_single_line_scroll()
norm! { norm! {
call assert_equal([0, 1, 1, 0], getpos('.')) call assert_equal([0, 1, 1, 0], getpos('.'))
" Ctrl-B scrolls up with hidden "above" virtual text. " Ctrl-B/Ctrl-U scroll up with hidden "above" virtual text.
set smoothscroll set smoothscroll
exe "normal \<C-E>" exe "normal \<C-E>"
call assert_notequal(0, winsaveview().skipcol) call assert_notequal(0, winsaveview().skipcol)
exe "normal \<C-B>" exe "normal \<C-B>"
call assert_equal(0, winsaveview().skipcol) call assert_equal(0, winsaveview().skipcol)
exe "normal \<C-E>"
call assert_notequal(0, winsaveview().skipcol)
exe "normal \<C-U>"
call assert_equal(0, winsaveview().skipcol)
set smoothscroll& set smoothscroll&
bw! bw!

View File

@@ -1008,18 +1008,39 @@ func Test_smoothscroll_page()
call setline(1, 'abcde '->repeat(150)) call setline(1, 'abcde '->repeat(150))
exe "norm! \<C-F>" exe "norm! \<C-F>"
call assert_equal(320, winsaveview().skipcol) call assert_equal(400, winsaveview().skipcol)
exe "norm! \<C-F>" exe "norm! \<C-F>"
call assert_equal(640, winsaveview().skipcol) call assert_equal(800, winsaveview().skipcol)
exe "norm! \<C-F>" exe "norm! \<C-F>"
call assert_equal(880, winsaveview().skipcol) call assert_equal(880, winsaveview().skipcol)
exe "norm! \<C-B>" exe "norm! \<C-B>"
call assert_equal(560, winsaveview().skipcol) call assert_equal(480, winsaveview().skipcol)
exe "norm! \<C-B>" exe "norm! \<C-B>"
call assert_equal(240, winsaveview().skipcol) call assert_equal(80, winsaveview().skipcol)
exe "norm! \<C-B>" exe "norm! \<C-B>"
call assert_equal(0, winsaveview().skipcol) call assert_equal(0, winsaveview().skipcol)
exe "norm! \<C-D>"
call assert_equal(200, winsaveview().skipcol)
exe "norm! \<C-D>"
call assert_equal(400, winsaveview().skipcol)
exe "norm! \<C-D>"
call assert_equal(600, winsaveview().skipcol)
exe "norm! \<C-D>"
call assert_equal(800, winsaveview().skipcol)
exe "norm! \<C-D>"
call assert_equal(880, winsaveview().skipcol)
exe "norm! \<C-U>"
call assert_equal(680, winsaveview().skipcol)
exe "norm! \<C-U>"
call assert_equal(480, winsaveview().skipcol)
exe "norm! \<C-U>"
call assert_equal(280, winsaveview().skipcol)
exe "norm! \<C-U>"
call assert_equal(80, winsaveview().skipcol)
exe "norm! \<C-U>"
call assert_equal(0, winsaveview().skipcol)
set smoothscroll& set smoothscroll&
endfunc endfunc