diff options
Diffstat (limited to 'src/nvim/statusline.c')
-rw-r--r-- | src/nvim/statusline.c | 84 |
1 files changed, 75 insertions, 9 deletions
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 0f28eae0d8..d548c285fb 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -367,8 +367,9 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Make a copy, because the statusline may include a function call that // might change the option value and free the memory. stl = xstrdup(stl); - width = build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, - opt_scope, fillchar, maxwidth, &hltab, &tabtab); + width = build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, opt_scope, + fillchar, maxwidth, &hltab, &tabtab, NULL); + xfree(stl); ewp->w_p_crb = p_crb_save; @@ -867,6 +868,32 @@ void draw_tabline(void) redraw_tabline = false; } +int build_statuscol_str(win_T *wp, bool setnum, bool wrap, linenr_T lnum, long relnum, int maxwidth, + int fillchar, char *buf, stl_hlrec_t **hlrec, statuscol_T *stcp) +{ + if (setnum) { + set_vim_var_nr(VV_LNUM, lnum); + set_vim_var_nr(VV_RELNUM, relnum); + } + set_vim_var_bool(VV_WRAP, wrap); + + StlClickRecord *clickrec; + char *stc = xstrdup(wp->w_p_stc); + int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, "statuscolumn", OPT_LOCAL, + fillchar, maxwidth, hlrec, &clickrec, stcp); + xfree(stc); + + // Allocate and fill click def array if width has changed + if (wp->w_status_click_defs_size != (size_t)width) { + stl_clear_click_defs(wp->w_statuscol_click_defs, wp->w_statuscol_click_defs_size); + wp->w_statuscol_click_defs = stl_alloc_click_defs(wp->w_statuscol_click_defs, width, + &wp->w_statuscol_click_defs_size); + stl_fill_click_defs(wp->w_statuscol_click_defs, clickrec, buf, width, false); + } + + return width; +} + /// Build a string from the status line items in "fmt". /// Return length of string in screen cells. /// @@ -890,11 +917,13 @@ void draw_tabline(void) /// @param fillchar Character to use when filling empty space in the statusline /// @param maxwidth The maximum width to make the statusline /// @param hltab HL attributes (can be NULL) -/// @param tabtab Tab clicks definition (can be NULL). +/// @param tabtab Tab clicks definition (can be NULL) +/// @param stcp Status column attributes (can be NULL) /// /// @return The final width of the statusline int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_name, int opt_scope, - int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab) + int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab, + statuscol_T *stcp) { static size_t stl_items_len = 20; // Initial value, grows as needed. static stl_item_t *stl_items = NULL; @@ -1466,8 +1495,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n } case STL_LINE: - num = (wp->w_buffer->b_ml.ml_flags & ML_EMPTY) - ? 0L : (long)(wp->w_cursor.lnum); + // Overload %l with v:lnum for 'statuscolumn' + num = 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; case STL_NUMLINES: @@ -1565,9 +1595,14 @@ 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: - itemisflag = true; - if (wp->w_buffer->b_p_ro) { - str = (opt == STL_ROFLAG_ALT) ? ",RO" : _("[RO]"); + // Overload %r with v:relnum for 'statuscolumn' + if (strcmp(opt_name, "statuscolumn") == 0) { + num = get_vim_var_nr(VV_RELNUM); + } else { + itemisflag = true; + if (wp->w_buffer->b_p_ro) { + str = (opt == STL_ROFLAG_ALT) ? ",RO" : _("[RO]"); + } } break; @@ -1579,6 +1614,33 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n } break; + case STL_FOLDCOL: // 'C' for 'statuscolumn' + case STL_SIGNCOL: { // 's' for 'statuscolumn' + if (stcp == NULL) { + break; + } + + bool fold = opt == STL_FOLDCOL; + *buf_tmp = NUL; + for (int i = 0; i <= 9; i++) { + char *p = fold ? stcp->fold_text : stcp->sign_text[i]; + if ((!p || !*p) && *buf_tmp == NUL) { + break; + } + 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)) { + str = buf_tmp; + break; + } + STRCAT(buf_tmp, p); + } + break; + } + case STL_FILETYPE: // Copy the filetype if it is not null and the formatted string will fit // in the temporary buffer @@ -1850,6 +1912,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // What follows is post-processing to handle alignment and highlighting. int width = vim_strsize(out); + // Return truncated width for 'statuscolumn' + if (stcp != NULL && width > maxwidth) { + stcp->truncate = width - maxwidth; + } if (maxwidth > 0 && width > maxwidth) { // Result is too long, must truncate somewhere. int item_idx = 0; |