decorations: right_align and win_col

This commit is contained in:
Björn Linse
2021-04-15 20:57:23 +02:00
parent 59eae3b38f
commit 0865f1238f
5 changed files with 227 additions and 60 deletions

View File

@@ -2101,6 +2101,7 @@ 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; // offsett for window columns
char_u buf_fold[FOLD_TEXT_LEN + 1]; // Hold value returned by get_foldtext
@@ -2790,6 +2791,10 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
if (draw_state == WL_NR && n_extra == 0) {
win_col_offset = off;
}
if (wp->w_briopt_sbr && draw_state == WL_BRI - 1
&& n_extra == 0 && *p_sbr != NUL) {
// draw indent after showbreak value
@@ -2904,7 +2909,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& vcol >= (long)wp->w_virtcol)
|| (number_only && draw_state > WL_NR))
&& filler_todo <= 0) {
draw_virt_text(buf, &col, grid->Columns);
draw_virt_text(buf, win_col_offset, &col, grid->Columns);
grid_put_linebuf(grid, row, 0, col, -grid->Columns, wp->w_p_rl, wp,
wp->w_hl_attr_normal, false);
// Pretend we have finished updating the window. Except when
@@ -3945,13 +3950,15 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
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);
virt_text = decor_redraw_eol(wp->w_buffer, &decor_state, &line_attr,
&has_aligned);
if (kv_size(virt_text)) {
do_virttext = true;
}
@@ -3963,7 +3970,8 @@ 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)) {
|| diff_hlf != (hlf_T)0 || do_virttext
|| has_aligned)) {
int rightmost_vcol = 0;
int i;
@@ -4001,7 +4009,7 @@ 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) {
if (base_attr || line_attr || has_aligned) {
rightmost_vcol = INT_MAX;
}
@@ -4079,7 +4087,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
}
}
draw_virt_text(buf, &col, grid->Columns);
draw_virt_text(buf, win_col_offset, &col, grid->Columns);
grid_put_linebuf(grid, row, 0, col, grid->Columns, wp->w_p_rl, wp,
wp->w_hl_attr_normal, false);
row++;
@@ -4300,7 +4308,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
&& !wp->w_p_rl; // Not right-to-left.
int draw_col = col - boguscols;
draw_virt_text(buf, &draw_col, grid->Columns);
draw_virt_text(buf, win_col_offset, &draw_col, grid->Columns);
grid_put_linebuf(grid, row, 0, draw_col, grid->Columns, wp->w_p_rl,
wp, wp->w_hl_attr_normal, wrap);
if (wrap) {
@@ -4377,52 +4385,62 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow,
return row;
}
void draw_virt_text(buf_T *buf, int *end_col, int max_col)
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;
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)
&& item->decor.virt_text_pos == kVTOverlay
&& item->virt_col >= 0) {
VirtText vt = item->decor.virt_text;
HlMode hl_mode = item->decor.hl_mode;
LineState s = LINE_STATE("");
int virt_attr = 0;
int col = item->virt_col;
size_t virt_pos = 0;
item->virt_col = -2; // deactivate
while (col < max_col) {
if (!*s.p) {
if (virt_pos == kv_size(vt)) {
break;
}
s.p = kv_A(vt, virt_pos).text;
int hl_id = kv_A(vt, virt_pos).hl_id;
virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
virt_pos++;
continue;
}
int attr;
bool through = false;
if (hl_mode == kHlModeCombine) {
attr = hl_combine_attr(linebuf_attr[col], virt_attr);
} else if (hl_mode == kHlModeBlend) {
through = (*s.p == ' ');
attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
} else {
attr = virt_attr;
}
schar_T dummy[2];
int cells = line_putchar(&s, through ? dummy : &linebuf_char[col],
max_col-col, false);
linebuf_attr[col++] = attr;
if (cells > 1) {
linebuf_attr[col++] = attr;
}
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;
item->win_col = right_pos;
} else if (item->decor.virt_text_pos == kVTWinCol) {
item->win_col = MAX(item->decor.col+col_off, 0);
}
*end_col = MAX(*end_col, col);
}
if (item->win_col < 0) {
continue;
}
VirtText vt = item->decor.virt_text;
HlMode hl_mode = item->decor.hl_mode;
LineState s = LINE_STATE("");
int virt_attr = 0;
int col = item->win_col;
size_t virt_pos = 0;
item->win_col = -2; // deactivate
while (col < max_col) {
if (!*s.p) {
if (virt_pos == kv_size(vt)) {
break;
}
s.p = kv_A(vt, virt_pos).text;
int hl_id = kv_A(vt, virt_pos).hl_id;
virt_attr = hl_id > 0 ? syn_id2attr(hl_id) : 0;
virt_pos++;
continue;
}
int attr;
bool through = false;
if (hl_mode == kHlModeCombine) {
attr = hl_combine_attr(linebuf_attr[col], virt_attr);
} else if (hl_mode == kHlModeBlend) {
through = (*s.p == ' ');
attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
} else {
attr = virt_attr;
}
schar_T dummy[2];
int cells = line_putchar(&s, through ? dummy : &linebuf_char[col],
max_col-col, false);
linebuf_attr[col++] = attr;
if (cells > 1) {
linebuf_attr[col++] = attr;
}
}
*end_col = MAX(*end_col, col);
}
}
}