mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 09:26:30 +00:00
feat(extmarks): add virt_text_repeat_linebreak flag (#26625)
Problem: Unable to predict which byte-offset to place virtual text to make it repeat visually in the wrapped part of a line. Solution: Add a flag to nvim_buf_set_extmark() that causes virtual text to repeat in wrapped lines.
This commit is contained in:
@@ -391,6 +391,8 @@ Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object e
|
||||
/// text is selected or hidden because of
|
||||
/// scrolling with 'nowrap' or 'smoothscroll'.
|
||||
/// Currently only affects "overlay" virt_text.
|
||||
/// - virt_text_repeat_linebreak : repeat the virtual text on
|
||||
/// wrapped lines.
|
||||
/// - hl_mode : control how highlights are combined with the
|
||||
/// highlights of the text. Currently only affects
|
||||
/// virt_text highlights, but might affect `hl_group`
|
||||
@@ -613,7 +615,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
}
|
||||
|
||||
hl.flags |= opts->hl_eol ? kSHHlEol : 0;
|
||||
virt_text.flags |= opts->virt_text_hide ? kVTHide : 0;
|
||||
virt_text.flags |= ((opts->virt_text_hide ? kVTHide : 0)
|
||||
| (opts->virt_text_repeat_linebreak ? kVTRepeatLinebreak : 0));
|
||||
|
||||
if (HAS_KEY(opts, set_extmark, hl_mode)) {
|
||||
String str = opts->hl_mode;
|
||||
|
@@ -33,6 +33,7 @@ typedef struct {
|
||||
String virt_text_pos;
|
||||
Integer virt_text_win_col;
|
||||
Boolean virt_text_hide;
|
||||
Boolean virt_text_repeat_linebreak;
|
||||
Boolean hl_eol;
|
||||
String hl_mode;
|
||||
Boolean invalidate;
|
||||
|
@@ -1061,11 +1061,11 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name)
|
||||
Array chunks = virt_text_to_array(virt_text->data.virt_text, hl_name);
|
||||
PUT(*dict, "virt_text", ARRAY_OBJ(chunks));
|
||||
PUT(*dict, "virt_text_hide", BOOLEAN_OBJ(virt_text->flags & kVTHide));
|
||||
PUT(*dict, "virt_text_repeat_linebreak", BOOLEAN_OBJ(virt_text->flags & kVTRepeatLinebreak));
|
||||
if (virt_text->pos == kVPosWinCol) {
|
||||
PUT(*dict, "virt_text_win_col", INTEGER_OBJ(virt_text->col));
|
||||
}
|
||||
PUT(*dict, "virt_text_pos",
|
||||
CSTR_TO_OBJ(virt_text_pos_str[virt_text->pos]));
|
||||
PUT(*dict, "virt_text_pos", CSTR_TO_OBJ(virt_text_pos_str[virt_text->pos]));
|
||||
priority = virt_text->priority;
|
||||
}
|
||||
|
||||
|
@@ -77,6 +77,7 @@ enum {
|
||||
kVTIsLines = 1,
|
||||
kVTHide = 2,
|
||||
kVTLinesAbove = 4,
|
||||
kVTRepeatLinebreak = 8,
|
||||
};
|
||||
|
||||
typedef struct DecorVirtText DecorVirtText;
|
||||
|
@@ -286,10 +286,12 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
|
||||
int vcol = item->draw_col - col_off;
|
||||
col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text,
|
||||
vt->hl_mode, max_col, vcol);
|
||||
if (vt->pos == kVPosEndOfLine && do_eol) {
|
||||
state->eol_col = col + 1;
|
||||
}
|
||||
}
|
||||
item->draw_col = INT_MIN; // deactivate
|
||||
if (vt && vt->pos == kVPosEndOfLine && do_eol) {
|
||||
state->eol_col = col + 1;
|
||||
if (!vt || !(vt->flags & kVTRepeatLinebreak)) {
|
||||
item->draw_col = INT_MIN; // deactivate
|
||||
}
|
||||
|
||||
*end_col = MAX(*end_col, col);
|
||||
@@ -1588,7 +1590,9 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool number_onl
|
||||
&& wlv.vcol >= wp->w_virtcol)
|
||||
|| number_only)
|
||||
&& wlv.filler_todo <= 0) {
|
||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
|
||||
if (!number_only) {
|
||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
|
||||
}
|
||||
// don't clear anything after wlv.col
|
||||
win_put_linebuf(wp, wlv.row, 0, wlv.col, wlv.col, bg_attr, false);
|
||||
// Pretend we have finished updating the window. Except when
|
||||
|
Reference in New Issue
Block a user