refactor(column): define and use maximum 'statuscolumn' width

Problem:  The maximum 'statuscolumn' width and grow behavior is undocumented.
Solution: Define, use and document the maximum 'statuscolumn' width and grow behavior.
This commit is contained in:
Luuk van Baal
2024-01-01 14:24:48 +01:00
committed by Lewis Russell
parent 444f37fe51
commit fa61e0c047
7 changed files with 32 additions and 26 deletions

View File

@@ -5923,9 +5923,13 @@ A jump table for the options with a short description can be found at |Q_op|.
%s sign column for currently drawn line
%C fold column for currently drawn line
NOTE: To draw the sign and fold columns, their items must be included in
'statuscolumn'. Even when they are not included, the status column width
will adapt to the 'signcolumn' and 'foldcolumn' width.
The 'statuscolumn' width follows that of the default columns and
adapts to the |'numberwidth'|, |'signcolumn'| and |'foldcolumn'| option
values (regardless of whether the sign and fold items are present).
Aditionally, the 'statuscolumn' grows with the size of the evaluated
format string, up to a point (following the maximum size of the default
fold, sign and number columns). Shrinking only happens when the number
of lines in a buffer changes, or the 'statuscolumn' option is set.
The |v:lnum| variable holds the line number to be drawn.
The |v:relnum| variable holds the relative line number to be drawn.

View File

@@ -6359,9 +6359,13 @@ vim.go.sol = vim.go.startofline
--- %s sign column for currently drawn line
--- %C fold column for currently drawn line
---
--- NOTE: To draw the sign and fold columns, their items must be included in
--- 'statuscolumn'. Even when they are not included, the status column width
--- will adapt to the 'signcolumn' and 'foldcolumn' width.
--- The 'statuscolumn' width follows that of the default columns and
--- adapts to the `'numberwidth'`, `'signcolumn'` and `'foldcolumn'` option
--- values (regardless of whether the sign and fold items are present).
--- Aditionally, the 'statuscolumn' grows with the size of the evaluated
--- format string, up to a point (following the maximum size of the default
--- fold, sign and number columns). Shrinking only happens when the number
--- of lines in a buffer changes, or the 'statuscolumn' option is set.
---
--- The `v:lnum` variable holds the line number to be drawn.
--- The `v:relnum` variable holds the relative line number to be drawn.

View File

@@ -563,9 +563,6 @@ static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int
}
/// Build and draw the 'statuscolumn' string for line "lnum" in window "wp".
/// Fill "stcp" with the built status column string and attributes.
///
/// @param[out] stcp Status column attributes
static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int virtnum,
statuscol_T *stcp)
{
@@ -579,11 +576,9 @@ static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int vir
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, buf, stcp);
if (stcp->truncate > 0) {
// Add truncated width to avoid unnecessary redraws
int addwidth = MIN(stcp->truncate, MAX_NUMBERWIDTH - wp->w_nrwidth);
stcp->truncate = 0;
int width = build_statuscol_str(wp, wp->w_nrwidth_line_count, 0, buf, stcp);
if (width > stcp->width) {
int addwidth = MIN(width - stcp->width, MAX_STCWIDTH - stcp->width);
stcp->width += addwidth;
wp->w_nrwidth += addwidth;
wp->w_nrwidth_width = wp->w_nrwidth;
@@ -594,13 +589,13 @@ static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int vir
int width = build_statuscol_str(wp, lnum, relnum, buf, 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 (*wp->w_p_stc == NUL || (width > stcp->width && stcp->width < MAX_STCWIDTH)) {
if (*wp->w_p_stc == NUL) { // 'statuscolumn' reset due to error
wp->w_nrwidth_line_count = 0;
wp->w_nrwidth = (wp->w_p_nu || wp->w_p_rnu) * number_width(wp);
} else { // Avoid truncating 'statuscolumn'
wp->w_nrwidth += MIN(width - stcp->width, MAX_STCWIDTH - stcp->width);
wp->w_nrwidth_width = wp->w_nrwidth;
wp->w_nrwidth = MIN(MAX_NUMBERWIDTH, wp->w_nrwidth + stcp->truncate);
}
wp->w_redr_statuscol = true;
return;

View File

@@ -1,6 +1,7 @@
#pragma once
#include "nvim/macros_defs.h"
#include "nvim/sign_defs.h"
#include "nvim/types_defs.h"
// option_vars.h: definition of global variables for settable options
@@ -785,7 +786,10 @@ EXTERN int p_cdh; ///< 'cdhome'
#define SB_MAX 100000 // Maximum 'scrollback' value.
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth' and 'statuscolumn'
#define MAX_NUMBERWIDTH 20 // used for 'numberwidth'
// Maximum 'statuscolumn' width: number + sign + fold columns
#define MAX_STCWIDTH MAX_NUMBERWIDTH + SIGN_SHOW_MAX * SIGN_WIDTH + 9
#define TABSTOP_MAX 9999

View File

@@ -8021,9 +8021,13 @@ return {
%s sign column for currently drawn line
%C fold column for currently drawn line
NOTE: To draw the sign and fold columns, their items must be included in
'statuscolumn'. Even when they are not included, the status column width
will adapt to the 'signcolumn' and 'foldcolumn' width.
The 'statuscolumn' width follows that of the default columns and
adapts to the |'numberwidth'|, |'signcolumn'| and |'foldcolumn'| option
values (regardless of whether the sign and fold items are present).
Aditionally, the 'statuscolumn' grows with the size of the evaluated
format string, up to a point (following the maximum size of the default
fold, sign and number columns). Shrinking only happens when the number
of lines in a buffer changes, or the 'statuscolumn' option is set.
The |v:lnum| variable holds the line number to be drawn.
The |v:relnum| variable holds the relative line number to be drawn.

View File

@@ -1964,11 +1964,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
// What follows is post-processing to handle alignment and highlighting.
int width = vim_strsize(out);
// Return truncated width for 'statuscolumn'
if (stcp != NULL && width > stcp->width) {
stcp->truncate = width - stcp->width;
}
if (maxwidth > 0 && width > maxwidth) {
if (maxwidth > 0 && width > maxwidth && (!stcp || width > MAX_STCWIDTH)) {
// Result is too long, must truncate somewhere.
int item_idx = 0;
char *trunc_p;

View File

@@ -58,7 +58,6 @@ typedef struct {
int width; ///< width of the status column
int num_attr; ///< default highlight attr
int sign_cul_id; ///< cursorline sign highlight id
int truncate; ///< truncated width
bool draw; ///< whether to draw the statuscolumn
bool use_cul; ///< whether to use cursorline attrs
stl_hlrec_t *hlrec; ///< highlight groups