fix(drawline): hang while redrawing diff filler above fold #39219

Problem:
win_line() falls into infinite loop when a diff window has top filler
above its first visible buffer line, that first visible buffer line is a
closed fold, and the folded line uses normal non-empty foldtext.

Solution:
Allow flushing pending diff filler rows even when the underlying buffer
line is folded with foldtext.

AI-assisted: Codex

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
(cherry picked from commit f2cc0a249d)
This commit is contained in:
Jaehwang Jung
2026-04-20 01:29:31 +09:00
committed by github-actions[bot]
parent 43398547ec
commit 9966afbc9d
2 changed files with 24 additions and 1 deletions

View File

@@ -3105,7 +3105,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
end_check:
// At end of screen line and there is more to come: Display the line
// so far. If there is no more to display it is caught above.
if (wlv.col >= view_width && (!has_foldtext || virt_line_index >= 0)
if (wlv.col >= view_width && (!has_foldtext || wlv.filler_todo > 0)
&& (wlv.col <= leftcols_width
|| *ptr != NUL
|| wlv.filler_todo > 0

View File

@@ -2978,6 +2978,29 @@ describe('folded lines', function()
with_ext_multigrid(false)
end)
it('does not hang drawing diff filler above a folded line', function()
Screen.new(80, 24)
exec([[
call setline(1, ['fold', 'body'])
vnew
call setline(1, ['inserted', 'fold', 'body'])
windo diffthis
wincmd l
setlocal foldmethod=manual
1,2fold
normal! zM
wincmd h
normal! 1Gzt
redraw
let g:diff_filler_fold_done = 1
]])
eq(1, api.nvim_get_var('diff_filler_fold_done'))
assert_alive()
end)
it("do not interfere with corrected cursor position for 'scrolloff'", function()
local screen = Screen.new(40, 7)
exec([[