vim-patch:9.1.2118: 'cursorline' missing after :diffput to empty buf (#37628)

Problem:  'cursorline' and part of 'statusline' are missing after
          :diffput to an empty buffer.
Solution: Make sure the cursor doesn't go beyond the last line after
          :diffput (zeertzjq)

related: neovim/neovim#37621
closes:  vim/vim#19281

ce1e562fda
This commit is contained in:
zeertzjq
2026-01-30 20:09:33 +08:00
committed by GitHub
parent ebfbe4db49
commit 47ce93ad6d
3 changed files with 77 additions and 0 deletions

View File

@@ -3890,6 +3890,10 @@ static void diffgetput(const int addr_count, const int idx_cur, const int idx_fr
// lines.
if (curwin->w_cursor.lnum >= lnum + count) {
curwin->w_cursor.lnum += added;
// When the buffer was previously empty, the cursor may
// now be beyond the last line, so clamp cursor lnum.
curwin->w_cursor.lnum = MIN(curwin->w_cursor.lnum,
curbuf->b_ml.ml_line_count);
} else if (added < 0) {
curwin->w_cursor.lnum = lnum;
}

View File

@@ -3379,3 +3379,50 @@ it(':%bwipe does not crash when using diffexpr', function()
4 buffers wiped out |
]])
end)
-- oldtest: Test_diffput_to_empty_buf()
it(':diffput to empty buffer redraws properly', function()
local screen = Screen.new(75, 20)
exec([[
set ruler
call setline(1, ['foo', 'bar', 'baz'])
rightbelow vnew
windo diffthis
windo set cursorline nofoldenable
wincmd t
]])
screen:add_extra_attr_ids({
[100] = { underline = true, background = Screen.colors.LightBlue },
})
screen:expect([[
{7: }{100:^foo }│{7: }{23:-----------------------------------}|
{7: }{22:bar }│{7: }{23:-----------------------------------}|
{7: }{22:baz }│{7: }{23:-----------------------------------}|
{1:~ }│{7: }{21: }|
{1:~ }│{1:~ }|*14
{3:[No Name] [+] 1,1 All }{2:[No Name] 0,0-1 All}|
|
]])
feed('0') -- Trigger an initial 'cursorbind' check.
screen:expect_unchanged()
command('diffput')
screen:expect([[
{7: }{21:^foo }│{7: }foo |
{7: }bar │{7: }bar |
{7: }baz │{7: }{21:baz }|
{1:~ }│{1:~ }|*15
{3:[No Name] [+] 1,1 All }{2:[No Name] [+] 3,1 All}|
|
]])
command(':redraw!')
screen:expect_unchanged()
feed('j')
screen:expect([[
{7: }foo │{7: }foo |
{7: }{21:^bar }│{7: }{21:bar }|
{7: }baz │{7: }baz |
{1:~ }│{1:~ }|*15
{3:[No Name] [+] 2,1 All }{2:[No Name] [+] 2,1 All}|
|
]])
end)

View File

@@ -3347,4 +3347,30 @@ func Test_diffexpr_wipe_buffers()
call term_sendkeys(buf, ":so\<CR>")
call WaitForAssert({-> assert_match('4 buffers wiped out', term_getline(buf, 20))})
call StopVimInTerminal(buf)
endfunc
func Test_diffput_to_empty_buf()
CheckScreendump
let lines =<< trim END
call setline(1, ['foo', 'bar', 'baz'])
rightbelow vnew
windo diffthis
windo set cursorline nofoldenable
wincmd t
END
call writefile(lines, 'Xtest_diffput_to_empty_buf', 'D')
let buf = RunVimInTerminal('-S Xtest_diffput_to_empty_buf', {})
call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_01', {})
call term_sendkeys(buf, '0') " Trigger an initial 'cursorbind' check.
call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_01', {})
call term_sendkeys(buf, ":diffput | echo\<CR>")
call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_02', {})
call term_sendkeys(buf, ":redraw!\<CR>")
call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_02', {})
call term_sendkeys(buf, 'j')
call VerifyScreenDump(buf, 'Test_diffput_to_empty_buf_03', {})
call StopVimInTerminal(buf)