diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-12-06 14:17:57 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-12-06 14:17:57 +0000 |
commit | 56a40fea9c28f8fc918a0db6de4c048da241cf32 (patch) | |
tree | 15a5a0949287b173557a778cf3ee92230975ab40 /src/drawline.c | |
parent | 7155fb6614f45a4e573bbfca23b5d150604ad506 (diff) |
patch 9.0.1019: 'smoothscroll' and virtual text above don't work togetherv9.0.1019
Problem: 'smoothscroll' and virtual text above don't work together.
(Yee Cheng Chin)
Solution: Skip virtual text above when w_skipcol is non-zero.
(closes #11665)
Diffstat (limited to 'src/drawline.c')
-rw-r--r-- | src/drawline.c | 107 |
1 files changed, 69 insertions, 38 deletions
diff --git a/src/drawline.c b/src/drawline.c index bde5ec8247..804b1005af 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -637,7 +637,8 @@ text_prop_position( int *n_extra, // nr of bytes for virtual text char_u **p_extra, // virtual text int *n_attr, // attribute cells, NULL if not used - int *n_attr_skip) // cells to skip attr, NULL if not used + int *n_attr_skip, // cells to skip attr, NULL if not used + int do_skip) // skip_cells is not zero { int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT); int above = (tp->tp_flags & TP_FLAG_ALIGN_ABOVE); @@ -690,6 +691,8 @@ text_prop_position( else n_used = *n_extra; } + else if (below && before > vcol && do_skip) + before -= vcol; else before = 0; } @@ -1500,15 +1503,75 @@ win_line( area_highlighting = TRUE; } + // When w_skipcol is non-zero and there is virtual text above the actual + // text, then this much of the virtual text is skipped. + int skipcol_in_text_prop_above = 0; + #ifdef FEAT_PROP_POPUP if (WIN_IS_POPUP(wp)) wlv.screen_line_flags |= SLF_POPUP; + + char_u *prop_start; + text_prop_count = get_text_props(wp->w_buffer, lnum, &prop_start, FALSE); + if (text_prop_count > 0) + { + // Make a copy of the properties, so that they are properly + // aligned. + text_props = ALLOC_MULT(textprop_T, text_prop_count); + if (text_props != NULL) + mch_memmove(text_props, prop_start, + text_prop_count * sizeof(textprop_T)); + + // Allocate an array for the indexes. + text_prop_idxs = ALLOC_MULT(int, text_prop_count); + if (text_prop_idxs == NULL) + VIM_CLEAR(text_props); + + if (text_props != NULL) + { + area_highlighting = TRUE; + extra_check = TRUE; + + // When skipping virtual text the props need to be sorted. The + // order is reversed! + if (lnum == wp->w_topline && wp->w_skipcol > 0) + { + for (int i = 0; i < text_prop_count; ++i) + text_prop_idxs[i] = i; + sort_text_props(wp->w_buffer, text_props, + text_prop_idxs, text_prop_count); + } + + // Text props "above" move the line number down to where the text + // is. Only count the ones that are visible, not those that are + // skipped because of w_skipcol. + int text_width = wp->w_width - win_col_off(wp); + for (int i = text_prop_count - 1; i >= 0; --i) + if (text_props[i].tp_flags & TP_FLAG_ALIGN_ABOVE) + { + if (lnum == wp->w_topline + && wp->w_skipcol - skipcol_in_text_prop_above + >= text_width) + { + // This virtual text above is skipped, remove it from + // the array. + skipcol_in_text_prop_above += text_width; + for (int j = i + 1; j < text_prop_count; ++j) + text_props[j - 1] = text_props[j]; + ++i; + --text_prop_count; + } + else + ++wlv.text_prop_above_count; + } + } + } #endif // 'nowrap' or 'wrap' and a single line that doesn't fit: Advance to the // first character to be displayed. if (wp->w_p_wrap) - v = startrow == 0 ? wp->w_skipcol : 0; + v = startrow == 0 ? wp->w_skipcol - skipcol_in_text_prop_above : 0; else v = wp->w_leftcol; if (v > 0 && !number_only) @@ -1559,7 +1622,8 @@ win_line( #ifdef FEAT_PROP_POPUP // 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) + if ((!wp->w_p_wrap || (lnum == wp->w_topline && wp->w_skipcol > 0)) + && v > wlv.vcol) skip_cells = v - wlv.vcol; #endif @@ -1703,40 +1767,6 @@ win_line( } #endif -#ifdef FEAT_PROP_POPUP - { - char_u *prop_start; - - text_prop_count = get_text_props(wp->w_buffer, lnum, - &prop_start, FALSE); - if (text_prop_count > 0) - { - // Make a copy of the properties, so that they are properly - // aligned. - text_props = ALLOC_MULT(textprop_T, text_prop_count); - if (text_props != NULL) - mch_memmove(text_props, prop_start, - text_prop_count * sizeof(textprop_T)); - - // Allocate an array for the indexes. - text_prop_idxs = ALLOC_MULT(int, text_prop_count); - if (text_prop_idxs == NULL) - VIM_CLEAR(text_props); - - if (text_props != NULL) - { - area_highlighting = TRUE; - extra_check = TRUE; - // text props "above" move the line number down to where the - // text is. - for (int i = 0; i < text_prop_count; ++i) - if (text_props[i].tp_flags & TP_FLAG_ALIGN_ABOVE) - ++wlv.text_prop_above_count; - } - } - } -#endif - win_line_start(wp, &wlv, FALSE); // Repeat for the whole displayed line. @@ -2059,7 +2089,8 @@ win_line( wlv.vcol, wlv.col, &wlv.n_extra, &wlv.p_extra, - &n_attr, &wlv.n_attr_skip); + &n_attr, &wlv.n_attr_skip, + skip_cells > 0); if (wlv.p_extra != prev_p_extra) { // wlv.p_extra was allocated |