mirror of
https://github.com/neovim/neovim.git
synced 2025-09-06 03:18:16 +00:00
Merge pull request #22108 from luukvbaal/statuscolumn
perf(column): only build fold/sign column when present in 'statuscolumn'
This commit is contained in:
@@ -337,36 +337,6 @@ struct mapblock {
|
|||||||
bool m_replace_keycodes; // replace keycodes in result of expression
|
bool m_replace_keycodes; // replace keycodes in result of expression
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Used for highlighting in the status line.
|
|
||||||
typedef struct stl_hlrec stl_hlrec_t;
|
|
||||||
struct stl_hlrec {
|
|
||||||
char *start;
|
|
||||||
int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Used for building the status line.
|
|
||||||
typedef struct stl_item stl_item_t;
|
|
||||||
struct stl_item {
|
|
||||||
// Where the item starts in the status line output buffer
|
|
||||||
char *start;
|
|
||||||
// Function to run for ClickFunc items.
|
|
||||||
char *cmd;
|
|
||||||
// The minimum width of the item
|
|
||||||
int minwid;
|
|
||||||
// The maximum width of the item
|
|
||||||
int maxwid;
|
|
||||||
enum {
|
|
||||||
Normal,
|
|
||||||
Empty,
|
|
||||||
Group,
|
|
||||||
Separate,
|
|
||||||
Highlight,
|
|
||||||
TabPage,
|
|
||||||
ClickFunc,
|
|
||||||
Trunc,
|
|
||||||
} type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// values for b_syn_spell: what to do with toplevel text
|
// values for b_syn_spell: what to do with toplevel text
|
||||||
#define SYNSPL_DEFAULT 0 // spell check if @Spell not defined
|
#define SYNSPL_DEFAULT 0 // spell check if @Spell not defined
|
||||||
#define SYNSPL_TOP 1 // spell check toplevel text
|
#define SYNSPL_TOP 1 // spell check toplevel text
|
||||||
@@ -1420,26 +1390,6 @@ struct window_S {
|
|||||||
size_t w_statuscol_click_defs_size;
|
size_t w_statuscol_click_defs_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Struct to hold info for 'statuscolumn'
|
|
||||||
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 + 1]; ///< attributes used for signs
|
|
||||||
int truncate; ///< truncated width
|
|
||||||
bool draw; ///< draw statuscolumn or not
|
|
||||||
char fold_text[9 * 4 + 1]; ///< 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
|
/// Macros defined in Vim, but not in Neovim
|
||||||
// uncrustify:off
|
// uncrustify:off
|
||||||
#define CHANGEDTICK(buf) \
|
#define CHANGEDTICK(buf) \
|
||||||
|
@@ -404,37 +404,10 @@ static int get_sign_attrs(buf_T *buf, linenr_T lnum, SignTextAttrs *sattrs, int
|
|||||||
/// the start of the buffer line "lnum" and once for the wrapped lines.
|
/// the start of the buffer line "lnum" and once for the wrapped lines.
|
||||||
///
|
///
|
||||||
/// @param[out] stcp Status column attributes
|
/// @param[out] stcp Status column attributes
|
||||||
static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines,
|
static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T *stcp)
|
||||||
int cul_attr, int sign_num_attr, int sign_cul_attr, statuscol_T *stcp,
|
|
||||||
foldinfo_T foldinfo, SignTextAttrs *sattrs)
|
|
||||||
{
|
{
|
||||||
long relnum = -1;
|
// When called for the first non-filler row of line "lnum" set num v:vars
|
||||||
bool use_cul = use_cursor_line_sign(wp, lnum);
|
long relnum = virtnum == 0 ? labs(get_cursor_rel_lnum(wp, lnum)) : -1;
|
||||||
int virtnum = row - startrow - filler_lines;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
: get_line_number_attr(wp, lnum, row, startrow, filler_lines);
|
|
||||||
}
|
|
||||||
// When called for the first non-filler row of line "lnum" set num v:vars and fold column
|
|
||||||
if (virtnum == 0) {
|
|
||||||
relnum = labs(get_cursor_rel_lnum(wp, lnum));
|
|
||||||
if (compute_foldcolumn(wp, 0)) {
|
|
||||||
size_t n = fill_foldcolumn(stcp->fold_text, wp, foldinfo, lnum);
|
|
||||||
stcp->fold_text[n] = NUL;
|
|
||||||
stcp->fold_attr = win_hl_attr(wp, use_cul ? HLF_CLF : HLF_FC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Make sure to clear->set->clear sign column for filler->first->wrapped lines
|
|
||||||
int i = 0;
|
|
||||||
for (; i < wp->w_scwidth; i++) {
|
|
||||||
SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, sattrs, wp->w_scwidth);
|
|
||||||
stcp->sign_text[i] = sattr && sattr->text ? sattr->text : " ";
|
|
||||||
stcp->sign_attr[i] = sattr ? (use_cul && sign_cul_attr ? sign_cul_attr : sattr->hl_attr_id)
|
|
||||||
: win_hl_attr(wp, use_cul ? HLF_CLS : HLF_SC);
|
|
||||||
}
|
|
||||||
stcp->sign_text[i] = NULL;
|
|
||||||
|
|
||||||
// When a buffer's line count has changed, make a best estimate for the full
|
// 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
|
// width of the status column by building with "w_nrwidth_line_count". Add
|
||||||
@@ -496,8 +469,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st
|
|||||||
if (stcp->textp + *n_extrap < stcp->text_end) {
|
if (stcp->textp + *n_extrap < stcp->text_end) {
|
||||||
int hl = stcp->hlrecp->userhl;
|
int hl = stcp->hlrecp->userhl;
|
||||||
stcp->textp = stcp->hlrecp->start;
|
stcp->textp = stcp->hlrecp->start;
|
||||||
stcp->cur_attr = hl < 0 ? syn_id2attr(-stcp->hlrecp->userhl)
|
stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : hl > 0 ? hl : stcp->num_attr;
|
||||||
: hl > 0 ? hl : stcp->num_attr;
|
|
||||||
stcp->hlrecp++;
|
stcp->hlrecp++;
|
||||||
*draw_state = WL_STC - 1;
|
*draw_state = WL_STC - 1;
|
||||||
}
|
}
|
||||||
@@ -1208,7 +1180,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
if (*wp->w_p_stc != NUL) {
|
if (*wp->w_p_stc != NUL) {
|
||||||
// Draw the 'statuscolumn' if option is set.
|
// Draw the 'statuscolumn' if option is set.
|
||||||
statuscol.draw = true;
|
statuscol.draw = true;
|
||||||
|
statuscol.sattrs = sattrs;
|
||||||
|
statuscol.foldinfo = foldinfo;
|
||||||
statuscol.width = win_col_off(wp);
|
statuscol.width = win_col_off(wp);
|
||||||
|
statuscol.use_cul = use_cursor_line_sign(wp, lnum);
|
||||||
|
statuscol.sign_cul_attr = statuscol.use_cul ? sign_cul_attr : 0;
|
||||||
|
statuscol.num_attr = sign_num_attr ? sign_num_attr
|
||||||
|
: get_line_number_attr(wp, lnum, row, startrow, filler_lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sign_idx = 0;
|
int sign_idx = 0;
|
||||||
@@ -1354,8 +1332,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
|||||||
// Draw the 'statuscolumn' if option is set.
|
// Draw the 'statuscolumn' if option is set.
|
||||||
if (statuscol.draw) {
|
if (statuscol.draw) {
|
||||||
if (statuscol.textp == NULL) {
|
if (statuscol.textp == NULL) {
|
||||||
get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr,
|
get_statuscol_str(wp, lnum, row - startrow - filler_lines, &statuscol);
|
||||||
sign_num_attr, sign_cul_attr, &statuscol, foldinfo, sattrs);
|
|
||||||
if (wp->w_redr_statuscol) {
|
if (wp->w_redr_statuscol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -9,17 +9,6 @@
|
|||||||
#include "nvim/pos.h"
|
#include "nvim/pos.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
|
|
||||||
// Info used to pass info about a fold from the fold-detection code to the
|
|
||||||
// code that displays the foldcolumn.
|
|
||||||
typedef struct foldinfo {
|
|
||||||
linenr_T fi_lnum; // line number where fold starts
|
|
||||||
int fi_level; // level of the fold; when this is zero the
|
|
||||||
// other fields are invalid
|
|
||||||
int fi_low_level; // lowest fold level that starts in the same
|
|
||||||
// line
|
|
||||||
linenr_T fi_lines;
|
|
||||||
} foldinfo_T;
|
|
||||||
|
|
||||||
EXTERN int disable_fold_update INIT(= 0);
|
EXTERN int disable_fold_update INIT(= 0);
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
17
src/nvim/fold_defs.h
Normal file
17
src/nvim/fold_defs.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef NVIM_FOLD_DEFS_H
|
||||||
|
#define NVIM_FOLD_DEFS_H
|
||||||
|
|
||||||
|
#include "nvim/pos.h"
|
||||||
|
|
||||||
|
// Info used to pass info about a fold from the fold-detection code to the
|
||||||
|
// code that displays the foldcolumn.
|
||||||
|
typedef struct foldinfo {
|
||||||
|
linenr_T fi_lnum; // line number where fold starts
|
||||||
|
int fi_level; // level of the fold; when this is zero the
|
||||||
|
// other fields are invalid
|
||||||
|
int fi_low_level; // lowest fold level that starts in the same
|
||||||
|
// line
|
||||||
|
linenr_T fi_lines;
|
||||||
|
} foldinfo_T;
|
||||||
|
|
||||||
|
#endif // NVIM_FOLD_DEFS_H
|
@@ -37,7 +37,7 @@
|
|||||||
#include "nvim/path.h"
|
#include "nvim/path.h"
|
||||||
#include "nvim/pos.h"
|
#include "nvim/pos.h"
|
||||||
#include "nvim/screen.h"
|
#include "nvim/screen.h"
|
||||||
#include "nvim/sign_defs.h"
|
#include "nvim/sign.h"
|
||||||
#include "nvim/statusline.h"
|
#include "nvim/statusline.h"
|
||||||
#include "nvim/strings.h"
|
#include "nvim/strings.h"
|
||||||
#include "nvim/types.h"
|
#include "nvim/types.h"
|
||||||
@@ -1637,20 +1637,40 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n
|
|||||||
if (stcp == NULL) {
|
if (stcp == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fold = opt == STL_FOLDCOL;
|
bool fold = opt == STL_FOLDCOL;
|
||||||
|
int width = fold ? (compute_foldcolumn(wp, 0) > 0) : wp->w_scwidth;
|
||||||
|
|
||||||
|
if (width == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *p;
|
||||||
|
if (fold) {
|
||||||
|
size_t n = fill_foldcolumn(out_p, wp, stcp->foldinfo, (linenr_T)get_vim_var_nr(VV_LNUM));
|
||||||
|
stl_items[curitem].minwid = win_hl_attr(wp, stcp->use_cul ? HLF_CLF : HLF_FC);
|
||||||
|
p = out_p;
|
||||||
|
p[n] = NUL;
|
||||||
|
}
|
||||||
|
|
||||||
*buf_tmp = NUL;
|
*buf_tmp = NUL;
|
||||||
for (int i = 0; i <= SIGN_SHOW_MAX; i++) {
|
varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM);
|
||||||
char *p = fold ? stcp->fold_text : stcp->sign_text[i];
|
for (int i = 0; i <= width; i++) {
|
||||||
if ((!p || !*p) && *buf_tmp == NUL) {
|
if (i == width) {
|
||||||
break;
|
if (*buf_tmp == NUL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stl_items[curitem].minwid = 0;
|
||||||
|
} else if (!fold) {
|
||||||
|
SignTextAttrs *sattr = virtnum ? NULL : sign_get_attr(i, stcp->sattrs, wp->w_scwidth);
|
||||||
|
p = sattr && sattr->text ? sattr->text : " ";
|
||||||
|
stl_items[curitem].minwid = sattr ? stcp->sign_cul_attr ? stcp->sign_cul_attr
|
||||||
|
: sattr->hl_attr_id
|
||||||
|
: win_hl_attr(wp, stcp->use_cul ? HLF_CLS : HLF_SC);
|
||||||
}
|
}
|
||||||
stl_items[curitem].type = Highlight;
|
stl_items[curitem].type = Highlight;
|
||||||
stl_items[curitem].start = out_p + strlen(buf_tmp);
|
stl_items[curitem].start = out_p + strlen(buf_tmp);
|
||||||
stl_items[curitem].minwid = !p || (fold && i) ? 0 : fold ? stcp->fold_attr
|
|
||||||
: stcp->sign_attr[i];
|
|
||||||
curitem++;
|
curitem++;
|
||||||
if (!p || (fold && i)) {
|
if (i == width) {
|
||||||
str = buf_tmp;
|
str = buf_tmp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,10 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "nvim/fold_defs.h"
|
||||||
#include "nvim/macros.h"
|
#include "nvim/macros.h"
|
||||||
|
#include "nvim/os/os_defs.h"
|
||||||
|
#include "nvim/sign_defs.h"
|
||||||
|
|
||||||
/// Status line click definition
|
/// Status line click definition
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -23,4 +26,54 @@ typedef struct {
|
|||||||
const char *start; ///< Location where region starts.
|
const char *start; ///< Location where region starts.
|
||||||
} StlClickRecord;
|
} StlClickRecord;
|
||||||
|
|
||||||
|
/// Used for highlighting in the status line.
|
||||||
|
typedef struct stl_hlrec stl_hlrec_t;
|
||||||
|
struct stl_hlrec {
|
||||||
|
char *start;
|
||||||
|
int userhl; // 0: no HL, 1-9: User HL, < 0 for syn ID
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Used for building the status line.
|
||||||
|
typedef struct stl_item stl_item_t;
|
||||||
|
struct stl_item {
|
||||||
|
// Where the item starts in the status line output buffer
|
||||||
|
char *start;
|
||||||
|
// Function to run for ClickFunc items.
|
||||||
|
char *cmd;
|
||||||
|
// The minimum width of the item
|
||||||
|
int minwid;
|
||||||
|
// The maximum width of the item
|
||||||
|
int maxwid;
|
||||||
|
enum {
|
||||||
|
Normal,
|
||||||
|
Empty,
|
||||||
|
Group,
|
||||||
|
Separate,
|
||||||
|
Highlight,
|
||||||
|
TabPage,
|
||||||
|
ClickFunc,
|
||||||
|
Trunc,
|
||||||
|
} type;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Struct to hold info for 'statuscolumn'
|
||||||
|
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 sign_cul_attr; ///< cursorline sign attr
|
||||||
|
int truncate; ///< truncated width
|
||||||
|
bool draw; ///< whether to draw the statuscolumn
|
||||||
|
bool use_cul; ///< whether to use cursorline attrs
|
||||||
|
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
|
||||||
|
foldinfo_T foldinfo; ///< fold information
|
||||||
|
SignTextAttrs *sattrs; ///< sign attributes
|
||||||
|
};
|
||||||
|
|
||||||
#endif // NVIM_STATUSLINE_DEFS_H
|
#endif // NVIM_STATUSLINE_DEFS_H
|
||||||
|
@@ -456,7 +456,7 @@ describe('statuscolumn', function()
|
|||||||
14 aaaaa |
|
14 aaaaa |
|
||||||
|
|
|
|
||||||
]])
|
]])
|
||||||
command('set stc=') -- also for the default sign column
|
command('set stc=') -- also for the default fold column
|
||||||
screen:expect_unchanged()
|
screen:expect_unchanged()
|
||||||
-- 'statuscolumn' is not too wide with custom (bogus) fold column
|
-- 'statuscolumn' is not too wide with custom (bogus) fold column
|
||||||
command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]])
|
command([[set stc=%{foldlevel(v:lnum)>0?repeat('-',foldlevel(v:lnum)):''}%=%l\ ]])
|
||||||
|
Reference in New Issue
Block a user