diff options
-rw-r--r-- | src/nvim/drawline.c | 30 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 27 |
2 files changed, 53 insertions, 4 deletions
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c index c9ebcd8ed4..0ad03f940a 100644 --- a/src/nvim/drawline.c +++ b/src/nvim/drawline.c @@ -966,7 +966,11 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, int n_attr3 = 0; // chars with overruling special attr int saved_attr3 = 0; // char_attr saved for n_attr3 - int n_skip = 0; // nr of chars to skip for 'nowrap' + int n_skip = 0; // nr of chars to skip for 'nowrap' or + // concealing + int skip_cells = 0; // nr of cells to skip for virtual text + // after the line, when w_skipcol is + // larger than the text length int fromcol_prev = -2; // start of inverting after cursor bool noinvcur = false; // don't invert the cursor @@ -1434,6 +1438,12 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, } } + // If there the text doesn't reach to the desired column, need to skip + // "skip_cells" cells when virtual text follows. + if (!wp->w_p_wrap && v > wlv.vcol) { + skip_cells = (int)(v - wlv.vcol); + } + // Adjust for when the inverted text is before the screen, // and when the start of the inverted text is before the screen. if (wlv.tocol <= wlv.vcol) { @@ -1744,8 +1754,8 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, 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 != kVTInline) { + || !kv_size(item->decor.virt_text) + || item->decor.virt_text_pos != kVTInline) { continue; } if (item->win_col >= -1 && item->start_col == v) { @@ -1773,6 +1783,20 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange, area_attr = 0; extmark_attr = 0; virt_inline_i++; + // If the text didn't reach until the first window + // column we need to skip cells. + if (skip_cells > 0) { + if (wlv.n_extra > skip_cells) { + wlv.n_extra -= skip_cells; + wlv.p_extra += skip_cells; + skip_cells = 0; + } else { + // the whole text is left of the window, drop + // it and advance to the next one + skip_cells -= wlv.n_extra; + wlv.n_extra = 0; + } + } } } diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 68c0e5eaca..ba3f73c229 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -1742,7 +1742,7 @@ bbbbbbb]]) ]]} end) - it('no wrap is rendered correctly with multiple virtual text, where one is hidden', function() + it('draws correctly with no wrap multiple virtual text, where one is hidden', function() insert('abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz') command("set nowrap") meths.buf_set_extmark(0, ns, 0, 50, @@ -1768,6 +1768,31 @@ bbbbbbb]]) | ]]} end) + + it('draws correctly with no wrap and a long virtual text', function() + insert('abcdefghi') + command("set nowrap") + meths.buf_set_extmark(0, ns, 0, 2, + { virt_text = { { string.rep('X', 55), 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) + feed('$') + screen:expect { grid = [[ + {28:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}cdefgh^i| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + end) end) describe('decorations: virtual lines', function() |