mirror of
https://github.com/neovim/neovim.git
synced 2026-09-09 07:25:51 +00:00
fix(move): zz does not center the cursor with wrapped lines #41656
Problem:
`scroll_cursor_halfway()` resets its `above` and `below` row counters on
every iteration of the `topline` scan, because they are declared inside
the loop. Each iteration then takes one line from each side regardless
of how many screen rows those lines occupy, so tall wrapped lines below
the cursor leave it near the top of the window instead of centered.
Affects the default `nosmoothscroll` path, reached from "zz" and from
`update_topline()`. Regression from 9b9ccac625 (vim-patch:9.0.1121),
which moved the declarations to their first use while porting; the
upstream patch did not touch them.
Solution:
Declare the counters at function scope, as Vim does, so they accumulate
across iterations.
This commit is contained in:
committed by
GitHub
parent
5209695703
commit
034fca6c53
@@ -2204,6 +2204,8 @@ void scroll_cursor_halfway(win_T *wp, bool atend, bool prefer_above)
|
||||
}
|
||||
|
||||
int topfill = 0;
|
||||
int above = 0;
|
||||
int below = 0;
|
||||
while (topline > 1) {
|
||||
// If using smoothscroll, we can precisely scroll to the
|
||||
// exact point where the cursor is halfway down the screen.
|
||||
@@ -2238,8 +2240,6 @@ void scroll_cursor_halfway(win_T *wp, bool atend, bool prefer_above)
|
||||
// Depending on "prefer_above" we add a line above or below first.
|
||||
// Loop twice to avoid duplicating code.
|
||||
bool done = false;
|
||||
int above = 0;
|
||||
int below = 0;
|
||||
for (int round = 1; round <= 2; round++) {
|
||||
if (prefer_above
|
||||
? (round == 2 && below < above)
|
||||
|
||||
@@ -1600,3 +1600,33 @@ describe('scrolloffpad', function()
|
||||
screen:expect(s1)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('scroll_cursor_halfway()', function()
|
||||
local screen
|
||||
|
||||
before_each(function()
|
||||
screen = Screen.new(40, 12)
|
||||
end)
|
||||
|
||||
it('weighs lines by their screen height', function()
|
||||
exec([[
|
||||
set nosmoothscroll scrolloff=0
|
||||
call setline(1, map(range(1, 20), '"short " .. v:val'))
|
||||
call append(20, 'CURSOR')
|
||||
call append(21, map(range(1, 8), 'repeat("x", 200)'))
|
||||
]])
|
||||
feed('21Gzz')
|
||||
-- The lines below the cursor wrap to five rows each, so only one of them
|
||||
-- fits under the cursor once it sits on row 6 of this 11 row window.
|
||||
screen:expect([[
|
||||
short 16 |
|
||||
short 17 |
|
||||
short 18 |
|
||||
short 19 |
|
||||
short 20 |
|
||||
^CURSOR |
|
||||
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|*5
|
||||
|
|
||||
]])
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -533,8 +533,6 @@ describe('statuscolumn', function()
|
||||
exec_lua('vim.api.nvim_buf_set_extmark(0, ns, 15, 0, { virt_lines = {{{"END", ""}}} })')
|
||||
feed('GkJzz')
|
||||
screen:expect([[
|
||||
{8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 12}aaaaaaaaa |
|
||||
{8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 13}aaaaaaaaa |
|
||||
{8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
@@ -543,7 +541,7 @@ describe('statuscolumn', function()
|
||||
{15:wrapped 1 15}{19:aaaaaaaaa^ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa}|
|
||||
{15:wrapped 2 15}{19:aaaaaaaaaaaaaaaaaaa }|
|
||||
{8:virtual-1 15}END |
|
||||
{1:~ }|*3
|
||||
{1:~ }|*5
|
||||
|
|
||||
]])
|
||||
-- Also test virt_lines when 'cpoptions' includes "n"
|
||||
@@ -553,8 +551,6 @@ describe('statuscolumn', function()
|
||||
vim.api.nvim_buf_set_extmark(0, ns, 14, 0, { virt_lines = {{{"virt_line2", ""}}} })
|
||||
]])
|
||||
screen:expect([[
|
||||
{8:buffer 0 12}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aaaaaaaaa |
|
||||
{8:buffer 0 13}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aaaaaaaaa |
|
||||
{8:buffer 0 14}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
@@ -565,7 +561,7 @@ describe('statuscolumn', function()
|
||||
{8:virtual-1 15}virt_line1 |
|
||||
{8:virtual-2 15}virt_line2 |
|
||||
{8:virtual-3 15}END |
|
||||
{1:~ }|
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
-- Also test "col_rows" code path for 'relativenumber' cursor movement
|
||||
@@ -574,8 +570,6 @@ describe('statuscolumn', function()
|
||||
set stc=%{v:virtnum<0?'virtual':(!v:virtnum?'buffer':'wrapped')}%=%{'\ '.v:virtnum.'\ '.v:lnum.'\ '.v:relnum}
|
||||
]])
|
||||
screen:expect([[
|
||||
{8:buffer 0 12 3}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 12 3}aaaaaaaaaaa |
|
||||
{8:buffer 0 13 2}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 13 2}aaaaaaaaaaa |
|
||||
{8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
@@ -586,13 +580,11 @@ describe('statuscolumn', function()
|
||||
{8:virtual-1 15 0}virt_line1 |
|
||||
{8:virtual-2 15 0}virt_line2 |
|
||||
{8:virtual-3 15 0}END |
|
||||
{1:~ }|
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
feed('kk')
|
||||
screen:expect([[
|
||||
{8:buffer 0 12 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 12 1}aaaaaaaaaaa |
|
||||
{8:buffer 0 13 0}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8:wrapped 1 13 0}aaaaaaaaaa^a |
|
||||
{8:buffer 0 14 1}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
@@ -603,7 +595,7 @@ describe('statuscolumn', function()
|
||||
{8:virtual-1 15 2}virt_line1 |
|
||||
{8:virtual-2 15 2}virt_line2 |
|
||||
{8:virtual-3 15 2}END |
|
||||
{1:~ }|
|
||||
{1:~ }|*3
|
||||
|
|
||||
]])
|
||||
feed('gg5<C-E>')
|
||||
|
||||
Reference in New Issue
Block a user