fix(fold): virtual lines duplicate foldopen (#39891)

Problem:
Virtual lines above a line where a fold starts show `foldopen` in
`foldcolumn`.

Solution:
Check if the line below the virtual one is inside a fold that starts
higher up or if it's the start of a fold. In the latter case, don't show
anything in `foldcolumn` for the virtual line.

refactor: lint
(cherry picked from commit 526ae1cc1b)
This commit is contained in:
Matei Stroia
2026-05-20 14:56:39 +03:00
committed by github-actions[bot]
parent b490fba786
commit 8fccb26cd3
2 changed files with 107 additions and 1 deletions

View File

@@ -486,7 +486,15 @@ static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv)
int fdc = compute_foldcolumn(wp, 0);
if (fdc > 0) {
int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLF : HLF_FC);
fill_foldcolumn(wp, wlv->foldinfo, wlv->lnum, attr, fdc, &wlv->off, NULL, NULL);
// Only draw 'foldcolumn' for filler line if lnum is inside a fold that
// starts higher up. We don't want to show 'foldopen' or 'foldclose' twice.
foldinfo_T fi;
if (wlv->filler_todo <= 0 || wlv->foldinfo.fi_lnum < wlv->lnum) {
fi = wlv->foldinfo;
} else {
fi = (foldinfo_T){ 0 };
}
fill_foldcolumn(wp, fi, wlv->lnum, attr, fdc, &wlv->off, NULL, NULL);
}
}

View File

@@ -2257,6 +2257,104 @@ describe('folded lines', function()
end
end)
it('virt_lines above line where fold begins do not duplicate foldcolumn', function()
fn.setline(1, 'line 1')
fn.setline(2, 'line 2')
fn.setline(3, 'line 3')
fn.setline(4, 'line 4')
local ns = api.nvim_create_namespace('ns')
api.nvim_buf_set_extmark(
0,
ns,
1,
0,
{ virt_lines_above = true, virt_lines = { { { 'above line 2' } } } }
)
api.nvim_buf_set_extmark(0, ns, 2, 0, { virt_lines = { { { 'below line 3' } } } })
command('set foldcolumn=1')
feed('jzfl')
feed('2jzfl')
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|*7
[3:---------------------------------------------]|
## grid 2
{7: }line 1 |
{7: }above line 2 |
{7:-}line 2 |
{7: }line 3 |
{7: }below line 3 |
{7:-}^line 4 |
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7: }line 1 |
{7: }above line 2 |
{7:-}line 2 |
{7: }line 3 |
{7: }below line 3 |
{7:-}^line 4 |
{1:~ }|
|
]])
end
end)
it('foldcolumn is not interrupted when virt_lines are inside a fold', function()
fn.setline(1, 'line 1')
fn.setline(2, 'line 2')
fn.setline(3, 'line 3')
fn.setline(4, 'line 4')
local ns = api.nvim_create_namespace('ns')
api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_lines = { { { 'below line 2', '' } } } })
api.nvim_buf_set_extmark(
0,
ns,
2,
0,
{ virt_lines_above = true, virt_lines = { { { 'above line 3', '' } } } }
)
command('set foldcolumn=1')
feed('zf2j')
feed('zo')
if multigrid then
screen:expect([[
## grid 1
[2:---------------------------------------------]|*7
[3:---------------------------------------------]|
## grid 2
{7:-}^line 1 |
{7:│}line 2 |
{7:│}below line 2 |
{7:│}above line 3 |
{7:│}line 3 |
{7: }line 4 |
{1:~ }|
## grid 3
|
]])
else
screen:expect([[
{7:-}^line 1 |
{7:│}line 2 |
{7:│}below line 2 |
{7:│}above line 3 |
{7:│}line 3 |
{7: }line 4 |
{1:~ }|
|
]])
end
end)
it('Folded and Visual highlights are combined #19691', function()
command('hi! Visual guifg=NONE guibg=Red')
insert([[