aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/drawline.c15
-rw-r--r--src/nvim/grid.c3
-rw-r--r--test/functional/ui/decorations_spec.lua76
3 files changed, 85 insertions, 9 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index 863d237062..67086b3248 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -342,12 +342,20 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
schar_T dummy[2];
int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
max_col - col, false, vcol);
- // if we failed to emit a char, we still need to advance
- cells = MAX(cells, 1);
-
+ // If we failed to emit a char, we still need to put a space and advance.
+ if (cells < 1) {
+ schar_from_ascii(linebuf_char[col], ' ');
+ cells = 1;
+ }
for (int c = 0; c < cells; c++) {
linebuf_attr[col++] = attr;
}
+ if (col < max_col && linebuf_char[col][0] == 0) {
+ // If the left half of a double-width char is overwritten,
+ // change the right half to a space so that grid redraws properly,
+ // but don't advance the current column.
+ schar_from_ascii(linebuf_char[col], ' ');
+ }
vcol += cells;
}
return col;
@@ -2806,6 +2814,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
wlv.col++;
// UTF-8: Put a 0 in the second screen char.
linebuf_char[wlv.off][0] = 0;
+ linebuf_attr[wlv.off] = linebuf_attr[wlv.off - 1];
if (wlv.draw_state > WL_STC && wlv.filler_todo <= 0) {
wlv.vcol++;
}
diff --git a/src/nvim/grid.c b/src/nvim/grid.c
index 037606c38f..76dd2a073a 100644
--- a/src/nvim/grid.c
+++ b/src/nvim/grid.c
@@ -316,8 +316,7 @@ int grid_puts_len(ScreenGrid *grid, const char *text, int textlen, int row, int
// When at the start of the text and overwriting the right half of a
// two-cell character in the same grid, truncate that into a '>'.
if (ptr == text && col > 0 && grid->chars[off][0] == 0) {
- grid->chars[off - 1][0] = '>';
- grid->chars[off - 1][1] = 0;
+ schar_from_ascii(grid->chars[off - 1], '>');
}
schar_copy(grid->chars[off], buf);
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index ccf1810ee1..e31361e74c 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -704,14 +704,14 @@ end]]
-- can "float" beyond end of line
meths.buf_set_extmark(0, ns, 5, 28, { virt_text={{'loopy', 'ErrorMsg'}}, virt_text_pos='overlay'})
-- bound check: right edge of window
- meths.buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork '}, {'bork bork bork', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 2, 26, { virt_text={{'bork bork bork'}, {(' bork'):rep(10), 'ErrorMsg'}}, virt_text_pos='overlay'})
-- empty virt_text should not change anything
meths.buf_set_extmark(0, ns, 6, 16, { virt_text={{''}}, virt_text_pos='overlay'})
screen:expect{grid=[[
^for _,item in ipairs(items) do |
{2:|} local text, hl_id_cell, count = unpack(item) |
- {2:|} if hl_id_cell ~= nil tbork bork bork {4:bork bork}|
+ {2:|} if hl_id_cell ~= nil tbork bork bork{4: bork bork}|
{2:|} {1:|} hl_id = hl_id_cell |
{2:|} end |
{2:|} for _ = 1, (count or 1) {4:loopy} |
@@ -726,7 +726,6 @@ end]]
|
]]}
-
-- handles broken lines
screen:try_resize(22, 25)
screen:expect{grid=[[
@@ -736,7 +735,7 @@ end]]
cell, count = unpack(i|
tem) |
{2:|} if hl_id_cell ~= n|
- il tbork bork bork {4:bor}|
+ il tbork bork bork{4: bor}|
{2:|} {1:|} hl_id = hl_id_|
cell |
{2:|} end |
@@ -756,6 +755,75 @@ end]]
{1:~ }|
|
]]}
+
+ -- truncating in the middle of a char leaves a space
+ meths.buf_set_lines(0, 0, 1, true, {'for _,item in ipairs(items) do -- 古古古'})
+ meths.buf_set_lines(0, 10, 12, true, {' end -- ??????????', 'end -- ?古古古古?古古'})
+ meths.buf_set_extmark(0, ns, 0, 35, { virt_text={{'A', 'ErrorMsg'}, {'AA'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 10, 19, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 11, 21, { virt_text={{'口口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ meths.buf_set_extmark(0, ns, 11, 8, { virt_text={{'口口', 'ErrorMsg'}}, virt_text_pos='overlay'})
+ screen:expect{grid=[[
+ ^for _,item in ipairs(i|
+ tems) do -- {4:A}AA 古 |
+ {2:|} local text, hl_id_|
+ cell, count = unpack(i|
+ tem) |
+ {2:|} if hl_id_cell ~= n|
+ il tbork bork bork{4: bor}|
+ {2:|} {1:|} hl_id = hl_id_|
+ cell |
+ {2:|} end |
+ {2:|} for _ = 1, (count |
+ or 1) {4:loopy} |
+ {2:|} {1:|} local cell = l|
+ ine[colpos] |
+ {2:|} {1:|} cell.text = te|
+ xt |
+ {2:|} {1:|} cell.hl_id = h|
+ l_id |
+ {2:|} {1:|} cofoo{3:bar}{4:!!}olpo|
+ s+1 |
+ end -- ???????{4:口 }|
+ end -- {4:口口} 古古{4:口口 }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]]}
+
+ screen:try_resize(82, 13)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do -- {4:A}AA 古 |
+ {2:|} local text, hl_id_cell, count = unpack(item) |
+ {2:|} if hl_id_cell ~= nil tbork bork bork{4: bork bork bork bork bork bork bork bork b}|
+ {2:|} {1:|} hl_id = hl_id_cell |
+ {2:|} end |
+ {2:|} for _ = 1, (count or 1) {4:loopy} |
+ {2:|} {1:|} local cell = line[colpos] |
+ {2:|} {1:|} cell.text = text |
+ {2:|} {1:|} cell.hl_id = hl_id |
+ {2:|} {1:|} cofoo{3:bar}{4:!!}olpos+1 |
+ end -- ???????{4:口口口} |
+ end -- {4:口口} 古古{4:口口口} |
+ |
+ ]]}
+
+ meths.buf_clear_namespace(0, ns, 0, -1)
+ screen:expect{grid=[[
+ ^for _,item in ipairs(items) do -- 古古古 |
+ local text, hl_id_cell, count = unpack(item) |
+ if hl_id_cell ~= nil then |
+ hl_id = hl_id_cell |
+ end |
+ for _ = 1, (count or 1) do |
+ local cell = line[colpos] |
+ cell.text = text |
+ cell.hl_id = hl_id |
+ colpos = colpos+1 |
+ end -- ?????????? |
+ end -- ?古古古古?古古 |
+ |
+ ]]}
end)
it('can have virtual text of overlay position and styling', function()