# HG changeset patch # User Bram Moolenaar # Date 1663002005 -7200 # Node ID 0d084880276aa30ab2d84685115d533cbb1cd9f0 # Parent aad84f731ef9efe240bbada29a76e10109682278 patch 9.0.0451: virtual text "above" does not work with 'nowrap' Commit: https://github.com/vim/vim/commit/c9dc03fff5acf6fb91a923fb95006f9c2bca6141 Author: Bram Moolenaar Date: Mon Sep 12 17:51:07 2022 +0100 patch 9.0.0451: virtual text "above" does not work with 'nowrap' Problem: Virtual text "above" does not work with 'nowrap'. Solution: Do wrap the line after. (closes https://github.com/vim/vim/issues/11084) diff --git a/src/drawline.c b/src/drawline.c --- a/src/drawline.c +++ b/src/drawline.c @@ -666,6 +666,7 @@ win_line( // syntax_attr int text_prop_id = 0; // active property ID int text_prop_flags = 0; + int text_prop_above = FALSE; // first doing virtual text above int text_prop_follows = FALSE; // another text prop to display int saved_search_attr = 0; // search_attr to be used when n_extra // goes to zero @@ -1784,6 +1785,7 @@ win_line( // Sort the properties on priority and/or starting last. // Then combine the attributes, highest priority last. + text_prop_above = FALSE; text_prop_follows = FALSE; sort_text_props(wp->w_buffer, text_props, text_prop_idxs, text_props_active); @@ -1817,6 +1819,8 @@ win_line( char_u *p = ((char_u **)wp->w_buffer ->b_textprop_text.ga_data)[ -text_prop_id - 1]; + int above = (tp->tp_flags + & TP_FLAG_ALIGN_ABOVE); // reset the ID in the copy to avoid it being used // again @@ -1826,8 +1830,6 @@ win_line( { int right = (tp->tp_flags & TP_FLAG_ALIGN_RIGHT); - int above = (tp->tp_flags - & TP_FLAG_ALIGN_ABOVE); int below = (tp->tp_flags & TP_FLAG_ALIGN_BELOW); int wrap = (tp->tp_flags & TP_FLAG_WRAP); @@ -1902,6 +1904,9 @@ win_line( // If another text prop follows the condition below at // the last window column must know. + // If this is an "above" text prop and 'nowrap' the we + // must wrap anyway. + text_prop_above = above; text_prop_follows = other_tpi != -1; } } @@ -3581,7 +3586,7 @@ win_line( || filler_todo > 0 #endif #ifdef FEAT_PROP_POPUP - || text_prop_follows + || text_prop_above || text_prop_follows #endif || (wp->w_p_list && wp->w_lcs_chars.eol != NUL && wlv.p_extra != at_end_str) @@ -3608,12 +3613,12 @@ win_line( && filler_todo <= 0 #endif #ifdef FEAT_PROP_POPUP - && !text_prop_follows + && !text_prop_above && !text_prop_follows #endif ) || lcs_eol_one == -1) break; #ifdef FEAT_PROP_POPUP - if (!wp->w_p_wrap && text_prop_follows) + if (!wp->w_p_wrap && text_prop_follows && !text_prop_above) { // do not output more of the line, only the "below" prop ptr += STRLEN(ptr); @@ -3647,7 +3652,7 @@ win_line( && filler_todo <= 0 #endif #ifdef FEAT_PROP_POPUP - && !text_prop_follows + && !text_prop_above && !text_prop_follows #endif && wp->w_width == Columns) { diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -377,8 +377,8 @@ plines_win_nofill( if (!wp->w_p_wrap) lines = 1 #ifdef FEAT_PROP_POPUP - // add a line for each "below" aligned text property - + prop_count_below(wp->w_buffer, lnum) + // add a line for each "above" and "below" aligned text property + + prop_count_above_below(wp->w_buffer, lnum) #endif ; else diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -1068,6 +1068,19 @@ curs_columns( #endif ) { +#ifdef FEAT_PROP_POPUP + if (curwin->w_virtcol_first_char > 0) + { + int cols = (curwin->w_width - extra); + int rows = cols > 0 ? curwin->w_virtcol_first_char / cols : 1; + + // each "above" text prop shifts the text one row down + curwin->w_wrow += rows; + curwin->w_wcol -= rows * cols; + endcol -= rows * cols; + curwin->w_cline_height = rows + 1; + } +#endif /* * If Cursor is left of the screen, scroll rightwards. * If Cursor is right of the screen, scroll leftwards diff --git a/src/proto/textprop.pro b/src/proto/textprop.pro --- a/src/proto/textprop.pro +++ b/src/proto/textprop.pro @@ -4,7 +4,7 @@ void f_prop_add(typval_T *argvars, typva void f_prop_add_list(typval_T *argvars, typval_T *rettv); int prop_add_common(linenr_T start_lnum, colnr_T start_col, dict_T *dict, buf_T *default_buf, typval_T *dict_arg); int get_text_props(buf_T *buf, linenr_T lnum, char_u **props, int will_change); -int prop_count_below(buf_T *buf, linenr_T lnum); +int prop_count_above_below(buf_T *buf, linenr_T lnum); int count_props(linenr_T lnum, int only_starting, int last_line); void sort_text_props(buf_T *buf, textprop_T *props, int *idxs, int count); int find_visible_prop(win_T *wp, int type_id, int id, textprop_T *prop, linenr_T *found_lnum); diff --git a/src/testdir/dumps/Test_prop_with_text_above_5.dump b/src/testdir/dumps/Test_prop_with_text_above_5.dump new file mode 100644 --- /dev/null +++ b/src/testdir/dumps/Test_prop_with_text_above_5.dump @@ -0,0 +1,9 @@ +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|1| |f+0#0000000#ffff4012|i|r|s|t| |t|h|i|n|g| |a|b|o|v|e| @36 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|s+0#0000000#ffd7ff255|e|c|o|n|d| |t|h|i|n|g| |a|b|o|v|e| @35 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|i+0#0000000&|n|s|e|r|t|e|d| |o|n|e| |t|w|o| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|2| |t+0#0000000&|h|r|e@1| |f|o|u>r| @43 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@1|3| | +0#0000000&@2|a+0&#ffff4012|n|o|t|h|e|r| |t|h|i|n|g| @37 +| +0#0000e05#a8a8a8255@1| +0#af5f00255#ffffff0@3|f+0#0000000&|i|v|e| |s|i|x| @45 +|~+0#4040ff13&| @58 +|~| @58 +|:+0#0000000&|s|e|t| |n|o|w|r|a|p| @30|2|,|1|0| @9|A|l@1| diff --git a/src/testdir/test_textprop.vim b/src/testdir/test_textprop.vim --- a/src/testdir/test_textprop.vim +++ b/src/testdir/test_textprop.vim @@ -2873,6 +2873,9 @@ func Test_props_with_text_above() call term_sendkeys(buf, ":set number signcolumn=yes\") call VerifyScreenDump(buf, 'Test_prop_with_text_above_4', {}) + call term_sendkeys(buf, ":set nowrap\gg$j") + call VerifyScreenDump(buf, 'Test_prop_with_text_above_5', {}) + call StopVimInTerminal(buf) endfunc diff --git a/src/textprop.c b/src/textprop.c --- a/src/textprop.c +++ b/src/textprop.c @@ -608,12 +608,12 @@ get_text_props(buf_T *buf, linenr_T lnum } /* - * Return the number of text properties with "below" alignment in line "lnum". - * A "right" aligned property also goes below after a "below" or other "right" - * aligned property. + * Return the number of text properties with "above" or "below" alignment in + * line "lnum". A "right" aligned property also goes below after a "below" or + * other "right" aligned property. */ int -prop_count_below(buf_T *buf, linenr_T lnum) +prop_count_above_below(buf_T *buf, linenr_T lnum) { char_u *props; int count = get_text_props(buf, lnum, &props, FALSE); @@ -636,6 +636,11 @@ prop_count_below(buf_T *buf, linenr_T ln next_right_goes_below = TRUE; ++result; } + else if (prop.tp_flags & TP_FLAG_ALIGN_ABOVE) + { + next_right_goes_below = FALSE; + ++result; + } else if (prop.tp_flags & TP_FLAG_ALIGN_RIGHT) next_right_goes_below = TRUE; } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -704,6 +704,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 451, +/**/ 450, /**/ 449,