aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/screen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/screen.c')
-rw-r--r--src/nvim/screen.c112
1 files changed, 36 insertions, 76 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 586aeff1e2..d8f5f1077c 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -165,7 +165,7 @@ static bool resizing = false;
#endif
#define SEARCH_HL_PRIORITY 0
-static char * provider_first_error = NULL;
+static char * provider_err = NULL;
static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
Array args, bool default_true)
@@ -187,10 +187,10 @@ static bool provider_invoke(NS ns_id, const char *name, LuaRef ref,
const char *ns_name = describe_ns(ns_id);
ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
bool verbose_errs = true; // TODO(bfredl):
- if (verbose_errs && provider_first_error == NULL) {
+ if (verbose_errs && provider_err == NULL) {
static char errbuf[IOSIZE];
snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
- provider_first_error = xstrdup(errbuf);
+ provider_err = xstrdup(errbuf);
}
}
@@ -2103,7 +2103,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
bool search_attr_from_match = false; // if search_attr is from :match
bool has_decor = false; // this buffer has decoration
- bool do_virttext = false; // draw virtual text for this line
int win_col_offset = 0; // offset for window columns
char_u buf_fold[FOLD_TEXT_LEN + 1]; // Hold value returned by get_foldtext
@@ -2148,8 +2147,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
row = startrow;
- char *err_text = NULL;
-
buf_T *buf = wp->w_buffer;
if (!number_only) {
@@ -2194,14 +2191,20 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
- if (has_decor) {
- extra_check = true;
+ if (provider_err) {
+ Decoration err_decor = DECORATION_INIT;
+ int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
+ kv_push(err_decor.virt_text,
+ ((VirtTextChunk){ .text = provider_err,
+ .hl_id = hl_err }));
+ err_decor.virt_text_width = mb_string2cells((char_u *)provider_err);
+ decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
+ provider_err = NULL;
+ has_decor = true;
}
- if (provider_first_error) {
- err_text = provider_first_error;
- provider_first_error = NULL;
- do_virttext = true;
+ if (has_decor) {
+ extra_check = true;
}
// Check for columns to display for 'colorcolumn'.
@@ -3953,19 +3956,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
if (draw_color_col)
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
- VirtText virt_text = KV_INITIAL_VALUE;
- bool has_aligned = false;
- if (err_text) {
- int hl_err = syn_check_group((char_u *)S_LEN("ErrorMsg"));
- kv_push(virt_text, ((VirtTextChunk){ .text = err_text,
- .hl_id = hl_err }));
- do_virttext = true;
- } else if (has_decor) {
- virt_text = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
- &has_aligned);
- if (kv_size(virt_text)) {
- do_virttext = true;
- }
+ bool has_virttext = false;
+ // Make sure alignment is the same regardless
+ // if listchars=eol:X is used or not.
+ int eol_skip = (wp->w_p_lcs_chars.eol == lcs_eol_one && eol_hl_off == 0
+ ? 1 : 0);
+
+ if (has_decor) {
+ has_virttext = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
+ col + eol_skip);
}
if (((wp->w_p_cuc
@@ -3974,20 +3973,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
grid->Columns * (row - startrow + 1) + v
&& lnum != wp->w_cursor.lnum)
|| draw_color_col || line_attr_lowprio || line_attr
- || diff_hlf != (hlf_T)0 || do_virttext
- || has_aligned)) {
+ || diff_hlf != (hlf_T)0 || has_virttext)) {
int rightmost_vcol = 0;
int i;
- size_t virt_pos = 0;
- LineState s = LINE_STATE("");
- int virt_attr = 0;
-
- // Make sure alignment is the same regardless
- // if listchars=eol:X is used or not.
- bool delay_virttext = wp->w_p_lcs_chars.eol == lcs_eol_one
- && eol_hl_off == 0;
-
if (wp->w_p_cuc) {
rightmost_vcol = wp->w_virtcol;
}
@@ -4013,38 +4002,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
int base_attr = hl_combine_attr(line_attr_lowprio, diff_attr);
- if (base_attr || line_attr || has_aligned) {
+ if (base_attr || line_attr || has_virttext) {
rightmost_vcol = INT_MAX;
}
int col_stride = wp->w_p_rl ? -1 : 1;
while (wp->w_p_rl ? col >= 0 : col < grid->Columns) {
- int cells = -1;
- // TODO: integrate this whith the other virt_text impl already
- if (do_virttext && !delay_virttext) {
- if (*s.p == NUL) {
- if (virt_pos < virt_text.size) {
- s.p = kv_A(virt_text, virt_pos).text;
- int hl_id = kv_A(virt_text, virt_pos).hl_id;
- virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
- virt_pos++;
- } else {
- do_virttext = false;
- }
- }
- if (*s.p != NUL) {
- cells = line_putchar(&s, &linebuf_char[off], grid->Columns - col,
- false);
- }
- }
- delay_virttext = false;
-
- if (cells == -1) {
- schar_from_ascii(linebuf_char[off], ' ');
- cells = 1;
- }
- col += cells * col_stride;
+ schar_from_ascii(linebuf_char[off], ' ');
+ col += col_stride;
if (draw_color_col) {
draw_color_col = advance_color_col(VCOL_HLC, &color_cols);
}
@@ -4057,24 +4023,16 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
col_attr = mc_attr;
}
- if (do_virttext) {
- col_attr = hl_combine_attr(col_attr, virt_attr);
- }
-
col_attr = hl_combine_attr(col_attr, line_attr);
linebuf_attr[off] = col_attr;
- if (cells == 2) {
- linebuf_attr[off+1] = col_attr;
- }
- off += cells * col_stride;
+ off += col_stride;
- if (VCOL_HLC >= rightmost_vcol && *s.p == NUL
- && virt_pos >= virt_text.size) {
+ if (VCOL_HLC >= rightmost_vcol) {
break;
}
- vcol += cells;
+ vcol += 1;
}
}
@@ -4393,7 +4351,6 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
xfree(p_extra_free);
- xfree(err_text);
return row;
}
@@ -4401,13 +4358,17 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
{
DecorState *state = &decor_state;
int right_pos = max_col;
+ bool do_eol = state->eol_col > -1;
for (size_t i = 0; i < kv_size(state->active); i++) {
DecorRange *item = &kv_A(state->active, i);
if (item->start_row == state->row && kv_size(item->decor.virt_text)) {
if (item->win_col == -1) {
if (item->decor.virt_text_pos == kVTRightAlign) {
- right_pos -= item->decor.col;
+ right_pos -= item->decor.virt_text_width;
item->win_col = right_pos;
+ } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ item->win_col = state->eol_col;
+ state->eol_col += item->decor.virt_text_width;
} else if (item->decor.virt_text_pos == kVTWinCol) {
item->win_col = MAX(item->decor.col+col_off, 0);
}
@@ -4436,7 +4397,6 @@ void draw_virt_text(buf_T *buf, int col_off, int *end_col, int max_col)
hl_id > 0 ? syn_id2attr(hl_id) : 0);
virt_pos++;
} while (!s.p && virt_pos < kv_size(vt));
- // TODO: y w0t m8
if (!s.p) {
break;
}