diff options
-rw-r--r-- | src/nvim/buffer_defs.h | 50 | ||||
-rw-r--r-- | src/nvim/drawline.c | 45 | ||||
-rw-r--r-- | src/nvim/fold.h | 11 | ||||
-rw-r--r-- | src/nvim/fold_defs.h | 17 | ||||
-rw-r--r-- | src/nvim/statusline.c | 38 | ||||
-rw-r--r-- | src/nvim/statusline_defs.h | 53 | ||||
-rw-r--r-- | test/functional/ui/statuscolumn_spec.lua | 2 |
7 files changed, 111 insertions, 105 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index cace4b1364..05901893b9 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -337,36 +337,6 @@ struct mapblock { 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 #define SYNSPL_DEFAULT 0 // spell check if @Spell not defined #define SYNSPL_TOP 1 // spell check toplevel text @@ -1420,26 +1390,6 @@ struct window_S { 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 // uncrustify:off #define CHANGEDTICK(buf) \ diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 3bd55dbe09..a74a5670d1 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -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. /// /// @param[out] stcp Status column attributes -static void get_statuscol_str(win_T *wp, linenr_T lnum, int row, int startrow, int filler_lines, - int cul_attr, int sign_num_attr, int sign_cul_attr, statuscol_T *stcp, - foldinfo_T foldinfo, SignTextAttrs *sattrs) +static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T *stcp) { - long relnum = -1; - bool use_cul = use_cursor_line_sign(wp, lnum); - 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 called for the first non-filler row of line "lnum" set num v:vars + long relnum = virtnum == 0 ? labs(get_cursor_rel_lnum(wp, lnum)) : -1; // 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 @@ -496,8 +469,7 @@ static void get_statuscol_display_info(statuscol_T *stcp, LineDrawState *draw_st 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) - : hl > 0 ? hl : stcp->num_attr; + stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : hl > 0 ? hl : stcp->num_attr; stcp->hlrecp++; *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) { // Draw the 'statuscolumn' if option is set. statuscol.draw = true; + statuscol.sattrs = sattrs; + statuscol.foldinfo = foldinfo; 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; @@ -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. if (statuscol.draw) { if (statuscol.textp == NULL) { - get_statuscol_str(wp, lnum, row, startrow, filler_lines, cul_attr, - sign_num_attr, sign_cul_attr, &statuscol, foldinfo, sattrs); + get_statuscol_str(wp, lnum, row - startrow - filler_lines, &statuscol); if (wp->w_redr_statuscol) { break; } diff --git a/src/nvim/fold.h b/src/nvim/fold.h index ac1e8c9419..cf44cf14c3 100644 --- a/src/nvim/fold.h +++ b/src/nvim/fold.h @@ -9,17 +9,6 @@ #include "nvim/pos.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); #ifdef INCLUDE_GENERATED_DECLARATIONS diff --git a/src/nvim/fold_defs.h b/src/nvim/fold_defs.h new file mode 100644 index 0000000000..c528d25348 --- /dev/null +++ b/src/nvim/fold_defs.h @@ -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 diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 6414b2bb74..9294bef6c2 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -37,7 +37,7 @@ #include "nvim/path.h" #include "nvim/pos.h" #include "nvim/screen.h" -#include "nvim/sign_defs.h" +#include "nvim/sign.h" #include "nvim/statusline.h" #include "nvim/strings.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) { break; } - 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; - 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; + varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM); + for (int i = 0; i <= width; i++) { + if (i == width) { + 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].start = out_p + strlen(buf_tmp); - stl_items[curitem].minwid = !p || (fold && i) ? 0 : fold ? stcp->fold_attr - : stcp->sign_attr[i]; curitem++; - if (!p || (fold && i)) { + if (i == width) { str = buf_tmp; break; } diff --git a/src/nvim/statusline_defs.h b/src/nvim/statusline_defs.h index eac9dfd690..6835d62cdd 100644 --- a/src/nvim/statusline_defs.h +++ b/src/nvim/statusline_defs.h @@ -3,7 +3,10 @@ #include <stddef.h> +#include "nvim/fold_defs.h" #include "nvim/macros.h" +#include "nvim/os/os_defs.h" +#include "nvim/sign_defs.h" /// Status line click definition typedef struct { @@ -23,4 +26,54 @@ typedef struct { const char *start; ///< Location where region starts. } 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 diff --git a/test/functional/ui/statuscolumn_spec.lua b/test/functional/ui/statuscolumn_spec.lua index 3233e6cd19..287686cf37 100644 --- a/test/functional/ui/statuscolumn_spec.lua +++ b/test/functional/ui/statuscolumn_spec.lua @@ -456,7 +456,7 @@ describe('statuscolumn', function() 14 aaaaa | | ]]) - command('set stc=') -- also for the default sign column + command('set stc=') -- also for the default fold 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\ ]]) |