From 204a8b17c8ebab1619cc47a920a06dcc348d75f7 Mon Sep 17 00:00:00 2001 From: luukvbaal <31730729+luukvbaal@users.noreply.github.com> Date: Sat, 18 Mar 2023 12:44:44 +0100 Subject: fix(column): rebuild status column when sign column is invalidated (#22690) * fix(column): rebuild status column when sign column is invalidated Problem: When implementing a custom sign column through `'statuscolumn'`, the status column is not properly rebuilt when the sign column width changes. Solution: Force a rebuild of the status column when the sign column width is invalidated. * test(column): 'statuscolumn' has correct width when (un)placing signs --- src/nvim/buffer.c | 3 +++ src/nvim/option.c | 9 +++++---- src/nvim/statusline.c | 19 +++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index cedbadbaf3..9a757960af 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -4109,6 +4109,7 @@ void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) if (!buf->b_signcols.sentinel) { buf->b_signcols.valid = false; + invalidate_statuscol(NULL, buf); return; } @@ -4117,6 +4118,7 @@ void buf_signcols_del_check(buf_T *buf, linenr_T line1, linenr_T line2) if (sent >= line1 && sent <= line2) { // Only invalidate when removing signs at the sentinel line. buf->b_signcols.valid = false; + invalidate_statuscol(NULL, buf); } } @@ -4132,6 +4134,7 @@ void buf_signcols_add_check(buf_T *buf, sign_entry_T *added) if (!added || !buf->b_signcols.sentinel) { buf->b_signcols.valid = false; + invalidate_statuscol(NULL, buf); return; } diff --git a/src/nvim/option.c b/src/nvim/option.c index 5fe6e18155..02b32b1fe5 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2176,10 +2176,8 @@ static char *set_bool_option(const int opt_idx, char *const varp, const int valu if (curwin->w_p_spell) { errmsg = did_set_spelllang(curwin); } - } else if ((int *)varp == &curwin->w_p_nu && *curwin->w_p_stc != NUL) { - // When 'statuscolumn' is set and 'number' is changed: - curwin->w_nrwidth_line_count = 0; // make sure width is reset - curwin->w_statuscol_line_count = 0; // make sure width is re-estimated + } else if ((int *)varp == &curwin->w_p_nu) { // 'number' + invalidate_statuscol(curwin, NULL); } if ((int *)varp == &curwin->w_p_arab) { @@ -5519,6 +5517,9 @@ int win_signcol_configured(win_T *wp, int *is_fixed) if (*scl == 'n' && (*(scl + 1) == 'o' || (*(scl + 1) == 'u' && (wp->w_p_nu || wp->w_p_rnu)))) { + if (*wp->w_p_stc != NUL) { + buf_signcols(wp->w_buffer, 0); + } return 0; } diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index ca92953b05..a54618205e 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -909,6 +909,25 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, long relnum, statuscol_T *stcp return width; } +/// Force a reset and re-estimation of the status column width. +/// +/// @param wp The window for which to reset the status column (can be NULL if "buf" is not) +/// @param buf The buffer for which to reset the status column (can be NULL) +void invalidate_statuscol(win_T *wp, buf_T *buf) +{ + if (buf != NULL) { + FOR_ALL_WINDOWS_IN_TAB(win, curtab) { + if (*win->w_p_stc != NUL && win->w_buffer == buf) { + win->w_nrwidth_line_count = 0; + win->w_statuscol_line_count = 0; + } + } + } else if (*wp->w_p_stc != NUL) { + wp->w_nrwidth_line_count = 0; // make sure width is reset + wp->w_statuscol_line_count = 0; // make sure width is re-estimated + } +} + /// Build a string from the status line items in "fmt". /// Return length of string in screen cells. /// -- cgit