To: vim_dev@googlegroups.com Subject: Patch 9.0.1301 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.1301 Problem: Virtual text below empty line not displayed. Solution: Adjust flags and computations. (closes #11959) Files: src/drawline.c, src/charset.c, src/testdir/test_textprop.vim, src/testdir/dumps/Test_prop_above_below_empty_1.dump *** ../vim-9.0.1300/src/drawline.c 2023-01-21 15:54:40.426545808 +0000 --- src/drawline.c 2023-02-11 13:45:47.382682457 +0000 *************** *** 1085,1090 **** --- 1085,1091 ---- int save_did_emsg; #endif #ifdef FEAT_PROP_POPUP + int did_line = FALSE; // set to TRUE when line text done int text_prop_count; int text_prop_next = 0; // next text property to use textprop_T *text_props = NULL; *************** *** 1914,1930 **** // Check if any active property ends. for (pi = 0; pi < text_props_active; ++pi) { ! int tpi = text_prop_idxs[pi]; ! if (text_props[tpi].tp_col != MAXCOL ! && bcol >= text_props[tpi].tp_col - 1 ! + text_props[tpi].tp_len) { if (pi + 1 < text_props_active) mch_memmove(text_prop_idxs + pi, text_prop_idxs + pi + 1, sizeof(int) ! * (text_props_active - (pi + 1))); --text_props_active; --pi; # ifdef FEAT_LINEBREAK --- 1915,1934 ---- // Check if any active property ends. for (pi = 0; pi < text_props_active; ++pi) { ! int tpi = text_prop_idxs[pi]; ! textprop_T *tp = &text_props[tpi]; ! // An inline property ends when after the start column plus ! // length. An "above" property ends when used and n_extra ! // is zero. ! if ((tp->tp_col != MAXCOL ! && bcol >= tp->tp_col - 1 + tp->tp_len)) { if (pi + 1 < text_props_active) mch_memmove(text_prop_idxs + pi, text_prop_idxs + pi + 1, sizeof(int) ! * (text_props_active - (pi + 1))); --text_props_active; --pi; # ifdef FEAT_LINEBREAK *************** *** 1940,1945 **** --- 1944,1952 ---- // not on the next char yet, don't start another prop --bcol; # endif + int display_text_first = FALSE; + int active_before = text_props_active; + // Add any text property that starts in this column. // With 'nowrap' and not in the first screen line only "below" // text prop can show. *************** *** 1950,1965 **** || wlv.row == startrow || (text_props[text_prop_next].tp_flags & TP_FLAG_ALIGN_BELOW))) ! || (bcol == 0 && ! (text_props[text_prop_next].tp_flags & TP_FLAG_ALIGN_ABOVE))) : bcol >= text_props[text_prop_next].tp_col - 1)) { if (text_props[text_prop_next].tp_col == MAXCOL ! && *ptr == NUL && wp->w_p_list && lcs_eol_one > 0) { ! // first display the '$' after the line text_prop_follows = TRUE; break; } if (text_props[text_prop_next].tp_col == MAXCOL --- 1957,1980 ---- || wlv.row == startrow || (text_props[text_prop_next].tp_flags & TP_FLAG_ALIGN_BELOW))) ! || (bcol == 0 ! && (text_props[text_prop_next].tp_flags & TP_FLAG_ALIGN_ABOVE))) : bcol >= text_props[text_prop_next].tp_col - 1)) { if (text_props[text_prop_next].tp_col == MAXCOL ! && *ptr == NUL ! && ((wp->w_p_list && lcs_eol_one > 0) ! || (ptr == line ! && !did_line ! && (text_props[text_prop_next].tp_flags ! & TP_FLAG_ALIGN_BELOW)))) { ! // first display the '$' after the line or display an ! // empty line text_prop_follows = TRUE; + if (text_props_active == active_before) + display_text_first = TRUE; break; } if (text_props[text_prop_next].tp_col == MAXCOL *************** *** 1978,1993 **** text_prop_id = 0; reset_extra_attr = FALSE; } ! if (text_props_active > 0 && wlv.n_extra == 0) { int used_tpi = -1; int used_attr = 0; int other_tpi = -1; - // 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); --- 1993,2010 ---- text_prop_id = 0; reset_extra_attr = FALSE; } ! if (text_props_active > 0 && wlv.n_extra == 0 ! && !display_text_first) { int used_tpi = -1; int used_attr = 0; int other_tpi = -1; text_prop_above = FALSE; text_prop_follows = FALSE; + + // Sort the properties on priority and/or starting last. + // Then combine the attributes, highest priority last. sort_text_props(wp->w_buffer, text_props, text_prop_idxs, text_props_active); *************** *** 2159,2166 **** // must wrap anyway. text_prop_above = above; text_prop_follows |= other_tpi != -1 ! && (wp->w_p_wrap ! || (text_props[other_tpi].tp_flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_RIGHT))); if (bail_out) --- 2176,2183 ---- // must wrap anyway. text_prop_above = above; text_prop_follows |= other_tpi != -1 ! && (wp->w_p_wrap ! || (text_props[other_tpi].tp_flags & (TP_FLAG_ALIGN_BELOW | TP_FLAG_ALIGN_RIGHT))); if (bail_out) *************** *** 2495,2500 **** --- 2512,2523 ---- #ifdef FEAT_LINEBREAK c0 = *ptr; #endif + #ifdef FEAT_PROP_POPUP + if (c == NUL) + // text is finished, may display a "below" virtual text + did_line = TRUE; + #endif + if (has_mbyte) { mb_c = c; *************** *** 3576,3595 **** // At end of the text line. if (c == NUL) { ! draw_screen_line(wp, &wlv); ! ! // Update w_cline_height and w_cline_folded if the cursor line was ! // updated (saves a call to plines() later). ! if (wp == curwin && lnum == curwin->w_cursor.lnum) { ! curwin->w_cline_row = startrow; ! curwin->w_cline_height = wlv.row - startrow; #ifdef FEAT_FOLDING ! curwin->w_cline_folded = FALSE; #endif ! curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); } - break; } // Show "extends" character from 'listchars' if beyond the line end and --- 3599,3629 ---- // At end of the text line. if (c == NUL) { ! #ifdef FEAT_PROP_POPUP ! if (text_prop_follows) ! { ! // Put the pointer back to the NUL. ! --ptr; ! c = ' '; ! } ! else ! #endif { ! draw_screen_line(wp, &wlv); ! ! // Update w_cline_height and w_cline_folded if the cursor line ! // was updated (saves a call to plines() later). ! if (wp == curwin && lnum == curwin->w_cursor.lnum) ! { ! curwin->w_cline_row = startrow; ! curwin->w_cline_height = wlv.row - startrow; #ifdef FEAT_FOLDING ! curwin->w_cline_folded = FALSE; #endif ! curwin->w_valid |= (VALID_CHEIGHT|VALID_CROW); ! } ! break; } } // Show "extends" character from 'listchars' if beyond the line end and *** ../vim-9.0.1300/src/charset.c 2023-02-05 18:00:38.353400148 +0000 --- src/charset.c 2023-02-11 13:32:56.238573887 +0000 *************** *** 1152,1157 **** --- 1152,1159 ---- * First get the normal size, without 'linebreak' or text properties */ size = win_chartabsize(wp, s, vcol); + if (*s == NUL) + size = 0; // NUL is not displayed # ifdef FEAT_PROP_POPUP if (cts->cts_has_prop_with_text) *** ../vim-9.0.1300/src/testdir/test_textprop.vim 2023-01-28 19:18:56.733720607 +0000 --- src/testdir/test_textprop.vim 2023-02-11 13:42:49.574667255 +0000 *************** *** 2779,2784 **** --- 2779,2806 ---- call StopVimInTerminal(buf) endfunc + func Test_prop_with_text_above_below_empty() + CheckRunVimInTerminal + + let lines =<< trim END + setlocal number + call setline(1, ['11111111', '', '333333333', '', '55555555555']) + + let vt = 'test' + call prop_type_add(vt, {'highlight': 'ToDo'}) + for ln in range(1, line('$')) + call prop_add(ln, 0, {'type': vt, 'text': '---', 'text_align': 'above'}) + call prop_add(ln, 0, {'type': vt, 'text': '+++', 'text_align': 'below'}) + endfor + normal G + END + call writefile(lines, 'XscriptPropAboveBelowEmpty', 'D') + let buf = RunVimInTerminal('-S XscriptPropAboveBelowEmpty', #{rows: 16, cols: 60}) + call VerifyScreenDump(buf, 'Test_prop_above_below_empty_1', {}) + + call StopVimInTerminal(buf) + endfunc + func Test_prop_with_text_below_after_match() CheckRunVimInTerminal *** ../vim-9.0.1300/src/testdir/dumps/Test_prop_above_below_empty_1.dump 2023-02-11 13:47:27.350689573 +0000 --- src/testdir/dumps/Test_prop_above_below_empty_1.dump 2023-02-11 13:42:24.622664830 +0000 *************** *** 0 **** --- 1,16 ---- + | +0#af5f00255#ffffff0@3|-+0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@1|1| |1+0#0000000&@7| @47 + | +0#af5f00255&@3|++0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@3|-+0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@1|2| | +0#0000000&@55 + | +0#af5f00255&@3|++0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@3|-+0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@1|3| |3+0#0000000&@8| @46 + | +0#af5f00255&@3|++0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@3|-+0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@1|4| | +0#0000000&@55 + | +0#af5f00255&@3|++0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@3|-+0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + | +0#af5f00255&@1|5| >5+0#0000000&@10| @44 + | +0#af5f00255&@3|++0#0000001#ffff4012@2| +0#0000000#ffffff0@52 + @42|5|,|1|-|5|7| @7|A|l@1| *** ../vim-9.0.1300/src/version.c 2023-02-11 11:15:19.999085252 +0000 --- src/version.c 2023-02-11 13:34:40.430597456 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 1301, /**/ -- FIXME and XXX are two common keywords used to mark broken or incomplete code not only since XXX as a sex reference would grab everybody's attention but simply due to the fact that Vim would highlight these words. -- Hendrik Scholz /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///