patch 9.2.1032: scrolling moves cursor up with 'scrolloffpad'
Commit:
https://github.com/vim/vim/commit/6a3db67a52cc5a2de13ce42f93ccf07493b8d2a4
Author: SeungheeKim <
ksh...@naver.com>
Date: Wed Sep 2 20:58:51 2026 +0000
patch 9.2.1032: scrolling moves cursor up with 'scrolloffpad'
Problem: Cursor correction can move the cursor up at the end of the
buffer when 'scrolloffpad' is enabled (gx089).
Solution: Allow missing context below EOF in cursor_correct(). Add
regression tests for CTRL-D and CTRL-E (Seunghee Kim).
fixes: #21096
closes: #21188
Co-Authored-By: OpenAI Codex <
nor...@openai.com>
Signed-off-by: SeungheeKim <
ksh...@naver.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/move.c b/src/move.c
index 635e63eb2..42790b3e2 100644
--- a/src/move.c
+++ b/src/move.c
@@ -3113,8 +3113,9 @@ cursor_correct(void)
if (curwin->w_botline == curbuf->b_ml.ml_line_count + 1
&& mouse_dragging == 0)
{
- if (!use_scrolloffpad())
- below_wanted = 0;
+ // Missing context below EOF must not move the cursor up. Automatic
+ // scrolling handles the centering for 'scrolloffpad'.
+ below_wanted = 0;
max_off = (curwin->w_height - 1) / 2;
if (above_wanted > max_off)
above_wanted = max_off;
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index ee865e637..9b24c38d9 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1760,6 +1760,60 @@ func Test_scrolloffpad_paging_to_eof()
bwipe!
endfunc
+func Test_scrolloffpad_ctrl_d_at_eof()
+ new
+ setlocal scroll=6
+ call setline(1, map(range(1, 80), 'printf("line %d", v:val)'))
+
+ for height in [11, 12]
+ execute 'resize ' .. height
+ for so in [1, 999]
+ let &l:scrolloff = so
+ for sop in [0, 1]
+ let &l:scrolloffpad = sop
+ for endcmd in ['ggG', 'ggGzb']
+ let context = printf('height=%d so=%d sop=%d %s',
+ \ height, so, sop, endcmd)
+ execute 'normal! ' .. endcmd
+ let view_before = winsaveview()
+
+ call assert_beeps('execute "normal! \<C-D>"')
+ call assert_equal(view_before, winsaveview(), context)
+ endfor
+ endfor
+ endfor
+ endfor
+
+ bwipe!
+endfunc
+
+func Test_scrolloffpad_ctrl_e_at_eof()
+ new
+ call setline(1, map(range(1, 80), 'printf("line %d", v:val)'))
+
+ for height in [11, 12]
+ execute 'resize ' .. height
+ for so in [1, 999]
+ let &l:scrolloff = so
+ for sop in [0, 1]
+ let &l:scrolloffpad = sop
+ for endcmd in ['ggG', 'ggGzb']
+ let context = printf('height=%d so=%d sop=%d %s',
+ \ height, so, sop, endcmd)
+ execute 'normal! ' .. endcmd
+ let expected_view = winsaveview()
+ let expected_view.topline += 1
+
+ execute "normal! \<C-E>"
+ call assert_equal(expected_view, winsaveview(), context)
+ endfor
+ endfor
+ endfor
+ endfor
+
+ bwipe!
+endfunc
+
func Test_scrolloffpad_autocmd_append_at_eof()
let states = {}
for sop in [0, 1]
diff --git a/src/version.c b/src/version.c
index 5fdd1cad0..c76b56a8a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1032,
/**/
1031,
/**/