mirror of
https://github.com/neovim/neovim.git
synced 2026-08-26 17:11:48 +00:00
feat(extmark): virt_lines can highlight until EOL #41289
This commit is contained in:
@@ -3356,7 +3356,9 @@ nvim_buf_set_extmark({buf}, {ns_id}, {line}, {col}, {opts})
|
||||
'wrap' and 'linebreak' options do not take effect, so the
|
||||
number of extra screen lines will match the list-size (but
|
||||
see `virt_lines_overflow`). By default lines are placed
|
||||
below the marked line.
|
||||
below the marked line. Special case: If the last
|
||||
`text_chunk` is empty, the corresponding `hl` will extend
|
||||
to the end of the line.
|
||||
• virt_lines_above: Place virtual lines above instead.
|
||||
• virt_lines_leftcol: Place virtual lines in the leftmost
|
||||
column of the window, bypassing sign and number columns.
|
||||
|
||||
@@ -228,6 +228,8 @@ API
|
||||
• |nvim_buf_set_extmark()| `virt_lines_overflow` accepts "wrap" to enable
|
||||
wrapping onto extra rows and "auto" which enables horizontal scrolling when
|
||||
'nowrap' is set and wrapping when 'wrap' is set.
|
||||
• |nvim_buf_set_extmark()| `virt_lines` can extend the last `hl` in each `virt_line`
|
||||
till the end of the line.
|
||||
• |nvim_set_option_value()| accepts a new `operation` field to modify the
|
||||
existing option value.
|
||||
• |nvim_set_option_value()| returns the new option value.
|
||||
|
||||
3
runtime/lua/vim/_meta/api.gen.lua
generated
3
runtime/lua/vim/_meta/api.gen.lua
generated
@@ -671,7 +671,8 @@ function vim.api.nvim_buf_line_count(buf) end
|
||||
--- display of the text, except 'tabstop' is used for hard tabs. The 'wrap' and
|
||||
--- 'linebreak' options do not take effect, so the number of extra screen lines will
|
||||
--- match the list-size (but see `virt_lines_overflow`). By default lines are placed
|
||||
--- below the marked line.
|
||||
--- below the marked line. Special case: If the last `text_chunk` is empty,
|
||||
--- the corresponding `hl` will extend to the end of the line.
|
||||
--- - virt_lines_above: Place virtual lines above instead.
|
||||
--- - virt_lines_leftcol: Place virtual lines in the leftmost column of the window,
|
||||
--- bypassing sign and number columns.
|
||||
|
||||
@@ -247,6 +247,12 @@ function Completor:show(hint)
|
||||
col = col + skip - 1
|
||||
|
||||
local virt_lines = { unpack(lines, 2) }
|
||||
for i, s in ipairs(virt_lines) do
|
||||
if #s == 1 and s[1][1] == '' then
|
||||
virt_lines[i] = {}
|
||||
end
|
||||
end
|
||||
|
||||
api.nvim_buf_set_extmark(self.bufnr, namespace, row, col, {
|
||||
virt_text = virt_text,
|
||||
virt_lines = virt_lines,
|
||||
|
||||
@@ -457,7 +457,8 @@ ArrayOf(DictAs(get_extmark_item)) nvim_buf_get_extmarks(Buffer buf, Integer ns_i
|
||||
/// display of the text, except 'tabstop' is used for hard tabs. The 'wrap' and
|
||||
/// 'linebreak' options do not take effect, so the number of extra screen lines will
|
||||
/// match the list-size (but see `virt_lines_overflow`). By default lines are placed
|
||||
/// below the marked line.
|
||||
/// below the marked line. Special case: If the last `text_chunk` is empty,
|
||||
/// the corresponding `hl` will extend to the end of the line.
|
||||
/// - virt_lines_above: Place virtual lines above instead.
|
||||
/// - virt_lines_leftcol: Place virtual lines in the leftmost column of the window,
|
||||
/// bypassing sign and number columns.
|
||||
|
||||
@@ -361,7 +361,7 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
|
||||
if (vt) {
|
||||
int vcol = item->draw_col - col_off;
|
||||
int col = draw_virt_text_item(buf, item->draw_col, vt->data.virt_text,
|
||||
vt->hl_mode, max_col, vcol, 0);
|
||||
vt->hl_mode, max_col, vcol, 0, false);
|
||||
if (do_eol && ((vt->pos == kVPosEndOfLine) || (vt->pos == kVPosEndOfLineRightAlign))) {
|
||||
state->eol_col = col + 1;
|
||||
}
|
||||
@@ -373,14 +373,20 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
|
||||
}
|
||||
}
|
||||
|
||||
/// @param eol_hl Extend highlight to EOL.
|
||||
static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col,
|
||||
int vcol, int skip_cells)
|
||||
int vcol, int skip_cells, bool eol_hl)
|
||||
{
|
||||
const char *virt_str = "";
|
||||
int virt_attr = 0;
|
||||
size_t virt_pos = 0;
|
||||
eol_hl &= kv_size(vt) && *kv_A(vt, kv_size(vt) - 1).text == NUL;
|
||||
|
||||
while (col < max_col) {
|
||||
// extending last highlight till the end of line
|
||||
if (eol_hl && *virt_str == NUL && virt_pos == kv_size(vt)) {
|
||||
virt_str = " ";
|
||||
}
|
||||
if (skip_cells >= 0 && *virt_str == NUL) {
|
||||
if (virt_pos >= kv_size(vt)) {
|
||||
break;
|
||||
@@ -2983,7 +2989,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, b
|
||||
}
|
||||
|
||||
if (kv_size(fold_vt) > 0) {
|
||||
draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, view_width, 0, 0);
|
||||
draw_virt_text_item(buf, win_col_offset, fold_vt, kHlModeCombine, view_width, 0, 0, false);
|
||||
}
|
||||
draw_virt_text(wp, buf, win_col_offset, &wlv.col, wlv.row);
|
||||
// Set increasing virtual columns in grid->vcols[] to set correct curswant
|
||||
@@ -3261,7 +3267,7 @@ end_check:
|
||||
kHlModeReplace,
|
||||
view_width,
|
||||
0,
|
||||
virt_line_skip_cells);
|
||||
virt_line_skip_cells, true);
|
||||
} else if (wlv.filler_todo <= 0) {
|
||||
draw_virt_text(wp, buf, win_col_offset, &draw_col, wlv.row);
|
||||
}
|
||||
|
||||
@@ -7276,6 +7276,82 @@ if (h->n_buckets < new_n_buckets) { // expand
|
||||
]])
|
||||
end)
|
||||
|
||||
it('highlight till eol with virt_lines_overflow=trunc', function()
|
||||
insert('line1')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {
|
||||
virt_lines = { { { 'VIRT LINE1', 'String' }, { '', 'Visual' } }, { { 'VIRT LINE2', 'String' } } },
|
||||
})
|
||||
screen:expect([[
|
||||
line^1 |
|
||||
{26:VIRT LINE1}{17: }|
|
||||
{26:VIRT LINE2} |
|
||||
{1:~ }|*8
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('highlight till eol with virt_lines_overflow=wrap', function()
|
||||
insert('line1')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {
|
||||
virt_lines = { { { 'VIRT LINE', 'String' }, { string.rep('-', 50), 'Visual' }, { '', 'Visual' } } },
|
||||
virt_lines_overflow = 'wrap',
|
||||
})
|
||||
screen:expect([[
|
||||
line^1 |
|
||||
{26:VIRT LINE}{17:-----------------------------------------}|
|
||||
{17:--------- }|
|
||||
{1:~ }|*8
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('highlight till eol with virt_lines_overflow=scroll', function()
|
||||
command('set nowrap')
|
||||
insert('abcdefghijklmnopqrstuvwxyz')
|
||||
api.nvim_buf_set_extmark(0, ns, 0, 0, {
|
||||
virt_lines = { { { 'VIRT LINE', 'String' }, { '', 'Visual' } } },
|
||||
virt_lines_overflow = 'scroll',
|
||||
})
|
||||
screen:expect([[
|
||||
abcdefghijklmnopqrstuvwxy^z |
|
||||
{26:VIRT LINE}{17: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
bcdefghijklmnopqrstuvwxy^z |
|
||||
{26:IRT LINE}{17: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
cdefghijklmnopqrstuvwxy^z |
|
||||
{26:RT LINE}{17: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
|
||||
feed('6zl')
|
||||
screen:expect([[
|
||||
ijklmnopqrstuvwxy^z |
|
||||
{26:E}{17: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
|
||||
feed('zl')
|
||||
screen:expect([[
|
||||
jklmnopqrstuvwxy^z |
|
||||
{17: }|
|
||||
{1:~ }|*9
|
||||
|
|
||||
]])
|
||||
end)
|
||||
|
||||
it('does not show twice if end_row or end_col is specified #18622', function()
|
||||
screen:try_resize(50, 8)
|
||||
insert([[
|
||||
|
||||
Reference in New Issue
Block a user