diff options
author | luukvbaal <31730729+luukvbaal@users.noreply.github.com> | 2023-02-02 10:35:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-02 09:35:51 +0000 |
commit | 64fa75a86a9e2e301e884e21911d71688fc8f122 (patch) | |
tree | cd9286f4df6659bc4432403b285e46ad9bdfcd00 | |
parent | 2c5906b55bb6092121f4d3b032d5449da7675c2b (diff) | |
download | rneovim-64fa75a86a9e2e301e884e21911d71688fc8f122.tar.gz rneovim-64fa75a86a9e2e301e884e21911d71688fc8f122.tar.bz2 rneovim-64fa75a86a9e2e301e884e21911d71688fc8f122.zip |
fix(column): estimate 'statuscolumn' width appropriately
Problem: The 'statuscolumn' width is being estimated without the
proper context. In particular, this resulted in the fact
that a custom fold column could be included in the estimated
`number_width()`, and doubly added when actually drawing the
statuscolumn due to `win_col_off()` also adding the
`'foldcolumn'` width. Resulting in a status column that is
`'foldcolumn'` cells wider than necessary.
Solution: Estimate 'statuscolumn' width in `get_statuscol_str()` when
a buffer's line count has changed.
-rw-r--r-- | src/nvim/buffer_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/drawline.c | 13 | ||||
-rw-r--r-- | src/nvim/screen.c | 11 | ||||
-rw-r--r-- | test/functional/ui/statuscolumn_spec.lua | 21 |
4 files changed, 36 insertions, 10 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index f01edd1ad2..4c99191170 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -1392,6 +1392,7 @@ struct window_S { int w_prev_fraction_row; linenr_T w_nrwidth_line_count; // line count when ml_nrwidth_width was computed. + linenr_T w_statuscol_line_count; // line count when 'statuscolumn' width was computed. int w_nrwidth_width; // nr of chars to print line count. qf_info_T *w_llist; // Location list for this window diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index e24d86b353..01ff207c2b 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -412,7 +412,6 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i bool use_cul = use_cursor_line_sign(wp, lnum); int virtnum = row - startrow - filler_lines; - set_vim_var_nr(VV_VIRTNUM, virtnum); // When called the first time for line "lnum" set num_attr if (stcp->num_attr == 0) { stcp->num_attr = sign_num_attr ? sign_num_attr @@ -437,6 +436,18 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i } stcp->sign_text[i] = NULL; + // When a buffer's line count has changed, make a best estimate for the full + // width of the status column by building with "w_nrwidth_line_count". Add + // potentially truncated width and rebuild before drawing anything. + if (wp->w_statuscol_line_count != wp->w_nrwidth_line_count) { + wp->w_statuscol_line_count = wp->w_nrwidth_line_count; + set_vim_var_nr(VV_VIRTNUM, 0); + build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, stcp->width, + ' ', stcp->text, &stcp->hlrec, stcp); + stcp->width += stcp->truncate; + } + set_vim_var_nr(VV_VIRTNUM, virtnum); + int width = build_statuscol_str(wp, lnum, relnum, stcp->width, ' ', stcp->text, &stcp->hlrec, stcp); // Force a redraw in case of error or when truncated diff --git a/src/nvim/screen.c b/src/nvim/screen.c index ebff52cd69..05da6e0ef1 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -768,7 +768,6 @@ void comp_col(void) /// Otherwise it depends on 'numberwidth' and the line count. int number_width(win_T *wp) { - int n; linenr_T lnum; if (wp->w_p_rnu && !wp->w_p_nu) { @@ -784,17 +783,13 @@ int number_width(win_T *wp) } wp->w_nrwidth_line_count = lnum; - // make best estimate for 'statuscolumn' + // reset for 'statuscolumn' if (*wp->w_p_stc != NUL) { - char buf[MAXPATHL]; - wp->w_nrwidth_width = 0; - n = build_statuscol_str(wp, lnum, 0, 0, NUL, buf, NULL, NULL); - n = MAX(n, (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw); - wp->w_nrwidth_width = MIN(n, MAX_NUMBERWIDTH); + wp->w_nrwidth_width = (wp->w_p_nu || wp->w_p_rnu) * (int)wp->w_p_nuw; return wp->w_nrwidth_width; } - n = 0; + int n = 0; do { lnum /= 10; n++; diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index ae3b95fb0f..3233e6cd19 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -439,7 +439,7 @@ describe('statuscolumn', function() vim.api.nvim_buf_set_extmark(0, ns, 7, 0, { virt_lines_leftcol = true, virt_lines = {{{"virt", ""}}} }) ]]) - feed('lh') -- force update wcol/row + feed('lh') -- force update cursor row screen:expect([[ 4 aaaaa | 5 aaaaa | @@ -458,5 +458,24 @@ describe('statuscolumn', function() ]]) command('set stc=') -- also for the default sign column screen:expect_unchanged() + -- 'statuscolumn' is not too wide with custom (bogus) fold column + command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]]) + feed('Gd10Ggg<C-l>') + screen:expect([[ + 1 ^aaaaa | + 2 aaaaa | + 3 aaaaa | + 4 aaaaa | + 5 aaaaa | + 6 aaaaa | + 7 aaaaa | + virt | + ---------8 aaaaa | + virt | + ---------9 aaaaa | + ~ | + ~ | + | + ]]) end) end) |