aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-11-22 19:58:17 +0100
committerbfredl <bjorn.linse@gmail.com>2023-12-22 10:54:28 +0100
commit66ac327db27c8097cfa6c1f136dca96151b074f4 (patch)
tree97ea2b8e6589683ca10dc50c31193cef298e83c6
parent720a3518e3d2eee745bee1d856c92e7c1d84549f (diff)
downloadrneovim-66ac327db27c8097cfa6c1f136dca96151b074f4.tar.gz
rneovim-66ac327db27c8097cfa6c1f136dca96151b074f4.tar.bz2
rneovim-66ac327db27c8097cfa6c1f136dca96151b074f4.zip
refactor(drawline): remove LineDrawState and wlv->saved_n_extra
We do not need an enum to keep track of what place in win_line() we currently are at. We already have a variable which keeps track where in the code we currently are (and thus what part of the line we are currently rendering), it is called the _program counter_. When we need non-linear or self-referential control-flow anyway for a laugh, we have a mechanism for that, it is called _function calls_. Do not "save" and "restore" the wlv->n_extra state every time the columns are to be drawn. This sort of thing needs to go away. Instead of setting the n_extra variables and then going to the outer while loop, the text in the columns can be rendered by just simply putting the text into the cells of the screen line, right away. Even in nvim this can be tricky sometimes, luckily we can use function calls to abstract this logic, which means that this handy data structure called the _call stack_ is handling saving away state temporarily, and restoring it back when we need it again. Lastly, but not least, as we now have direct control how signs are rendered, these can be stored as schar_T[2] and be directly put on screen as such.
-rw-r--r--src/nvim/api/extmark.c7
-rw-r--r--src/nvim/decoration.c36
-rw-r--r--src/nvim/decoration_defs.h8
-rw-r--r--src/nvim/drawline.c697
-rw-r--r--src/nvim/sign.c68
-rw-r--r--src/nvim/sign_defs.h7
-rw-r--r--src/nvim/statusline.c22
-rw-r--r--src/nvim/types_defs.h2
-rw-r--r--test/functional/ui/sign_spec.lua10
9 files changed, 393 insertions, 464 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index ec47d7227e..fa3c5afcc6 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -665,9 +665,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
}
if (HAS_KEY(opts, set_extmark, sign_text)) {
- sign.text.ptr = NULL;
- VALIDATE_S(init_sign_text(NULL, &sign.text.ptr, opts->sign_text.data),
- "sign_text", "", {
+ sign.text[0] = 0;
+ VALIDATE_S(init_sign_text(NULL, sign.text, opts->sign_text.data), "sign_text", "", {
goto error;
});
sign.flags |= kSHIsSign;
@@ -785,7 +784,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
uint32_t decor_indexed = DECOR_ID_INVALID;
if (sign.flags & kSHIsSign) {
decor_indexed = decor_put_sh(sign);
- if (sign.text.ptr != NULL) {
+ if (sign.text[0]) {
decor_flags |= MT_FLAG_DECOR_SIGNTEXT;
}
if (sign.number_hl_id || sign.line_hl_id || sign.cursorline_hl_id) {
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index 7b3a32167e..bddc48b8c7 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -6,6 +6,7 @@
#include "nvim/api/extmark.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/ascii_defs.h"
#include "nvim/buffer_defs.h"
#include "nvim/decoration.h"
#include "nvim/drawscreen.h"
@@ -20,6 +21,7 @@
#include "nvim/move.h"
#include "nvim/option_vars.h"
#include "nvim/pos_defs.h"
+#include "nvim/sign.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "decoration.c.generated.h"
@@ -159,7 +161,7 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item)
DecorSignHighlight conv = {
.flags = item.flags,
.priority = item.priority,
- .text.sc[0] = item.conceal_char,
+ .text[0] = item.conceal_char,
.hl_id = item.hl_id,
.number_hl_id = 0,
.line_hl_id = 0,
@@ -208,7 +210,7 @@ void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2)
if (sh->flags & kSHIsSign) {
sh->sign_add_id = sign_add_id++;
buf->b_signs++;
- if (sh->text.ptr) {
+ if (sh->text[0]) {
buf->b_signs_with_text++;
buf_signcols_invalidate_range(buf, row1, row2, 1);
}
@@ -254,7 +256,7 @@ void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh)
if (sh->flags & kSHIsSign) {
assert(buf->b_signs > 0);
buf->b_signs--;
- if (sh->text.ptr) {
+ if (sh->text[0]) {
assert(buf->b_signs_with_text > 0);
buf->b_signs_with_text--;
if (row2 >= row1) {
@@ -313,9 +315,6 @@ void decor_free_inner(DecorVirtText *vt, uint32_t first_idx)
while (idx != DECOR_ID_INVALID) {
DecorSignHighlight *sh = &kv_A(decor_items, idx);
if (sh->flags & kSHIsSign) {
- xfree(sh->text.ptr);
- }
- if (sh->flags & kSHIsSign) {
xfree(sh->sign_name);
}
sh->flags = 0;
@@ -363,8 +362,11 @@ void decor_check_invalid_glyphs(void)
{
for (size_t i = 0; i < kv_size(decor_items); i++) {
DecorSignHighlight *it = &kv_A(decor_items, i);
- if ((it->flags & kSHConceal) && schar_high(it->text.sc[0])) {
- it->text.sc[0] = schar_from_char(schar_get_first_codepoint(it->text.sc[0]));
+ int width = (it->flags & kSHIsSign) ? SIGN_WIDTH : ((it->flags & kSHConceal) ? 1 : 0);
+ for (int j = 0; j < width; j++) {
+ if (schar_high(it->text[j])) {
+ it->text[j] = schar_from_char(schar_get_first_codepoint(it->text[j]));
+ }
}
}
}
@@ -662,7 +664,7 @@ next_mark:
if (item.start_row == state->row && item.start_col == col) {
DecorSignHighlight *sh = &item.data.sh;
conceal = 2;
- conceal_char = sh->text.sc[0];
+ conceal_char = sh->text[0];
state->col_until = MIN(state->col_until, item.start_col);
conceal_attr = item.attr_id;
}
@@ -730,7 +732,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) {
if (!mt_invalid(pair.start) && mt_decor_sign(pair.start)) {
DecorSignHighlight *sh = decor_find_sign(mt_decor(pair.start));
- num_text += (sh->text.ptr != NULL);
+ num_text += (sh->text[0] != NUL);
kv_push(signs, ((SignItem){ sh, pair.start.id }));
}
}
@@ -742,7 +744,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
}
if (!mt_end(mark) && !mt_invalid(mark) && mt_decor_sign(mark)) {
DecorSignHighlight *sh = decor_find_sign(mt_decor(mark));
- num_text += (sh->text.ptr != NULL);
+ num_text += (sh->text[0] != NUL);
kv_push(signs, ((SignItem){ sh, mark.id }));
}
@@ -756,8 +758,8 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
for (size_t i = 0; i < kv_size(signs); i++) {
DecorSignHighlight *sh = kv_A(signs, i).sh;
- if (idx >= 0 && sh->text.ptr) {
- sattrs[idx].text = sh->text.ptr;
+ if (idx >= 0 && sh->text[0]) {
+ memcpy(sattrs[idx].text, sh->text, SIGN_WIDTH * sizeof(sattr_T));
sattrs[idx--].hl_id = sh->hl_id;
}
if (*num_id == 0) {
@@ -1034,7 +1036,7 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name)
PUT(*dict, "hl_eol", BOOLEAN_OBJ(sh_hl.flags & kSHHlEol));
if (sh_hl.flags & kSHConceal) {
char buf[MAX_SCHAR_SIZE];
- schar_get(buf, sh_hl.text.sc[0]);
+ schar_get(buf, sh_hl.text[0]);
PUT(*dict, "conceal", CSTR_TO_OBJ(buf));
}
@@ -1082,8 +1084,10 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name)
}
if (sh_sign.flags & kSHIsSign) {
- if (sh_sign.text.ptr) {
- PUT(*dict, "sign_text", CSTR_TO_OBJ(sh_sign.text.ptr));
+ if (sh_sign.text[0]) {
+ char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
+ describe_sign_text(buf, sh_sign.text);
+ PUT(*dict, "sign_text", CSTR_TO_OBJ(buf));
}
if (sh_sign.sign_name) {
diff --git a/src/nvim/decoration_defs.h b/src/nvim/decoration_defs.h
index f272753f46..4550ae0a42 100644
--- a/src/nvim/decoration_defs.h
+++ b/src/nvim/decoration_defs.h
@@ -59,11 +59,7 @@ typedef struct {
uint16_t flags;
DecorPriority priority;
int hl_id; // if sign: highlight of sign text
- // TODO(bfredl): Later signs should use sc[2] as well.
- union {
- char *ptr; // sign
- schar_T sc[2]; // conceal text (only sc[0] used)
- } text;
+ schar_T text[SIGN_WIDTH]; // conceal text only uses text[0]
// NOTE: if more functionality is added to a Highlight these should be overloaded
// or restructured
char *sign_name;
@@ -74,7 +70,7 @@ typedef struct {
uint32_t next;
} DecorSignHighlight;
-#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { .ptr = NULL }, NULL, 0, 0, 0, 0, \
+#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { 0, 0 }, NULL, 0, 0, 0, 0, \
DECOR_ID_INVALID }
enum {
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 4f62fda2c5..29221e64f9 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -52,23 +52,8 @@
#define MB_FILLER_CHAR '<' // character used when a double-width character doesn't fit.
-/// possible draw states in win_line(), drawn in sequence.
-typedef enum {
- WL_START = 0, // nothing done yet
- WL_CMDLINE, // cmdline window column
- WL_FOLD, // 'foldcolumn'
- WL_SIGN, // column for signs
- WL_NR, // line number
- WL_STC, // 'statuscolumn'
- WL_BRI, // 'breakindent'
- WL_SBR, // 'showbreak' or 'diff'
- WL_LINE, // text in the line
-} LineDrawState;
-
/// structure with variables passed between win_line() and other functions
typedef struct {
- LineDrawState draw_state; ///< what to draw next
-
linenr_T lnum; ///< line number to be drawn
foldinfo_T foldinfo; ///< fold info for this line
@@ -102,18 +87,8 @@ typedef struct {
int c_extra; ///< extra chars, all the same
int c_final; ///< final char, mandatory if set
- int n_closing; ///< number of chars in fdc which will be closing
-
bool extra_for_extmark; ///< n_extra set for inline virtual text
- // saved "extra" items for when draw_state becomes WL_LINE (again)
- int saved_n_extra;
- char *saved_p_extra;
- bool saved_extra_for_extmark;
- int saved_c_extra;
- int saved_c_final;
- int saved_char_attr;
-
char extra[57]; ///< sign, line number and 'fdc' must fit in here
hlf_T diff_hlf; ///< type of diff highlighting
@@ -136,6 +111,8 @@ typedef struct {
///< or w_skipcol or concealing
int skipped_cells; ///< nr of skipped cells for virtual text
///< to be added to wlv.vcol later
+
+ int *color_cols; ///< if not NULL, highlight colorcolumn using according columns array
} winlinevars_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS
@@ -163,15 +140,17 @@ void drawline_free_all_mem(void)
}
#endif
-/// Advance **color_cols
-///
-/// @return true when there are columns to draw.
-static bool advance_color_col(int vcol, int **color_cols)
+/// Advance wlv->color_cols if not NULL
+static void advance_color_col(winlinevars_T *wlv, int vcol)
{
- while (**color_cols >= 0 && vcol > **color_cols) {
- (*color_cols)++;
+ if (wlv->color_cols) {
+ while (*wlv->color_cols >= 0 && vcol > *wlv->color_cols) {
+ wlv->color_cols++;
+ }
+ if (*wlv->color_cols < 0) {
+ wlv->color_cols = NULL;
+ }
}
- return **color_cols >= 0;
}
/// Used when 'cursorlineopt' contains "screenline": compute the margins between
@@ -360,6 +339,38 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
return col;
}
+// TODO(bfredl): integrate with grid.c linebuf code? madness?
+static void draw_col_buf(win_T *wp, winlinevars_T *wlv, const char *text, size_t len, int attr,
+ bool vcol)
+{
+ const char *ptr = text;
+ while (ptr < text + len && wlv->off < wp->w_grid.cols) {
+ int cells = line_putchar(wp->w_buffer, &ptr, &linebuf_char[wlv->off],
+ wp->w_grid.cols - wlv->off, wlv->off);
+ int myattr = attr;
+ if (vcol) {
+ advance_color_col(wlv, wlv->vcol);
+ if (wlv->color_cols && wlv->vcol == *wlv->color_cols) {
+ myattr = hl_combine_attr(win_hl_attr(wp, HLF_MC), myattr);
+ }
+ }
+ for (int c = 0; c < cells; c++) {
+ linebuf_attr[wlv->off] = myattr;
+ linebuf_vcol[wlv->off] = vcol ? wlv->vcol++ : -1;
+ wlv->off++;
+ }
+ }
+}
+
+static void draw_col_fill(winlinevars_T *wlv, schar_T fillchar, int width, int attr)
+{
+ for (int i = 0; i < width; i++) {
+ linebuf_char[wlv->off] = fillchar;
+ linebuf_attr[wlv->off] = attr;
+ wlv->off++;
+ }
+}
+
/// Return true if CursorLineSign highlight is to be used.
static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum)
{
@@ -368,28 +379,18 @@ static bool use_cursor_line_highlight(win_T *wp, linenr_T lnum)
&& (wp->w_p_culopt_flags & CULOPT_NBR);
}
-static char fdc_buf[MB_MAXCHAR * 10 + 1];
-
/// Setup for drawing the 'foldcolumn', if there is one.
-static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
+static void draw_foldcolumn(win_T *wp, winlinevars_T *wlv)
{
int fdc = compute_foldcolumn(wp, 0);
if (fdc <= 0) {
return;
}
- // Use a separate buffer as `extra_buf` might be in use.
- wlv->n_extra = (int)fill_foldcolumn(fdc_buf, wp, wlv->foldinfo, wlv->lnum,
- &wlv->n_closing);
- fdc_buf[wlv->n_extra] = NUL;
- wlv->p_extra = fdc_buf;
- wlv->c_extra = NUL;
- wlv->c_final = NUL;
- if (use_cursor_line_highlight(wp, wlv->lnum)) {
- wlv->char_attr = win_hl_attr(wp, HLF_CLF);
- } else {
- wlv->char_attr = win_hl_attr(wp, HLF_FC);
- }
+ 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".
@@ -401,29 +402,25 @@ static void handle_foldcolumn(win_T *wp, winlinevars_T *wlv)
///
/// Assume monocell characters
/// @return number of chars added to \param p
-size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int *n_closing)
+size_t fill_foldcolumn(void *maybe_wlv, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, int attr,
+ schar_T *out_buffer)
{
int i = 0;
int fdc = compute_foldcolumn(wp, 0); // available cell width
- size_t char_counter = 0;
- int symbol = 0;
- int len = 0;
+ int char_counter = 0;
bool closed = foldinfo.fi_level != 0 && foldinfo.fi_lines > 0;
- // Init to all spaces.
- memset(p, ' ', MB_MAXCHAR * (size_t)fdc + 1);
int level = foldinfo.fi_level;
+ winlinevars_T *wlv = maybe_wlv; // TODO(bfredl): this is bullshit
+
// If the column is too narrow, we start at the lowest level that
// fits and use numbers to indicate the depth.
- int first_level = level - fdc - closed + 1;
- if (first_level < 1) {
- first_level = 1;
- }
+ int first_level = MAX(level - fdc - closed + 1, 1);
for (i = 0; i < MIN(fdc, level); i++) {
- if (foldinfo.fi_lnum == lnum
- && first_level + i >= foldinfo.fi_low_level) {
+ int symbol = 0;
+ 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;
@@ -433,64 +430,74 @@ size_t fill_foldcolumn(char *p, win_T *wp, foldinfo_T foldinfo, linenr_T lnum, i
symbol = '>';
}
- len = utf_char2bytes(symbol, &p[char_counter]);
- char_counter += (size_t)len;
+ if (out_buffer) {
+ out_buffer[char_counter++] = schar_from_char(symbol);
+ } else {
+ linebuf_vcol[wlv->off] = -3;
+ linebuf_attr[wlv->off] = attr;
+ linebuf_char[wlv->off++] = schar_from_char(symbol);
+ char_counter++;
+ }
+
if (first_level + i >= level) {
i++;
break;
}
}
- int n_closing_val = i;
-
if (closed) {
- if (symbol != 0) {
+ if (char_counter > 0) {
// rollback previous write
- char_counter -= (size_t)len;
- memset(&p[char_counter], ' ', (size_t)len);
- n_closing_val--;
+ 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++;
}
- len = utf_char2bytes(wp->w_p_fcs_chars.foldclosed, &p[char_counter]);
- char_counter += (size_t)len;
}
- if (n_closing) {
- *n_closing = n_closing_val;
+ 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);
+ }
}
-
- return MAX(char_counter + (size_t)(fdc - i), (size_t)fdc);
+ return (size_t)width;
}
/// Get information needed to display the sign in line "wlv->lnum" in window "wp".
/// If "nrcol" is true, the sign is going to be displayed in the number column.
/// Otherwise the sign is going to be displayed in the sign column. If there is no
/// sign, draw blank cells instead.
-static void get_sign_display_info(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx,
- int sign_cul_attr)
+static void draw_sign(bool nrcol, win_T *wp, winlinevars_T *wlv, int sign_idx, int sign_cul_attr)
{
SignTextAttrs sattr = wlv->sattrs[sign_idx];
wlv->c_final = NUL;
- if (sattr.text && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) {
- size_t fill = nrcol ? (size_t)number_width(wp) - SIGN_WIDTH : 0;
- size_t sign_len = strlen(sattr.text);
-
- // Spaces + sign: " " + ">>" + ' '
- wlv->n_extra = (int)(fill + sign_len + nrcol);
- if (nrcol) {
- memset(wlv->extra, ' ', (size_t)wlv->n_extra);
- }
- memcpy(wlv->extra + fill, sattr.text, sign_len);
- wlv->p_extra = wlv->extra;
- wlv->c_extra = NUL;
- wlv->char_attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr)
- ? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0;
+ if (sattr.text[0] && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) {
+ int attr = (use_cursor_line_highlight(wp, wlv->lnum) && sign_cul_attr)
+ ? sign_cul_attr : sattr.hl_id ? syn_id2attr(sattr.hl_id) : 0;
+ int fill = nrcol ? number_width(wp) + 1 : SIGN_WIDTH;
+ draw_col_fill(wlv, schar_from_ascii(' '), fill, attr);
+ int sign_pos = wlv->off - SIGN_WIDTH - (int)nrcol;
+ linebuf_char[sign_pos] = sattr.text[0];
+ linebuf_char[sign_pos + 1] = sattr.text[1];
} else {
+ assert(!nrcol); // handled in draw_lnum_col()
wlv->c_extra = ' ';
- wlv->n_extra = nrcol ? number_width(wp) + 1 : SIGN_WIDTH;
- if (!nrcol) {
- wlv->char_attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC);
- }
+ int attr = win_hl_attr(wp, use_cursor_line_highlight(wp, wlv->lnum) ? HLF_CLS : HLF_SC);
+ draw_col_fill(wlv, schar_from_ascii(' '), SIGN_WIDTH, attr);
}
}
@@ -557,7 +564,7 @@ static int get_line_number_attr(win_T *wp, winlinevars_T *wlv)
/// Display the absolute or relative line number. After the first row fill with
/// blanks when the 'n' flag isn't in 'cpo'.
-static void handle_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int sign_cul_attr)
+static void draw_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, int sign_cul_attr)
{
bool has_cpo_n = vim_strchr(p_cpo, CPO_NUMCOL) != NULL;
@@ -568,33 +575,30 @@ static void handle_lnum_col(win_T *wp, winlinevars_T *wlv, int sign_num_attr, in
&& !((has_cpo_n && !wp->w_p_bri) && wp->w_skipcol > 0 && wlv->lnum == wp->w_topline)) {
// If 'signcolumn' is set to 'number' and a sign is present in "lnum",
// then display the sign instead of the line number.
- if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text) {
- get_sign_display_info(true, wp, wlv, 0, sign_cul_attr);
+ if (wp->w_minscwidth == SCL_NUM && wlv->sattrs[0].text[0]
+ && wlv->row == wlv->startrow + wlv->filler_lines && wlv->filler_todo <= 0) {
+ draw_sign(true, wp, wlv, 0, sign_cul_attr);
} else {
// Draw the line number (empty space after wrapping).
+ int width = number_width(wp) + 1;
+ int attr = (sign_num_attr > 0 && wlv->filler_todo <= 0)
+ ? sign_num_attr : get_line_number_attr(wp, wlv);
if (wlv->row == wlv->startrow + wlv->filler_lines
&& (wp->w_skipcol == 0 || wlv->row > 0 || (wp->w_p_nu && wp->w_p_rnu))) {
- get_line_number_str(wp, wlv->lnum, wlv->extra, sizeof(wlv->extra));
+ char buf[32];
+ get_line_number_str(wp, wlv->lnum, buf, sizeof(buf));
if (wp->w_skipcol > 0 && wlv->startrow == 0) {
- for (wlv->p_extra = wlv->extra; *wlv->p_extra == ' '; wlv->p_extra++) {
- *wlv->p_extra = '-';
+ for (char *c = buf; *c == ' '; c++) {
+ *c = '-';
}
}
if (wp->w_p_rl) { // reverse line numbers
- char *num = skipwhite(wlv->extra);
+ char *num = skipwhite(buf);
rl_mirror_ascii(num, skiptowhite(num));
}
- wlv->p_extra = wlv->extra;
- wlv->c_extra = NUL;
+ draw_col_buf(wp, wlv, buf, (size_t)width, attr, false);
} else {
- wlv->c_extra = ' ';
- }
- wlv->c_final = NUL;
- wlv->n_extra = number_width(wp) + 1;
- if (sign_num_attr > 0) {
- wlv->char_attr = sign_num_attr;
- } else {
- wlv->char_attr = get_line_number_attr(wp, wlv);
+ draw_col_fill(wlv, schar_from_ascii(' '), width, attr);
}
}
}
@@ -663,124 +667,108 @@ static void get_statuscol_str(win_T *wp, linenr_T lnum, int virtnum, statuscol_T
///
/// @param stcp Status column attributes
/// @param[in,out] wlv
-static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv)
+static void draw_statuscol(win_T *wp, statuscol_T *stcp, winlinevars_T *wlv)
{
- wlv->c_extra = NUL;
- wlv->c_final = NUL;
do {
- wlv->draw_state = WL_STC;
- wlv->char_attr = stcp->cur_attr;
- wlv->p_extra = stcp->textp;
- char *const section_end = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end;
- wlv->n_extra = (int)(section_end - stcp->textp);
+ int attr = stcp->cur_attr;
+ char *text = stcp->textp;
+ char *section_end = stcp->hlrecp->start ? stcp->hlrecp->start : stcp->text_end;
+ ptrdiff_t len = section_end - text;
// Prepare for next highlight section if not yet at the end
if (section_end < stcp->text_end) {
int hl = stcp->hlrecp->userhl;
stcp->textp = stcp->hlrecp->start;
stcp->cur_attr = hl < 0 ? syn_id2attr(-hl) : stcp->num_attr;
stcp->hlrecp++;
- wlv->draw_state = WL_STC - 1;
+ } else {
+ stcp->textp = section_end;
}
// Skip over empty highlight sections
- } while (wlv->n_extra == 0 && stcp->textp < stcp->text_end);
- if (wlv->n_extra > 0) {
- static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * 2) * MB_MAXBYTES + 1];
- wlv->n_extra = (int)transstr_buf(wlv->p_extra, wlv->n_extra, transbuf, sizeof transbuf, true);
- wlv->p_extra = transbuf;
- }
+ if (len) {
+ static char transbuf[(MAX_NUMBERWIDTH + 9 + 9 * SIGN_WIDTH) * MB_MAXBYTES + 1];
+ size_t translen = transstr_buf(text, len, transbuf, sizeof transbuf, true);
+ draw_col_buf(wp, wlv, transbuf, translen, attr, false);
+ }
+ } while (stcp->textp < stcp->text_end);
}
static void handle_breakindent(win_T *wp, winlinevars_T *wlv)
{
- if (wp->w_briopt_sbr && wlv->draw_state == WL_BRI - 1
- && *get_showbreak_value(wp) != NUL) {
- // draw indent after showbreak value
- wlv->draw_state = WL_BRI;
- } else if (wp->w_briopt_sbr && wlv->draw_state == WL_SBR) {
- // after the showbreak, draw the breakindent
- wlv->draw_state = WL_BRI - 1;
- }
-
// draw 'breakindent': indent wrapped text accordingly
- if (wlv->draw_state == WL_BRI - 1 && wlv->n_extra == 0) {
- wlv->draw_state = WL_BRI;
- // if wlv->need_showbreak is set, breakindent also applies
- if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines
- || wlv->need_showbreak)) {
- wlv->char_attr = 0;
- if (wlv->diff_hlf != (hlf_T)0) {
- wlv->char_attr = win_hl_attr(wp, (int)wlv->diff_hlf);
- }
- wlv->p_extra = NULL;
- wlv->c_extra = ' ';
- wlv->c_final = NUL;
- wlv->n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, wlv->lnum));
- if (wlv->row == wlv->startrow) {
- wlv->n_extra -= win_col_off2(wp);
- if (wlv->n_extra < 0) {
- wlv->n_extra = 0;
- }
- }
- if (wp->w_skipcol > 0 && wlv->startrow == 0 && wp->w_p_wrap && wp->w_briopt_sbr) {
- wlv->need_showbreak = false;
+ // if wlv->need_showbreak is set, breakindent also applies
+ if (wp->w_p_bri && (wlv->row > wlv->startrow + wlv->filler_lines
+ || wlv->need_showbreak)) {
+ int attr = 0;
+ if (wlv->diff_hlf != (hlf_T)0) {
+ attr = win_hl_attr(wp, (int)wlv->diff_hlf);
+ }
+ int num = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, wlv->lnum));
+ if (wlv->row == wlv->startrow) {
+ num -= win_col_off2(wp);
+ if (wlv->n_extra < 0) {
+ num = 0;
}
- // Correct end of highlighted area for 'breakindent',
- // required wen 'linebreak' is also set.
- if (wlv->tocol == wlv->vcol) {
- wlv->tocol += wlv->n_extra;
+ }
+
+ // Correct end of highlighted area for 'breakindent',
+ // required wen 'linebreak' is also set.
+ if (wlv->tocol == wlv->vcol) {
+ wlv->tocol += num;
+ }
+
+ for (int i = 0; i < num; i++) {
+ linebuf_char[wlv->off] = schar_from_ascii(' ');
+
+ advance_color_col(wlv, wlv->vcol);
+ int myattr = attr;
+ if (wlv->color_cols && wlv->vcol == *wlv->color_cols) {
+ myattr = hl_combine_attr(win_hl_attr(wp, HLF_MC), myattr);
}
+ linebuf_attr[wlv->off] = myattr;
+ linebuf_vcol[wlv->off] = wlv->vcol++; // These are vcols, sorry I don't make the rules
+ wlv->off++;
+ }
+
+ if (wp->w_skipcol > 0 && wlv->startrow == 0 && wp->w_p_wrap && wp->w_briopt_sbr) {
+ wlv->need_showbreak = false;
}
}
}
static void handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv)
{
+ int remaining = wp->w_grid.cols - wlv->off;
if (wlv->filler_todo > wlv->filler_lines - wlv->n_virt_lines) {
// TODO(bfredl): check this doesn't inhibit TUI-style
// clear-to-end-of-line.
- wlv->c_extra = ' ';
- wlv->c_final = NUL;
- wlv->n_extra = wp->w_grid.cols - wlv->col;
- wlv->char_attr = 0;
+ draw_col_fill(wlv, schar_from_ascii(' '), remaining, 0);
} else if (wlv->filler_todo > 0) {
// Draw "deleted" diff line(s)
- if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
- wlv->c_extra = '-';
- wlv->c_final = NUL;
- } else {
- wlv->c_extra = wp->w_p_fcs_chars.diff;
- wlv->c_final = NUL;
- }
- wlv->n_extra = wp->w_grid.cols - wlv->col;
- wlv->char_attr = win_hl_attr(wp, HLF_DED);
+ int c = (char2cells(wp->w_p_fcs_chars.diff) > 1) ? '-' : wp->w_p_fcs_chars.diff;
+ draw_col_fill(wlv, schar_from_char(c), remaining, win_hl_attr(wp, HLF_DED));
}
char *const sbr = get_showbreak_value(wp);
if (*sbr != NUL && wlv->need_showbreak) {
// Draw 'showbreak' at the start of each broken line.
- wlv->p_extra = sbr;
- wlv->c_extra = NUL;
- wlv->c_final = NUL;
- wlv->n_extra = (int)strlen(sbr);
- wlv->char_attr = win_hl_attr(wp, HLF_AT);
if (wp->w_skipcol == 0 || wlv->startrow != 0 || !wp->w_p_wrap) {
wlv->need_showbreak = false;
}
- wlv->vcol_sbr = wlv->vcol + mb_charlen(sbr);
+ // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
+ int attr = hl_combine_attr(wlv->cul_attr, win_hl_attr(wp, HLF_AT));
+ int vcol_before = wlv->vcol;
+ draw_col_buf(wp, wlv, sbr, strlen(sbr), attr, true);
+ wlv->vcol_sbr = wlv->vcol;
// Correct start of highlighted area for 'showbreak'.
- if (wlv->fromcol >= wlv->vcol && wlv->fromcol < wlv->vcol_sbr) {
+ if (wlv->fromcol >= vcol_before && wlv->fromcol < wlv->vcol_sbr) {
wlv->fromcol = wlv->vcol_sbr;
}
// Correct end of highlighted area for 'showbreak',
// required when 'linebreak' is also set.
- if (wlv->tocol == wlv->vcol) {
- wlv->tocol += wlv->n_extra;
- }
- // Combine 'showbreak' with 'cursorline', prioritizing 'showbreak'.
- if (wlv->cul_attr) {
- wlv->char_attr = hl_combine_attr(wlv->cul_attr, wlv->char_attr);
+ if (wlv->tocol == vcol_before) {
+ wlv->tocol = wlv->vcol;
}
}
}
@@ -943,37 +931,7 @@ static void win_line_start(win_T *wp, winlinevars_T *wlv, bool save_extra)
wlv->col = 0;
wlv->off = 0;
wlv->need_lbr = false;
-
- if (save_extra) {
- // reset the drawing state for the start of a wrapped line
- wlv->draw_state = WL_START;
- wlv->saved_n_extra = wlv->n_extra;
- wlv->saved_p_extra = wlv->p_extra;
- wlv->saved_extra_for_extmark = wlv->extra_for_extmark;
- wlv->saved_c_extra = wlv->c_extra;
- wlv->saved_c_final = wlv->c_final;
- wlv->need_lbr = true;
- wlv->saved_char_attr = wlv->char_attr;
-
- wlv->n_extra = 0;
- }
-}
-
-/// Called when wlv->draw_state is set to WL_LINE.
-static void win_line_continue(winlinevars_T *wlv)
-{
- if (wlv->saved_n_extra > 0) {
- // Continue item from end of wrapped line.
- wlv->n_extra = wlv->saved_n_extra;
- wlv->saved_n_extra = 0;
- wlv->c_extra = wlv->saved_c_extra;
- wlv->c_final = wlv->saved_c_final;
- wlv->p_extra = wlv->saved_p_extra;
- wlv->extra_for_extmark = wlv->saved_extra_for_extmark;
- wlv->char_attr = wlv->saved_char_attr;
- } else {
- wlv->char_attr = 0;
- }
+ memset(linebuf_vcol, -1, (size_t)wp->w_grid.cols * sizeof(*linebuf_vcol));
}
/// Display line "lnum" of window "wp" on the screen.
@@ -1025,8 +983,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
int folded_attr = 0; // attributes for folded line
int save_did_emsg;
int eol_hl_off = 0; // 1 if highlighted char after EOL
- bool draw_color_col = false; // highlight colorcolumn
- int *color_cols = NULL; // pointer to according columns array
#define SPWORDLEN 150
char nextline[SPWORDLEN * 2]; // text with start of the next line
int nextlinecol = 0; // column where nextline[] starts
@@ -1079,7 +1035,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
bool is_concealing = false;
bool did_wcol = false;
int old_boguscols = 0;
-#define VCOL_HLC (wlv.vcol - wlv.vcol_off)
+#define vcol_hlc(wlv) ((wlv).vcol - (wlv).vcol_off)
#define FIX_FOR_BOGUSCOLS \
{ \
wlv.n_extra += wlv.vcol_off; \
@@ -1136,10 +1092,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
// Check for columns to display for 'colorcolumn'.
- color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols;
- if (color_cols != NULL) {
- draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- }
+ wlv.color_cols = wp->w_buffer->terminal ? NULL : wp->w_p_cc_cols;
+ advance_color_col(&wlv, vcol_hlc(wlv));
// handle Visual active in this window
if (VIsual_active && wp->w_buffer == curwin->w_buffer) {
@@ -1453,7 +1407,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
// - the visual mode is active,
// the end of the line may be before the start of the displayed part.
if (wlv.vcol < v && (wp->w_p_cuc
- || draw_color_col
+ || wlv.color_cols
|| virtual_active()
|| (VIsual_active && wp->w_buffer == curwin->w_buffer))) {
wlv.vcol = (colnr_T)v;
@@ -1550,6 +1504,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
win_line_start(wp, &wlv, false);
+ bool draw_cols = true;
+ int leftcols_width = 0;
// won't highlight after TERM_ATTRS_MAX columns
int term_attrs[TERM_ATTRS_MAX] = { 0 };
@@ -1558,7 +1514,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
extra_check = true;
}
- int sign_idx = 0;
int virt_line_index;
int virt_line_offset = -1;
// Repeat for the whole displayed line.
@@ -1569,119 +1524,85 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
bool did_decrement_ptr = false;
// Skip this quickly when working on the text.
- if (wlv.draw_state != WL_LINE) {
+ if (draw_cols) {
if (cul_screenline) {
wlv.cul_attr = 0;
wlv.line_attr = line_attr_save;
wlv.line_attr_lowprio = line_attr_lowprio_save;
}
- if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0) {
- wlv.draw_state = WL_CMDLINE;
- if (cmdwin_type != 0 && wp == curwin) {
- // Draw the cmdline character.
- wlv.n_extra = 1;
- wlv.c_extra = cmdwin_type;
- wlv.c_final = NUL;
- wlv.char_attr = win_hl_attr(wp, HLF_AT);
- }
- }
-
- if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) {
- if (wlv.filler_todo > 0) {
- int index = wlv.filler_todo - (wlv.filler_lines - wlv.n_virt_lines);
- if (index > 0) {
- virt_line_index = (int)kv_size(virt_lines) - index;
- assert(virt_line_index >= 0);
- virt_line_offset = kv_A(virt_lines, virt_line_index).left_col ? 0 : win_col_off(wp);
- }
- }
- if (virt_line_offset == 0) {
- // Skip the column states if there is a "virt_left_col" line.
- wlv.draw_state = WL_BRI - 1;
- } else if (statuscol.draw) {
- // Skip fold, sign and number states if 'statuscolumn' is set.
- wlv.draw_state = WL_STC - 1;
- }
- }
+ assert(wlv.off == 0);
- if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) {
- wlv.draw_state = WL_FOLD;
- handle_foldcolumn(wp, &wlv);
+ if (cmdwin_type != 0 && wp == curwin) {
+ // Draw the cmdline character.
+ draw_col_fill(&wlv, schar_from_ascii(cmdwin_type), 1, win_hl_attr(wp, HLF_AT));
}
- // sign column, this is hit until sign_idx reaches count
- if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) {
- // Show the sign column when desired.
- wlv.draw_state = WL_SIGN;
- if (wp->w_scwidth > 0) {
- get_sign_display_info(false, wp, &wlv, sign_idx, sign_cul_attr);
- if (++sign_idx < wp->w_scwidth) {
- wlv.draw_state = WL_SIGN - 1;
- } else {
- sign_idx = 0;
- }
+ if (wlv.filler_todo > 0) {
+ int index = wlv.filler_todo - (wlv.filler_lines - wlv.n_virt_lines);
+ if (index > 0) {
+ virt_line_index = (int)kv_size(virt_lines) - index;
+ assert(virt_line_index >= 0);
+ virt_line_offset = kv_A(virt_lines, virt_line_index).left_col ? 0 : win_col_off(wp);
}
}
- if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) {
- // Show the line number, if desired.
- wlv.draw_state = WL_NR;
- handle_lnum_col(wp, &wlv, sign_num_attr, sign_cul_attr);
- }
-
- if (wlv.draw_state == WL_STC - 1 && wlv.n_extra == 0) {
- wlv.draw_state = WL_STC;
- // Draw the 'statuscolumn' if option is set.
- if (statuscol.draw) {
- if (sign_num_attr == 0) {
- statuscol.num_attr = get_line_number_attr(wp, &wlv);
+ if (virt_line_offset == 0) {
+ // skip columns
+ } else if (statuscol.draw) {
+ // Draw 'statuscolumn' if it is set.
+ if (sign_num_attr == 0) {
+ statuscol.num_attr = get_line_number_attr(wp, &wlv);
+ }
+ if (statuscol.textp == NULL) {
+ v = (ptr - line);
+ get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol);
+ if (!end_fill) {
+ // Get the line again as evaluating 'statuscolumn' may free it.
+ line = ml_get_buf(wp->w_buffer, lnum);
+ ptr = line + v;
}
- if (statuscol.textp == NULL) {
- v = (ptr - line);
- get_statuscol_str(wp, lnum, wlv.row - startrow - wlv.filler_lines, &statuscol);
- if (!end_fill) {
- // Get the line again as evaluating 'statuscolumn' may free it.
- line = ml_get_buf(wp->w_buffer, lnum);
- ptr = line + v;
- }
- if (wp->w_redr_statuscol) {
- break;
- }
+ if (wp->w_redr_statuscol) {
+ break;
}
- get_statuscol_display_info(&statuscol, &wlv);
}
- }
+ draw_statuscol(wp, &statuscol, &wlv);
+ } else {
+ // draw builtin info columns: fold, sign, number
+ draw_foldcolumn(wp, &wlv);
+
+ // wp->w_scwidth is zero if signcol=number is used
+ for (int sign_idx = 0; sign_idx < wp->w_scwidth; sign_idx++) {
+ draw_sign(false, wp, &wlv, sign_idx, sign_cul_attr);
+ }
- if (wlv.draw_state == WL_STC && wlv.n_extra == 0) {
- win_col_offset = wlv.off;
+ draw_lnum_col(wp, &wlv, sign_num_attr, sign_cul_attr);
}
+ win_col_offset = wlv.off;
+
// Check if 'breakindent' applies and show it.
// May change wlv.draw_state to WL_BRI or WL_BRI - 1.
- if (wlv.n_extra == 0) {
+ if (!wp->w_briopt_sbr) {
handle_breakindent(wp, &wlv);
}
-
- if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0) {
- wlv.draw_state = WL_SBR;
- handle_showbreak_and_filler(wp, &wlv);
+ handle_showbreak_and_filler(wp, &wlv);
+ if (wp->w_briopt_sbr) {
+ handle_breakindent(wp, &wlv);
}
- if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0) {
- sign_idx = 0;
- wlv.draw_state = WL_LINE;
- if (has_decor && wlv.row == startrow + wlv.filler_lines) {
- // hide virt_text on text hidden by 'nowrap' or 'smoothscroll'
- decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state);
- }
- win_line_continue(&wlv); // use wlv.saved_ values
+ wlv.col = wlv.off;
+ draw_cols = false;
+ if (wlv.filler_todo <= 0) {
+ leftcols_width = wlv.off;
+ }
+ if (has_decor && wlv.row == startrow + wlv.filler_lines) {
+ // hide virt_text on text hidden by 'nowrap' or 'smoothscroll'
+ decor_redraw_col(wp, (colnr_T)(ptr - line) - 1, wlv.off, true, &decor_state);
}
}
- if (cul_screenline && wlv.draw_state == WL_LINE
- && wlv.vcol >= left_curline_col
- && wlv.vcol < right_curline_col) {
+ if (cul_screenline && wlv.vcol >= left_curline_col && wlv.vcol < right_curline_col) {
apply_cursorline_highlight(wp, &wlv);
}
@@ -1690,7 +1611,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
&& wp == curwin
&& lnum == wp->w_cursor.lnum
&& wlv.vcol >= wp->w_virtcol)
- || (number_only && wlv.draw_state > WL_STC))
+ || number_only)
&& wlv.filler_todo <= 0) {
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
// don't clear anything after wlv.col
@@ -1705,15 +1626,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
break;
}
- const bool draw_folded = wlv.draw_state == WL_LINE && has_fold
- && wlv.row == startrow + wlv.filler_lines;
+ const bool draw_folded = has_fold && wlv.row == startrow + wlv.filler_lines;
if (draw_folded && wlv.n_extra == 0) {
wlv.char_attr = folded_attr = win_hl_attr(wp, HLF_FL);
}
int extmark_attr = 0;
- if (wlv.draw_state == WL_LINE
- && (area_highlighting || spv->spv_has_spell || extra_check)) {
+ if (area_highlighting || spv->spv_has_spell || extra_check) {
if (wlv.n_extra == 0 || !wlv.extra_for_extmark) {
wlv.reset_extra_attr = false;
}
@@ -1740,7 +1659,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
decor_recheck_draw_col(wlv.off, selected, &decor_state);
decor_need_recheck = false;
}
- extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state);
+ if (wlv.filler_todo <= 0) {
+ extmark_attr = decor_redraw_col(wp, (colnr_T)v, wlv.off, selected, &decor_state);
+ }
if (!has_fold && wp->w_buffer->b_virt_text_inline > 0) {
handle_inline_virtual_text(wp, &wlv, v);
@@ -1924,28 +1845,31 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
// Only restore search_attr and area_attr after "n_extra" in
// the next screen line is also done.
if (wlv.n_extra <= 0) {
- if (wlv.saved_n_extra <= 0) {
- if (search_attr == 0) {
- search_attr = saved_search_attr;
- saved_search_attr = 0;
- }
- if (area_attr == 0 && *ptr != NUL) {
- area_attr = saved_area_attr;
- saved_area_attr = 0;
- }
- if (decor_attr == 0) {
- decor_attr = saved_decor_attr;
- saved_decor_attr = 0;
- }
+ if (search_attr == 0) {
+ search_attr = saved_search_attr;
+ saved_search_attr = 0;
+ }
+ if (area_attr == 0 && *ptr != NUL) {
+ area_attr = saved_area_attr;
+ saved_area_attr = 0;
+ }
+ if (decor_attr == 0) {
+ decor_attr = saved_decor_attr;
+ saved_decor_attr = 0;
+ }
- if (wlv.extra_for_extmark) {
- // wlv.extra_attr should be used at this position but not
- // any further.
- wlv.reset_extra_attr = true;
- }
+ if (wlv.extra_for_extmark) {
+ // wlv.extra_attr should be used at this position but not
+ // any further.
+ wlv.reset_extra_attr = true;
}
wlv.extra_for_extmark = false;
}
+ } else if (wlv.filler_todo > 0) {
+ // Wait with reading text until filler lines are done. Still need to
+ // initialize these.
+ mb_c = ' ';
+ mb_schar = schar_from_ascii(' ');
} else if (has_fold) {
// skip writing the buffer line itself
mb_c = NUL;
@@ -2519,7 +2443,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
// In the cursor line and we may be concealing characters: correct
// the cursor column when we reach its position.
- if (!did_wcol && wlv.draw_state == WL_LINE
+ if (!did_wcol
&& wp == curwin && lnum == wp->w_cursor.lnum
&& conceal_cursor_line(wp)
&& (int)wp->w_virtcol <= wlv.vcol + wlv.skip_cells) {
@@ -2530,7 +2454,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
// Don't override visual selection highlighting.
- if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && !search_attr_from_match) {
+ if (wlv.n_attr > 0 && !search_attr_from_match) {
wlv.char_attr = hl_combine_attr(wlv.char_attr, wlv.extra_attr);
if (wlv.reset_extra_attr) {
wlv.reset_extra_attr = false;
@@ -2547,7 +2471,6 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
&& wp->w_p_list
&& (wp->w_p_wrap ? (wp->w_skipcol > 0 && wlv.row == 0) : wp->w_leftcol > 0)
&& wlv.filler_todo <= 0
- && wlv.draw_state > WL_STC
&& mb_c != NUL) {
mb_c = wp->w_p_lcs_chars.prec;
lcs_prec_todo = NUL;
@@ -2638,9 +2561,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
wlv.col -= wlv.boguscols;
wlv.boguscols = 0;
- if (draw_color_col) {
- draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- }
+ advance_color_col(&wlv, vcol_hlc(wlv));
bool has_virttext = false;
// Make sure alignment is the same regardless
@@ -2653,10 +2574,10 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
if (((wp->w_p_cuc
- && wp->w_virtcol >= VCOL_HLC - eol_hl_off
+ && wp->w_virtcol >= vcol_hlc(wlv) - eol_hl_off
&& wp->w_virtcol < grid->cols * (ptrdiff_t)(wlv.row - startrow + 1) + v
&& lnum != wp->w_cursor.lnum)
- || draw_color_col || wlv.line_attr_lowprio || wlv.line_attr
+ || wlv.color_cols || wlv.line_attr_lowprio || wlv.line_attr
|| wlv.diff_hlf != 0 || has_virttext)) {
int rightmost_vcol = 0;
@@ -2664,11 +2585,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
rightmost_vcol = wp->w_virtcol;
}
- if (draw_color_col) {
+ if (wlv.color_cols) {
// determine rightmost colorcolumn to possibly draw
- for (int i = 0; color_cols[i] >= 0; i++) {
- if (rightmost_vcol < color_cols[i]) {
- rightmost_vcol = color_cols[i];
+ for (int i = 0; wlv.color_cols[i] >= 0; i++) {
+ if (rightmost_vcol < wlv.color_cols[i]) {
+ rightmost_vcol = wlv.color_cols[i];
}
}
}
@@ -2693,15 +2614,13 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
linebuf_char[wlv.off] = schar_from_ascii(' ');
linebuf_vcol[wlv.off] = MAXCOL;
wlv.col++;
- if (draw_color_col) {
- draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- }
+ advance_color_col(&wlv, vcol_hlc(wlv));
int col_attr = base_attr;
- if (wp->w_p_cuc && VCOL_HLC == wp->w_virtcol) {
+ if (wp->w_p_cuc && vcol_hlc(wlv) == wp->w_virtcol) {
col_attr = cuc_attr;
- } else if (draw_color_col && VCOL_HLC == *color_cols) {
+ } else if (wlv.color_cols && vcol_hlc(wlv) == *wlv.color_cols) {
col_attr = hl_combine_attr(wlv.line_attr_lowprio, mc_attr);
}
@@ -2710,7 +2629,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
linebuf_attr[wlv.off] = col_attr;
wlv.off++;
- if (VCOL_HLC >= rightmost_vcol) {
+ if (vcol_hlc(wlv) >= rightmost_vcol) {
break;
}
@@ -2747,13 +2666,20 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW);
conceal_cursor_used = conceal_cursor_line(curwin);
}
+
+ // When the window is too narrow draw all "@" lines.
+ if (leftcols_width >= wp->w_grid.cols && wp->w_p_wrap) {
+ win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT);
+ set_empty_rows(wp, wlv.row);
+ wlv.row = endrow;
+ }
+
break;
}
// Show "extends" character from 'listchars' if beyond the line end and
// 'list' is set.
if (wp->w_p_lcs_chars.ext != NUL
- && wlv.draw_state == WL_LINE
&& wp->w_p_list
&& !wp->w_p_wrap
&& wlv.filler_todo <= 0
@@ -2773,47 +2699,38 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
}
- // advance to the next 'colorcolumn'
- if (draw_color_col) {
- draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- }
+ advance_color_col(&wlv, vcol_hlc(wlv));
// Highlight the cursor column if 'cursorcolumn' is set. But don't
// highlight the cursor position itself.
// Also highlight the 'colorcolumn' if it is different than
// 'cursorcolumn'
- // Also highlight the 'colorcolumn' if 'breakindent' and/or 'showbreak'
- // options are set
vcol_save_attr = -1;
- if ((wlv.draw_state == WL_LINE
- || wlv.draw_state == WL_BRI
- || wlv.draw_state == WL_SBR)
- && !lnum_in_visual_area
+ if (!lnum_in_visual_area
&& search_attr == 0
&& area_attr == 0
&& wlv.filler_todo <= 0) {
- if (wp->w_p_cuc && VCOL_HLC == wp->w_virtcol
+ if (wp->w_p_cuc && vcol_hlc(wlv) == wp->w_virtcol
&& lnum != wp->w_cursor.lnum) {
vcol_save_attr = wlv.char_attr;
wlv.char_attr = hl_combine_attr(win_hl_attr(wp, HLF_CUC), wlv.char_attr);
- } else if (draw_color_col && VCOL_HLC == *color_cols) {
+ } else if (wlv.color_cols && vcol_hlc(wlv) == *wlv.color_cols) {
vcol_save_attr = wlv.char_attr;
wlv.char_attr = hl_combine_attr(win_hl_attr(wp, HLF_MC), wlv.char_attr);
}
}
// Apply lowest-priority line attr now, so everything can override it.
- if (wlv.draw_state == WL_LINE) {
- wlv.char_attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.char_attr);
- }
+ wlv.char_attr = hl_combine_attr(wlv.line_attr_lowprio, wlv.char_attr);
- if (wlv.draw_state == WL_LINE) {
- vcol_prev = wlv.vcol;
- }
+ vcol_prev = wlv.vcol;
// Store character to be displayed.
// Skip characters that are left of the screen for 'nowrap'.
- if (wlv.draw_state < WL_LINE || wlv.skip_cells <= 0) {
+ if (wlv.filler_todo > 0) {
+ // TODO(bfredl): the main render loop should get called also with the virtual
+ // lines chunks, so we get line wrapping and other Nice Things.
+ } else if (wlv.skip_cells <= 0) {
// Store the character.
linebuf_char[wlv.off] = mb_schar;
if (multi_attr) {
@@ -2823,18 +2740,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
linebuf_attr[wlv.off] = wlv.char_attr;
}
- if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) {
- linebuf_vcol[wlv.off] = wlv.vcol;
- } else if (wlv.draw_state == WL_FOLD) {
- if (wlv.n_closing > 0) {
- linebuf_vcol[wlv.off] = -3;
- wlv.n_closing--;
- } else {
- linebuf_vcol[wlv.off] = -2;
- }
- } else {
- linebuf_vcol[wlv.off] = -1;
- }
+ linebuf_vcol[wlv.off] = wlv.vcol;
if (utf_char2cells(mb_c) > 1) {
// Need to fill two screen columns.
@@ -2844,11 +2750,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
linebuf_char[wlv.off] = 0;
linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1];
- if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) {
- linebuf_vcol[wlv.off] = ++wlv.vcol;
- } else {
- linebuf_vcol[wlv.off] = -1;
- }
+ linebuf_vcol[wlv.off] = ++wlv.vcol;
// When "wlv.tocol" is halfway through a character, set it to the end
// of the character, otherwise highlighting won't stop.
@@ -2904,15 +2806,14 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
// The skipped cells need to be accounted for in vcol.
- if (wlv.draw_state > WL_STC && wlv.skipped_cells > 0) {
+ if (wlv.skipped_cells > 0) {
wlv.vcol += wlv.skipped_cells;
wlv.skipped_cells = 0;
}
// Only advance the "wlv.vcol" when after the 'number' or
// 'relativenumber' column.
- if (wlv.draw_state > WL_STC
- && wlv.filler_todo <= 0) {
+ if (wlv.filler_todo <= 0) {
wlv.vcol++;
}
@@ -2921,12 +2822,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
// restore attributes after "predeces" in 'listchars'
- if (wlv.draw_state > WL_STC && n_attr3 > 0 && --n_attr3 == 0) {
+ if (n_attr3 > 0 && --n_attr3 == 0) {
wlv.char_attr = saved_attr3;
}
// restore attributes after last 'listchars' or 'number' char
- if (wlv.n_attr > 0 && wlv.draw_state == WL_LINE && --wlv.n_attr == 0) {
+ if (wlv.n_attr > 0 && --wlv.n_attr == 0) {
wlv.char_attr = saved_attr2;
}
@@ -2947,8 +2848,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
// At end of screen line and there is more to come: Display the line
// so far. If there is no more to display it is caught above.
if (wlv.col >= grid->cols && (!has_fold || virt_line_offset >= 0)
- && (wlv.draw_state != WL_LINE
- || *ptr != NUL
+ && (*ptr != NUL
|| wlv.filler_todo > 0
|| (wp->w_p_list && wp->w_p_lcs_chars.eol != NUL
&& wlv.p_extra != at_end_str)
@@ -2992,7 +2892,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
// When the window is too narrow draw all "@" lines.
- if (wlv.draw_state != WL_LINE && wlv.filler_todo <= 0) {
+ if (wlv.col <= leftcols_width) {
win_draw_end(wp, '@', ' ', true, wlv.row, wp->w_grid.rows, HLF_AT);
set_empty_rows(wp, wlv.row);
wlv.row = endrow;
@@ -3005,6 +2905,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
}
win_line_start(wp, &wlv, true);
+ draw_cols = true;
lcs_prec_todo = wp->w_p_lcs_chars.prec;
if (wlv.filler_todo <= 0) {
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index b52142f721..41ec4572ee 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -27,6 +27,7 @@
#include "nvim/fold.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
+#include "nvim/grid.h"
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/macros_defs.h"
@@ -105,7 +106,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr
DecorSignHighlight sign = DECOR_SIGN_HIGHLIGHT_INIT;
sign.flags |= kSHIsSign;
- sign.text.ptr = sp->sn_text ? xstrdup(sp->sn_text) : NULL;
+ memcpy(sign.text, sp->sn_text, SIGN_WIDTH * sizeof(schar_T));
sign.sign_name = xstrdup(sp->sn_name);
sign.hl_id = sp->sn_text_hl;
sign.line_hl_id = sp->sn_line_hl;
@@ -114,7 +115,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr
sign.priority = (DecorPriority)prio;
bool has_hl = (sp->sn_line_hl || sp->sn_num_hl || sp->sn_cul_hl);
- uint16_t decor_flags = (sp->sn_text ? MT_FLAG_DECOR_SIGNTEXT : 0)
+ uint16_t decor_flags = (sp->sn_text[0] ? MT_FLAG_DECOR_SIGNTEXT : 0)
| (has_hl ? MT_FLAG_DECOR_SIGNHL : 0);
DecorInline decor = { .ext = true, .data.ext = { .vt = NULL, .sh_idx = decor_put_sh(sign) } };
@@ -334,9 +335,24 @@ static int sign_cmd_idx(char *begin_cmd, char *end_cmd)
return idx;
}
+/// buf must be SIGN_WIDTH * MAX_SCHAR_SIZE (no extra +1 needed)
+size_t describe_sign_text(char *buf, schar_T *sign_text)
+{
+ size_t p = 0;
+ for (int i = 0; i < SIGN_WIDTH; i++) {
+ schar_get(buf + p, sign_text[i]);
+ size_t len = strlen(buf + p);
+ if (len == 0) {
+ break;
+ }
+ p += len;
+ }
+ return p;
+}
+
/// Initialize the "text" for a new sign and store in "sign_text".
/// "sp" is NULL for signs added through nvim_buf_set_extmark().
-int init_sign_text(sign_T *sp, char **sign_text, char *text)
+int init_sign_text(sign_T *sp, schar_T *sign_text, char *text)
{
char *s;
char *endp = text + (int)strlen(text);
@@ -351,34 +367,29 @@ int init_sign_text(sign_T *sp, char **sign_text, char *text)
// Count cells and check for non-printable chars
int cells = 0;
for (s = text; s < endp; s += utfc_ptr2len(s)) {
- if (!vim_isprintc(utf_ptr2char(s))) {
+ int c;
+ sign_text[cells] = utfc_ptr2schar(s, &c);
+ if (!vim_isprintc(c)) {
break;
}
- cells += utf_ptr2cells(s);
+ int width = utf_char2cells(c);
+ if (width == 2) {
+ sign_text[cells + 1] = 0;
+ }
+ cells += width;
}
// Currently must be empty, one or two display cells
- if (s != endp || cells > 2) {
+ if (s != endp || cells > SIGN_WIDTH) {
if (sp != NULL) {
semsg(_("E239: Invalid sign text: %s"), text);
}
return FAIL;
}
- if (cells < 1) {
- if (sp != NULL) {
- sp->sn_text = NULL;
- }
- return OK;
- }
- if (sp != NULL) {
- xfree(sp->sn_text);
- }
- // Allocate one byte more if we need to pad up with a space.
- size_t len = (size_t)(endp - text + (cells == 1));
- *sign_text = xstrnsave(text, len);
-
- if (cells == 1) {
- STRCPY(*sign_text + len - 1, " ");
+ if (cells < 1) {
+ sign_text[0] = 0;
+ } else if (cells == 1) {
+ sign_text[1] = schar_from_ascii(' ');
}
return OK;
@@ -412,7 +423,7 @@ static int sign_define_by_name(char *name, char *icon, char *text, char *linehl,
backslash_halve((*sp)->sn_icon);
}
- if (text != NULL && (init_sign_text(*sp, &(*sp)->sn_text, text) == FAIL)) {
+ if (text != NULL && (init_sign_text(*sp, (*sp)->sn_text, text) == FAIL)) {
return FAIL;
}
@@ -437,7 +448,6 @@ static int sign_undefine_by_name(const char *name)
}
xfree(sp->sn_name);
- xfree(sp->sn_text);
xfree(sp->sn_icon);
xfree(sp);
return OK;
@@ -452,9 +462,11 @@ static void sign_list_defined(sign_T *sp)
msg_outtrans(sp->sn_icon, 0);
msg_puts(_(" (not supported)"));
}
- if (sp->sn_text != NULL) {
+ if (sp->sn_text[0]) {
msg_puts(" text=");
- msg_outtrans(sp->sn_text, 0);
+ char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
+ describe_sign_text(buf, sp->sn_text);
+ msg_outtrans(buf, 0);
}
static char *arg[] = { " linehl=", " texthl=", " culhl=", " numhl=" };
int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl };
@@ -881,8 +893,10 @@ static dict_T *sign_get_info_dict(sign_T *sp)
if (sp->sn_icon != NULL) {
tv_dict_add_str(d, S_LEN("icon"), sp->sn_icon);
}
- if (sp->sn_text != NULL) {
- tv_dict_add_str(d, S_LEN("text"), sp->sn_text);
+ if (sp->sn_text[0]) {
+ char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
+ describe_sign_text(buf, sp->sn_text);
+ tv_dict_add_str(d, S_LEN("text"), buf);
}
static char *arg[] = { "linehl", "texthl", "culhl", "numhl" };
int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl };
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 79d21585fc..7676fa5319 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -1,8 +1,10 @@
#pragma once
+#include "nvim/types_defs.h"
+
/// Sign attributes. Used by the screen refresh routines.
typedef struct {
- char *text;
+ schar_T text[SIGN_WIDTH];
int hl_id;
} SignTextAttrs;
@@ -10,13 +12,12 @@ typedef struct {
typedef struct sign {
char *sn_name; // name of sign
char *sn_icon; // name of pixmap
- char *sn_text; // text used instead of pixmap
+ schar_T sn_text[SIGN_WIDTH]; // text used instead of pixmap
int sn_line_hl; // highlight ID for line
int sn_text_hl; // highlight ID for text
int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set
int sn_num_hl; // highlight ID for line number
} sign_T;
-enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn
enum { SIGN_SHOW_MAX = 9, }; ///< Maximum number of signs shown on a single line
enum { SIGN_DEF_PRIO = 10, }; ///< Default sign highlight priority
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
index 01729bc4de..b0d3988ce6 100644
--- a/src/nvim/statusline.c
+++ b/src/nvim/statusline.c
@@ -1641,20 +1641,32 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
char *p = NULL;
if (fold) {
- size_t n = fill_foldcolumn(out_p, wp, stcp->foldinfo,
- (linenr_T)get_vim_var_nr(VV_LNUM), NULL);
+ 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);
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++) {
+ schar_get(out_p + buflen, fold_buf[i]);
+ buflen += strlen(out_p + buflen);
+ }
p = out_p;
- p[n] = NUL;
}
+ char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
size_t buflen = 0;
varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM);
for (int i = 0; i < width; i++) {
if (!fold) {
SignTextAttrs *sattr = virtnum ? NULL : &stcp->sattrs[i];
- p = sattr && sattr->text ? sattr->text : " ";
- stl_items[curitem].minwid = -(sattr && sattr->text
+ p = " ";
+ if (sattr && sattr->text[0]) {
+ describe_sign_text(buf, sattr->text);
+ p = buf;
+ }
+ stl_items[curitem].minwid = -(sattr && sattr->text[0]
? (stcp->sign_cul_id ? stcp->sign_cul_id : sattr->hl_id)
: (stcp->use_cul ? HLF_CLS : HLF_SC) + 1);
}
diff --git a/src/nvim/types_defs.h b/src/nvim/types_defs.h
index cc9deb9630..81845eecdb 100644
--- a/src/nvim/types_defs.h
+++ b/src/nvim/types_defs.h
@@ -56,6 +56,8 @@ typedef struct {
} SignRange;
#define SIGNRANGE_INIT { 0, 0 }
+enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn
+
typedef struct file_buffer buf_T;
typedef struct syn_state synstate_T;
typedef struct terminal Terminal;
diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua
index d47c4ae230..57b11240dc 100644
--- a/test/functional/ui/sign_spec.lua
+++ b/test/functional/ui/sign_spec.lua
@@ -389,8 +389,8 @@ describe('Signs', function()
feed('gg100aa<Esc>')
screen:expect([[
{1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
- aa^a |
+ {8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
+ {8: }aa^a |
{8: 2 }b |
{6: 3 }c |
{6: 4 } |
@@ -404,10 +404,10 @@ describe('Signs', function()
feed('<C-Y>')
-- number column on virtual lines should be empty
screen:expect([[
- VIRT LINES |
+ {6: }VIRT LINES |
{1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
- aa^a |
+ {8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
+ {8: }aa^a |
{8: 2 }b |
{6: 3 }c |
{6: 4 } |