commit 1d9990daac37810ebfd20b49fa57e39e6806f4f6
parent 9b11746d80905c54d8e99e919a5b8ad195e616db
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 10 May 2025 10:36:33 +0800
fix(folds): avoid unnecessary loop with horizontal scrolling (#33932)
Fix #33931
Diffstat:
2 files changed, 104 insertions(+), 5 deletions(-)
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
@@ -1475,7 +1475,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
? (startrow == 0 ? wp->w_skipcol : 0)
: wp->w_leftcol;
- if (start_col > 0 && col_rows == 0) {
+ if (has_foldtext) {
+ wlv.vcol = start_col;
+ } else if (start_col > 0 && col_rows == 0) {
char *prev_ptr = ptr;
CharSize cs = { 0 };
@@ -1518,12 +1520,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
// - 'cuc' is set, or
// - 'colorcolumn' is set, or
// - 'virtualedit' is set, or
- // - the visual mode is active,
+ // - the visual mode is active, or
+ // - drawing a fold
// the end of the line may be before the start of the displayed part.
if (wlv.vcol < start_col && (wp->w_p_cuc
|| wlv.color_cols
|| virtual_active(wp)
- || (VIsual_active && wp->w_buffer == curwin->w_buffer))) {
+ || (VIsual_active && wp->w_buffer == curwin->w_buffer)
+ || has_fold)) {
wlv.vcol = start_col;
}
@@ -1935,6 +1939,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
wlv.n_extra = (int)strlen(wlv.p_extra);
if (wlv.p_extra != buf_fold) {
+ assert(foldtext_free == NULL);
foldtext_free = wlv.p_extra;
}
wlv.sc_extra = NUL;
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
@@ -1593,6 +1593,45 @@ describe('folded lines', function()
|
]])
end
+
+ eq({ 0, 1, 2, 0, 2 }, fn.getcurpos())
+ api.nvim_input_mouse('left', 'press', '', multigrid and 2 or 0, 2, 4)
+ eq({ 0, 3, 2, 0, 2 }, fn.getcurpos())
+ feed('2k')
+ eq({ 0, 1, 2, 0, 2 }, fn.getcurpos())
+
+ api.nvim_set_option_value('foldtext', "'αβγ'", { win = 0 })
+ -- No crash or memory leak when scrolling beyond end of folded line #33931
+ fn.append('$', ('!'):rep(100))
+ feed('G$')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:---------------------------------------------]|*7
+ [3:---------------------------------------------]|
+ ## grid 2
+ {8: 1 } |
+ {8: 2 } |
+ {8: 3 }{5:αβγ······································}|
+ {8: 5 } |
+ {8: 6 } |
+ {8: 7 }!!!!!!!!!!!!!!!!!!!!^! |
+ {1:~ }|
+ ## grid 3
+ |
+ ]])
+ else
+ screen:expect([[
+ {8: 1 } |
+ {8: 2 } |
+ {8: 3 }{5:αβγ······································}|
+ {8: 5 } |
+ {8: 6 } |
+ {8: 7 }!!!!!!!!!!!!!!!!!!!!^! |
+ {1:~ }|
+ |
+ ]])
+ end
end)
it('fold attached virtual lines are drawn and scrolled correctly #21837', function()
@@ -2624,8 +2663,6 @@ describe('folded lines', function()
screen:try_resize(30, 7)
insert(content1)
command('hi! CursorLine guibg=NONE guifg=Red gui=NONE')
- command('hi F0 guibg=Red guifg=Black')
- command('hi F1 guifg=White')
command([[syn match Keyword /\<sentence\>/]])
command('hi! Keyword guibg=NONE guifg=Green')
api.nvim_set_option_value('cursorline', true, {})
@@ -2734,6 +2771,63 @@ describe('folded lines', function()
{11:-- VISUAL LINE --} |
]])
end
+
+ api.nvim_set_option_value('rightleft', false, {})
+ api.nvim_set_option_value('wrap', false, {})
+ feed('<Esc>zl')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:------------------------------]|*6
+ [3:------------------------------]|
+ ## grid 2
+ {7: }his is a |
+ {7:- }{12:^alid English }|
+ {7:│+ }{21:entence}{5: composed by·······}|
+ {7:│+ }{5:n his cave.···············}|
+ {1:~ }|*2
+ ## grid 3
+ |
+ ]])
+ else
+ screen:expect([[
+ {7: }his is a |
+ {7:- }{12:^alid English }|
+ {7:│+ }{21:entence}{5: composed by·······}|
+ {7:│+ }{5:n his cave.···············}|
+ {1:~ }|*2
+ |
+ ]])
+ end
+
+ fn.append(0, ('!'):rep(15))
+ feed('gg$zs')
+ if multigrid then
+ screen:expect([[
+ ## grid 1
+ [2:------------------------------]|*6
+ [3:------------------------------]|
+ ## grid 2
+ {7: }{12:^! }|
+ {7: } |
+ {7:- } |
+ {7:│+ }{5:sed by····················}|
+ {7:│+ }{5:··························}|
+ {1:~ }|
+ ## grid 3
+ |
+ ]])
+ else
+ screen:expect([[
+ {7: }{12:^! }|
+ {7: } |
+ {7:- } |
+ {7:│+ }{5:sed by····················}|
+ {7:│+ }{5:··························}|
+ {1:~ }|
+ |
+ ]])
+ end
end)
end