From 01e273c340b5e51b593900c8feb894ba9a46c366 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 24 Jul 2023 15:18:24 +0800 Subject: [PATCH] fix(statuscolumn): don't update clicks if current width is 0 (#24459) --- src/nvim/drawline.c | 2 +- src/nvim/statusline.c | 9 +++++---- test/functional/ui/statuscolumn_spec.lua | 17 +++++++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 53e6b157c6..d0cd11ccf3 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -686,7 +686,7 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T int width = build_statuscol_str(wp, lnum, relnum, stcp); // Force a redraw in case of error or when truncated if (*wp->w_p_stc == NUL || (stcp->truncate > 0 && wp->w_nrwidth < MAX_NUMBERWIDTH)) { - if (stcp->truncate) { // Avoid truncating 'statuscolumn' + if (stcp->truncate > 0) { // Avoid truncating 'statuscolumn' wp->w_nrwidth = MIN(MAX_NUMBERWIDTH, wp->w_nrwidth + stcp->truncate); wp->w_nrwidth_width = wp->w_nrwidth; } else { // 'statuscolumn' reset due to error diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index b01febc18c..b1c7cbb8dc 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -890,7 +890,9 @@ void draw_tabline(void) /// @return The width of the built status column string for line "lnum" int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, statuscol_T *stcp) { - bool fillclick = relnum >= 0 && lnum == wp->w_topline; + // Only update click definitions once per window per redraw. + // Don't update when current width is 0, since it will be redrawn again if not empty. + const bool fillclick = relnum >= 0 && stcp->width > 0 && lnum == wp->w_topline; if (relnum >= 0) { set_vim_var_nr(VV_LNUM, lnum); @@ -903,7 +905,6 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, statuscol_T *stcp stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); - // Only update click definitions once per window per redraw if (fillclick) { stl_clear_click_defs(wp->w_statuscol_click_defs, wp->w_statuscol_click_defs_size); wp->w_statuscol_click_defs = stl_alloc_click_defs(wp->w_statuscol_click_defs, stcp->width, @@ -1973,8 +1974,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n int width = vim_strsize(out); // Return truncated width for 'statuscolumn' - if (stcp != NULL && width > maxwidth) { - stcp->truncate = width - maxwidth; + if (stcp != NULL && width > stcp->width) { + stcp->truncate = width - stcp->width; } if (maxwidth > 0 && width > maxwidth) { // Result is too long, must truncate somewhere. diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 6a1c20ff67..35cd479bb9 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -9,6 +9,7 @@ local exec_lua = helpers.exec_lua local feed = helpers.feed local meths = helpers.meths local pcall_err = helpers.pcall_err +local assert_alive = helpers.assert_alive local mousemodels = { "extend", "popup", "popup_setpos" } @@ -577,8 +578,8 @@ describe('statuscolumn', function() end) end - it('click labels do not leak memory', function() - command([[ + it('click labels do not leak memory #21878', function() + exec([[ set laststatus=2 setlocal statuscolumn=%0@MyClickFunc@abcd%T 4vsplit @@ -590,6 +591,18 @@ describe('statuscolumn', function() ]]) end) + it('click labels do not crash when initial width is 0 #24428', function() + exec([[ + set nonumber + bwipe! + setlocal statuscolumn=abcd + redraw + setlocal statuscolumn=%0@MyClickFunc@abcd%T + redraw + ]]) + assert_alive() + end) + it('works with foldcolumn', function() -- Fits maximum multibyte foldcolumn #21759 command([[set stc=%C%=%l\ fdc=9 fillchars=foldsep:ð’€€]])