mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
fix(statuscolumn): fix crashes and clang/PVS warnings (#21725)
This commit is contained in:
parent
870ca1de52
commit
9b1112cf48
@ -1419,20 +1419,20 @@ struct window_S {
|
||||
typedef struct statuscol statuscol_T;
|
||||
|
||||
struct statuscol {
|
||||
int width; // width of the status column
|
||||
int cur_attr; // current attributes in text
|
||||
int num_attr; // attributes used for line number
|
||||
int fold_attr; // attributes used for fold column
|
||||
int sign_attr[SIGN_SHOW_MAX]; // attributes used for signs
|
||||
int truncate; // truncated width
|
||||
bool draw; // draw statuscolumn or not
|
||||
char fold_text[10]; // text in fold column (%C)
|
||||
char *sign_text[SIGN_SHOW_MAX]; // text in sign column (%s)
|
||||
char text[MAXPATHL]; // text in status column
|
||||
char *textp; // current position in text
|
||||
size_t text_len; // length of text
|
||||
stl_hlrec_t *hlrec; // highlight groups
|
||||
stl_hlrec_t *hlrecp; // current highlight group
|
||||
int width; ///< width of the status column
|
||||
int cur_attr; ///< current attributes in text
|
||||
int num_attr; ///< attributes used for line number
|
||||
int fold_attr; ///< attributes used for fold column
|
||||
int sign_attr[SIGN_SHOW_MAX + 1]; ///< attributes used for signs
|
||||
int truncate; ///< truncated width
|
||||
bool draw; ///< draw statuscolumn or not
|
||||
char fold_text[10]; ///< text in fold column (%C)
|
||||
char *sign_text[SIGN_SHOW_MAX + 1]; ///< text in sign column (%s)
|
||||
char text[MAXPATHL]; ///< text in status column
|
||||
char *textp; ///< current position in text
|
||||
char *text_end; ///< end of text (the NUL byte)
|
||||
stl_hlrec_t *hlrec; ///< highlight groups
|
||||
stl_hlrec_t *hlrecp; ///< current highlight group
|
||||
};
|
||||
|
||||
/// Macros defined in Vim, but not in Neovim
|
||||
|
@ -450,14 +450,13 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, i
|
||||
stcp->textp = stcp->text;
|
||||
stcp->hlrecp = stcp->hlrec;
|
||||
stcp->cur_attr = stcp->num_attr;
|
||||
stcp->text_len = strlen(stcp->text);
|
||||
stcp->text_end = stcp->text + strlen(stcp->text);
|
||||
|
||||
int fill = stcp->width - width;
|
||||
if (fill > 0) {
|
||||
// Fill up with ' '
|
||||
memset(&stcp->text[stcp->text_len], ' ', (size_t)fill);
|
||||
stcp->text_len += (size_t)fill;
|
||||
stcp->text[stcp->text_len] = NUL;
|
||||
memset(stcp->text_end, ' ', (size_t)fill);
|
||||
*(stcp->text_end += fill) = NUL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,10 +475,9 @@ static void get_statuscol_display_info(LineDrawState *draw_state, int *char_attr
|
||||
*draw_state = WL_STC;
|
||||
*char_attr = stcp->cur_attr;
|
||||
*pp_extra = stcp->textp;
|
||||
*n_extrap = stcp->hlrecp->start ? (int)(stcp->hlrecp->start - stcp->textp)
|
||||
: (int)strlen(*pp_extra);
|
||||
*n_extrap = (int)((stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end) - stcp->textp);
|
||||
// Prepare for next highlight section if not yet at the end
|
||||
if (stcp->textp + *n_extrap < stcp->text + stcp->text_len) {
|
||||
if (stcp->textp + *n_extrap < stcp->text_end) {
|
||||
int hl = stcp->hlrecp->userhl;
|
||||
stcp->textp = stcp->hlrecp->start;
|
||||
stcp->cur_attr = hl < 0 ? syn_id2attr(-stcp->hlrecp->userhl)
|
||||
@ -488,7 +486,7 @@ static void get_statuscol_display_info(LineDrawState *draw_state, int *char_attr
|
||||
*draw_state = WL_STC - 1;
|
||||
}
|
||||
// Skip over empty highlight sections
|
||||
} while (*n_extrap == 0 && stcp->textp < stcp->text + stcp->text_len);
|
||||
} while (*n_extrap == 0 && stcp->textp < stcp->text_end);
|
||||
}
|
||||
|
||||
/// Return true if CursorLineNr highlight is to be used for the number column.
|
||||
@ -1328,7 +1326,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
draw_state = WL_STC;
|
||||
// Draw the 'statuscolumn' if option is set.
|
||||
if (statuscol.draw) {
|
||||
if (statuscol.text_len == 0) {
|
||||
if (statuscol.textp == NULL) {
|
||||
get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr,
|
||||
sign_num_attr, sattrs, foldinfo, extra, &statuscol);
|
||||
if (wp->w_redr_statuscol) {
|
||||
@ -2823,7 +2821,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||
if (statuscol.draw) {
|
||||
if (row == startrow + 1 || row == startrow + filler_lines) {
|
||||
// Re-evaluate 'statuscolumn' for the first wrapped row and non filler line
|
||||
statuscol.text_len = 0;
|
||||
statuscol.textp = NULL;
|
||||
} else { // Otherwise just reset the text/hlrec pointers
|
||||
statuscol.textp = statuscol.text;
|
||||
statuscol.hlrecp = statuscol.hlrec;
|
||||
|
@ -1110,7 +1110,7 @@ retnomove:
|
||||
? wp->w_winbar_height != 0
|
||||
: false;
|
||||
|
||||
on_statuscol = grid == (col < win_col_off(wp))
|
||||
on_statuscol = (grid == (col < win_col_off(wp)))
|
||||
? *wp->w_p_stc != NUL
|
||||
: false;
|
||||
|
||||
|
@ -1502,7 +1502,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
|
||||
|
||||
case STL_LINE:
|
||||
// Overload %l with v:lnum for 'statuscolumn'
|
||||
num = strcmp(opt_name, "statuscolumn") == 0 ? get_vim_var_nr(VV_LNUM)
|
||||
num = opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0 ? get_vim_var_nr(VV_LNUM)
|
||||
: (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) ? 0L : (long)(wp->w_cursor.lnum);
|
||||
break;
|
||||
|
||||
@ -1602,7 +1602,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
|
||||
case STL_ROFLAG:
|
||||
case STL_ROFLAG_ALT:
|
||||
// Overload %r with v:relnum for 'statuscolumn'
|
||||
if (strcmp(opt_name, "statuscolumn") == 0) {
|
||||
if (opt_name != NULL && strcmp(opt_name, "statuscolumn") == 0) {
|
||||
num = get_vim_var_nr(VV_RELNUM);
|
||||
} else {
|
||||
itemisflag = true;
|
||||
@ -1628,7 +1628,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
|
||||
|
||||
bool fold = opt == STL_FOLDCOL;
|
||||
*buf_tmp = NUL;
|
||||
for (int i = 0; i <= 9; i++) {
|
||||
for (int i = 0; i <= SIGN_SHOW_MAX; i++) {
|
||||
char *p = fold ? stcp->fold_text : stcp->sign_text[i];
|
||||
if ((!p || !*p) && *buf_tmp == NUL) {
|
||||
break;
|
||||
|
@ -3126,7 +3126,12 @@ describe('API', function()
|
||||
eq('E539: Illegal character <}>',
|
||||
pcall_err(meths.eval_statusline, '%{%}', {}))
|
||||
end)
|
||||
it('supports %S item', function()
|
||||
it('supports various items', function()
|
||||
eq({ str = '0', width = 1 },
|
||||
meths.eval_statusline('%l', { maxwidth = 5 }))
|
||||
command('set readonly')
|
||||
eq({ str = '[RO]', width = 4 },
|
||||
meths.eval_statusline('%r', { maxwidth = 5 }))
|
||||
local screen = Screen.new(80, 24)
|
||||
screen:attach()
|
||||
command('set showcmd')
|
||||
|
@ -293,6 +293,31 @@ describe('statuscolumn', function()
|
||||
{2: }{1: │ }aaaaaa |
|
||||
|
|
||||
]])
|
||||
-- Up to 9 signs in a line
|
||||
command('set signcolumn=auto:9 foldcolumn=auto')
|
||||
command('sign place 5 line=6 name=piet1 buffer=1')
|
||||
command('sign place 6 line=6 name=piet2 buffer=1')
|
||||
command('sign place 7 line=6 name=piet1 buffer=1')
|
||||
command('sign place 8 line=6 name=piet2 buffer=1')
|
||||
command('sign place 9 line=6 name=piet1 buffer=1')
|
||||
command('sign place 10 line=6 name=piet2 buffer=1')
|
||||
command('sign place 11 line=6 name=piet1 buffer=1')
|
||||
screen:expect([[
|
||||
{2: }{1: 4│>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
{2: }{1: 3│}{0:>!}{1: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
{2: }{1: 2│>>}{0:>!}{1:>>}{0:>!}{1:>>}{0:>!}{1:>>}{0:>!}{1:>> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
{2: }{1: 1│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
{2:+}{1: 0│ }{3:^+-- 1 line: aaaaaaaaaaaaaaaaa}|
|
||||
{2: }{1: 1│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
{2: }{1: 2│ }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{2: }{1: │ }aaaaaaaaaaaaaaaaaaaa |
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('works with \'statuscolumn\' clicks', function()
|
||||
|
Loading…
Reference in New Issue
Block a user