aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/statusline.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/statusline.c')
-rw-r--r--src/nvim/statusline.c84
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;