diff options
-rw-r--r-- | src/nvim/drawline.c | 15 | ||||
-rw-r--r-- | src/nvim/grid.c | 3 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 76 |
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() |