diff options
author | bfredl <bjorn.linse@gmail.com> | 2023-12-29 22:13:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-29 22:13:39 +0100 |
commit | c5e9acca6471280e32fbcaa30849aa68358155ca (patch) | |
tree | 496fa0456e16adfa88d87850016307434c034850 | |
parent | 9aed26079c3021bc194d4261ac4fa8011476cf3e (diff) | |
parent | fe2ca7eabff7d924eff18e0b3a8efc354c0eaf17 (diff) | |
download | rneovim-c5e9acca6471280e32fbcaa30849aa68358155ca.tar.gz rneovim-c5e9acca6471280e32fbcaa30849aa68358155ca.tar.bz2 rneovim-c5e9acca6471280e32fbcaa30849aa68358155ca.zip |
Merge pull request #26758 from luukvbaal/drawline
refactor(drawline): avoid writing foldopen before writing foldclosed
-rw-r--r-- | src/nvim/drawline.c | 83 | ||||
-rw-r--r-- | src/nvim/statusline.c | 13 |
2 files changed, 29 insertions, 67 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index 9478175105..0e2f0e95ea 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -386,33 +386,20 @@ static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum) static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv) { int fdc = compute_foldcolumn(wp, 0); - if (fdc <= 0) { - return; + if (fdc > 0) { + int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLF : HLF_FC); + fill_foldcolumn(wlv, wp, wlv->foldinfo, wlv->lnum, attr, fdc, NULL); } - - int attr = use_cursor_line_highlight(wp, wlv->lnum) - ? win_hl_attr(wp, HLF_CLF) : win_hl_attr(wp, HLF_FC); - - fill_foldcolumn(wlv, wp, wlv->foldinfo, wlv->lnum, attr, NULL); } -/// Fills the foldcolumn at "p" for window "wp". -/// Only to be called when 'foldcolumn' > 0. +/// Draw the foldcolumn or fill "out_buffer". Assume monocell characters. /// -/// @param[out] p Char array to write into -/// @param lnum Absolute current line number -/// @param closed Whether it is in 'foldcolumn' mode -/// -/// Assume monocell characters -/// @return number of chars added to \param p -size_t fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, - schar_T *out_buffer) +/// @param fdc Current width of the foldcolumn +/// @param[out] out_buffer Char array to write into, only used for 'statuscolumn' +void fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr, + int fdc, schar_T *out_buffer) { - int i = 0; - int fdc = compute_foldcolumn(wp, 0); // available cell width - int char_counter = 0; bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0; - int level = foldinfo.fi_level; winlinevars_T *wlv = maybe_wlv; // TODO(bfredl): this is bullshit @@ -420,10 +407,14 @@ size_t fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T // If the column is too narrow, we start at the lowest level that // fits and use numbers to indicate the depth. int first_level = MAX(level - fdc - closed + 1, 1); + int endcol = MIN(fdc, level); + int i = 0; - for (i = 0; i < MIN(fdc, level); i++) { + for (i = 0; i < endcol; i++) { int symbol = 0; - if (foldinfo.fi_lnum == lnum && first_level + i >= foldinfo.fi_low_level) { + if (i == endcol - 1 && closed) { + symbol = wp->w_p_fcs_chars.foldclosed; + } else if (foldinfo.fi_lnum == lnum && first_level + i >= foldinfo.fi_low_level) { symbol = wp->w_p_fcs_chars.foldopen; } else if (first_level == 1) { symbol = wp->w_p_fcs_chars.foldsep; @@ -434,49 +425,21 @@ size_t fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T } if (out_buffer) { - out_buffer[char_counter++] = schar_from_char(symbol); + out_buffer[i] = schar_from_char(symbol); } else { - linebuf_vcol[wlv->off] = -3; + linebuf_vcol[wlv->off] = (i == endcol - 1 && closed) ? -2 : -3; linebuf_attr[wlv->off] = attr; linebuf_char[wlv->off++] = schar_from_char(symbol); - char_counter++; - } - - if (first_level + i >= level) { - i++; - break; } } - if (closed) { - if (char_counter > 0) { - // rollback previous write - char_counter--; - if (!out_buffer) { - wlv->off--; - } - } - if (out_buffer) { - out_buffer[char_counter++] = schar_from_char(wp->w_p_fcs_chars.foldclosed); - } else { - linebuf_vcol[wlv->off] = -2; - linebuf_attr[wlv->off] = attr; - linebuf_char[wlv->off++] = schar_from_char(wp->w_p_fcs_chars.foldclosed); - char_counter++; - } - } - - int width = MAX(char_counter + (fdc - i), fdc); - if (char_counter < width) { - if (out_buffer) { - while (char_counter < width) { - out_buffer[char_counter++] = schar_from_ascii(' '); - } - } else { - draw_col_fill(wlv, schar_from_ascii(' '), width - char_counter, attr); + if (out_buffer) { + while (i < fdc) { + out_buffer[i++] = schar_from_ascii(' '); } + } else { + draw_col_fill(wlv, schar_from_ascii(' '), fdc - i, attr); } - return (size_t)width; } /// Get information needed to display the sign in line "wlv->lnum" in window "wp". @@ -668,9 +631,7 @@ static void draw_statuscol(win_T *wp, winlinevars_T *wlv, linenr_T lnum, int vir } size_t translen = transstr_buf(p, buf + len - p, transbuf, MAXPATHL, true); draw_col_buf(wp, wlv, transbuf, translen, attr, false); - - // Fill up with ' ' - draw_col_fill(wlv, ' ', stcp->width - width, stcp->num_attr); + draw_col_fill(wlv, schar_from_ascii(' '), stcp->width - width, stcp->num_attr); } static void handle_breakindent(win_T *wp, winlinevars_T *wlv) diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 563e1d0a5b..1843676820 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -1631,9 +1631,10 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op break; } bool fold = opt == STL_FOLDCOL; - int width = fold ? (compute_foldcolumn(wp, 0) > 0) : wp->w_scwidth; + int fdc = fold ? compute_foldcolumn(wp, 0) : 0; + int width = fold ? fdc > 0 : wp->w_scwidth; - if (width == 0) { + if (width <= 0) { break; } foldsignitem = curitem; @@ -1641,13 +1642,13 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op char *p = NULL; if (fold) { schar_T fold_buf[10]; - size_t n = fill_foldcolumn(NULL, wp, stcp->foldinfo, - (linenr_T)get_vim_var_nr(VV_LNUM), 0, fold_buf); + fill_foldcolumn(NULL, wp, stcp->foldinfo, + (linenr_T)get_vim_var_nr(VV_LNUM), 0, fdc, fold_buf); stl_items[curitem].minwid = -((stcp->use_cul ? HLF_CLF : HLF_FC) + 1); size_t buflen = 0; // TODO(bfredl): this is very backwards. we must support schar_T - // being used directly in 'statuscol' - for (size_t i = 0; i < n; i++) { + // being used directly in 'statuscolumn' + for (int i = 0; i < fdc; i++) { schar_get(out_p + buflen, fold_buf[i]); buflen += strlen(out_p + buflen); } |