To: vim_dev@googlegroups.com Subject: Patch 9.0.0153 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0153 Problem: No fold and sign column for virtual text with "below" align and 'nowrap'. Solution: Go back to draw state WL_START when moving to the next line. (closes #10851) Files: src/drawline.c, src/testdir/test_textprop.vim, src/testdir/dumps/Test_prop_with_text_after_nowrap_2.dump *** ../vim-9.0.0152/src/drawline.c 2022-08-06 14:21:48.902455645 +0100 --- src/drawline.c 2022-08-06 15:56:52.327000213 +0100 *************** *** 75,80 **** --- 75,163 ---- } #endif + // structure with variables passed between win_line() and other functions + typedef struct { + int draw_state; // what to draw next + + linenr_T lnum; // line number to be drawn + + int startrow; // first row in the window to be drawn + int row; // row in the window, excl w_winrow + int screen_row; // row on the screen, incl w_winrow + + long vcol; // virtual column, before wrapping + int col; // visual column on screen, after wrapping + #ifdef FEAT_CONCEAL + int boguscols; // nonexistent columns added to "col" to force + // wrapping + int vcol_off; // offset for concealed characters + #endif + #ifdef FEAT_SYN_HL + int draw_color_col; // highlight colorcolumn + int *color_cols; // pointer to according columns array + #endif + int eol_hl_off; // 1 if highlighted char after EOL + + unsigned off; // offset in ScreenLines/ScreenAttrs + + int win_attr; // background for the whole window, except + // margins and "~" lines. + + int screen_line_flags; // flags for screen_line() + + // TRUE when 'cursorlineopt' has "screenline" and cursor is in this line + int cul_screenline; + + int char_attr; // attributes for the next character + + int n_extra; // number of extra bytes + char_u *p_extra; // string of extra chars, plus NUL, only used + // when c_extra and c_final are NUL + int c_extra; // extra chars, all the same + int c_final; // final char, mandatory if set + + // saved "extra" items for when draw_state becomes WL_LINE (again) + int saved_n_extra; + char_u *saved_p_extra; + int saved_c_extra; + int saved_c_final; + int saved_char_attr; + + #ifdef FEAT_DIFF + hlf_T diff_hlf; // type of diff highlighting + #endif + } winlinevars_T; + + // draw_state values for items that are drawn in sequence: + #define WL_START 0 // nothing done yet, must be zero + #ifdef FEAT_CMDWIN + # define WL_CMDLINE (WL_START + 1) // cmdline window column + #else + # define WL_CMDLINE WL_START + #endif + #ifdef FEAT_FOLDING + # define WL_FOLD (WL_CMDLINE + 1) // 'foldcolumn' + #else + # define WL_FOLD WL_CMDLINE + #endif + #ifdef FEAT_SIGNS + # define WL_SIGN (WL_FOLD + 1) // column for signs + #else + # define WL_SIGN WL_FOLD // column for signs + #endif + #define WL_NR (WL_SIGN + 1) // line number + #ifdef FEAT_LINEBREAK + # define WL_BRI (WL_NR + 1) // 'breakindent' + #else + # define WL_BRI WL_NR + #endif + #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) + # define WL_SBR (WL_BRI + 1) // 'showbreak' or 'diff' + #else + # define WL_SBR WL_BRI + #endif + #define WL_LINE (WL_SBR + 1) // text in the line + #ifdef FEAT_SIGNS /* * Return TRUE if CursorLineSign highlight is to be used. *************** *** 97,114 **** int nrcol, win_T *wp, linenr_T lnum, sign_attrs_T *sattr, int wcr_attr, - int row, - int startrow, int filler_lines UNUSED, int filler_todo UNUSED, ! int *c_extrap, ! int *c_finalp, ! char_u *extra, ! char_u **pp_extra, ! int *n_extrap, ! int *char_attrp) { int text_sign; # ifdef FEAT_SIGN_ICONS --- 180,191 ---- int nrcol, win_T *wp, linenr_T lnum, + winlinevars_T *wlv, sign_attrs_T *sattr, int wcr_attr, int filler_lines UNUSED, int filler_todo UNUSED, ! char_u *extra) { int text_sign; # ifdef FEAT_SIGN_ICONS *************** *** 116,135 **** # endif // Draw two cells with the sign value or blank. ! *c_extrap = ' '; ! *c_finalp = NUL; if (nrcol) ! *n_extrap = number_width(wp) + 1; else { if (use_cursor_line_sign(wp, lnum)) ! *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLS)); else ! *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC)); ! *n_extrap = 2; } ! if (row == startrow #ifdef FEAT_DIFF + filler_lines && filler_todo <= 0 #endif --- 193,212 ---- # endif // Draw two cells with the sign value or blank. ! wlv->c_extra = ' '; ! wlv->c_final = NUL; if (nrcol) ! wlv->n_extra = number_width(wp) + 1; else { if (use_cursor_line_sign(wp, lnum)) ! wlv->char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLS)); else ! wlv->char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC)); ! wlv->n_extra = 2; } ! if (wlv->row == wlv->startrow #ifdef FEAT_DIFF + filler_lines && filler_todo <= 0 #endif *************** *** 143,179 **** // Use the image in this position. if (nrcol) { ! *c_extrap = NUL; sprintf((char *)extra, "%-*c ", number_width(wp), SIGN_BYTE); ! *pp_extra = extra; ! *n_extrap = (int)STRLEN(*pp_extra); } else ! *c_extrap = SIGN_BYTE; # ifdef FEAT_NETBEANS_INTG if (netbeans_active() && (buf_signcount(wp->w_buffer, lnum) > 1)) { if (nrcol) { ! *c_extrap = NUL; sprintf((char *)extra, "%-*c ", number_width(wp), MULTISIGN_BYTE); ! *pp_extra = extra; ! *n_extrap = (int)STRLEN(*pp_extra); } else ! *c_extrap = MULTISIGN_BYTE; } # endif ! *c_finalp = NUL; ! *char_attrp = icon_sign; } else # endif if (text_sign != 0) { ! *pp_extra = sattr->sat_text; ! if (*pp_extra != NULL) { if (nrcol) { --- 220,256 ---- // Use the image in this position. if (nrcol) { ! wlv->c_extra = NUL; sprintf((char *)extra, "%-*c ", number_width(wp), SIGN_BYTE); ! wlv->p_extra = extra; ! wlv->n_extra = (int)STRLEN(wlv->p_extra); } else ! wlv->c_extra = SIGN_BYTE; # ifdef FEAT_NETBEANS_INTG if (netbeans_active() && (buf_signcount(wp->w_buffer, lnum) > 1)) { if (nrcol) { ! wlv->c_extra = NUL; sprintf((char *)extra, "%-*c ", number_width(wp), MULTISIGN_BYTE); ! wlv->p_extra = extra; ! wlv->n_extra = (int)STRLEN(wlv->p_extra); } else ! wlv->c_extra = MULTISIGN_BYTE; } # endif ! wlv->c_final = NUL; ! wlv->char_attr = icon_sign; } else # endif if (text_sign != 0) { ! wlv->p_extra = sattr->sat_text; ! if (wlv->p_extra != NULL) { if (nrcol) { *************** *** 182,200 **** for (n = 0; n < width; n++) extra[n] = ' '; extra[n] = 0; ! STRCAT(extra, *pp_extra); STRCAT(extra, " "); ! *pp_extra = extra; } ! *c_extrap = NUL; ! *c_finalp = NUL; ! *n_extrap = (int)STRLEN(*pp_extra); } if (use_cursor_line_sign(wp, lnum) && sattr->sat_culhl > 0) ! *char_attrp = sattr->sat_culhl; else ! *char_attrp = sattr->sat_texthl; } } } --- 259,277 ---- for (n = 0; n < width; n++) extra[n] = ' '; extra[n] = 0; ! STRCAT(extra, wlv->p_extra); STRCAT(extra, " "); ! wlv->p_extra = extra; } ! wlv->c_extra = NUL; ! wlv->c_final = NUL; ! wlv->n_extra = (int)STRLEN(wlv->p_extra); } if (use_cursor_line_sign(wp, lnum) && sattr->sat_culhl > 0) ! wlv->char_attr = sattr->sat_culhl; else ! wlv->char_attr = sattr->sat_texthl; } } } *************** *** 249,282 **** } #endif - // structure with variables passed between win_line() and other functions - typedef struct { - linenr_T lnum; // line number to be drawn - - int startrow; // first row in the window to be drawn - int row; // row in the window, excl w_winrow - int screen_row; // row on the screen, incl w_winrow - - long vcol; // virtual column, before wrapping - int col; // visual column on screen, after wrapping - #ifdef FEAT_CONCEAL - int boguscols; // nonexistent columns added to "col" to force - // wrapping - int vcol_off; // offset for concealed characters - #endif - #ifdef FEAT_SYN_HL - int draw_color_col; // highlight colorcolumn - int *color_cols; // pointer to according columns array - #endif - int eol_hl_off; // 1 if highlighted char after EOL - - unsigned off; // offset in ScreenLines/ScreenAttrs - - int win_attr; // background for the whole window, except - // margins and "~" lines. - int screen_line_flags; - } winlinevars_T; - /* * Called when finished with the line: draw the screen line and handle any * highlighting until the right of the window. --- 326,331 ---- *************** *** 367,375 **** /* * Start a screen line at column zero. */ static void ! win_line_start(win_T *wp UNUSED, winlinevars_T *wlv) { wlv->col = 0; wlv->off = (unsigned)(current_ScreenLine - ScreenLines); --- 416,425 ---- /* * Start a screen line at column zero. + * When "save_extra" is TRUE save and reset n_extra, p_extra, etc. */ static void ! win_line_start(win_T *wp UNUSED, winlinevars_T *wlv, int save_extra) { wlv->col = 0; wlv->off = (unsigned)(current_ScreenLine - ScreenLines); *************** *** 385,390 **** --- 435,460 ---- wlv->screen_line_flags |= SLF_RIGHTLEFT; } #endif + if (save_extra) + { + // reset the drawing state for the start of a wrapped line + wlv->draw_state = WL_START; + wlv->saved_n_extra = wlv->n_extra; + wlv->saved_p_extra = wlv->p_extra; + wlv->saved_c_extra = wlv->c_extra; + wlv->saved_c_final = wlv->c_final; + #ifdef FEAT_SYN_HL + if (!(wlv->cul_screenline + # ifdef FEAT_DIFF + && wlv->diff_hlf == (hlf_T)0 + # endif + )) + wlv->saved_char_attr = wlv->char_attr; + else + #endif + wlv->saved_char_attr = 0; + wlv->n_extra = 0; + } } /* *************** *** 414,424 **** char_u *ptr; // current position in "line" char_u extra[21]; // "%ld " and 'fdc' must fit in here - int n_extra = 0; // number of extra bytes - char_u *p_extra = NULL; // string of extra chars, plus NUL char_u *p_extra_free = NULL; // p_extra needs to be freed ! int c_extra = NUL; // extra chars, all the same ! int c_final = NUL; // final char, mandatory if set int extra_attr = 0; // attributes when n_extra != 0 #if defined(FEAT_LINEBREAK) && defined(FEAT_PROP_POPUP) int in_linebreak = FALSE; // n_extra set for showing linebreak --- 484,493 ---- char_u *ptr; // current position in "line" char_u extra[21]; // "%ld " and 'fdc' must fit in here char_u *p_extra_free = NULL; // p_extra needs to be freed ! #ifdef FEAT_PROP_POPUP ! char_u *p_extra_free2 = NULL; // another p_extra to be freed ! #endif int extra_attr = 0; // attributes when n_extra != 0 #if defined(FEAT_LINEBREAK) && defined(FEAT_PROP_POPUP) int in_linebreak = FALSE; // n_extra set for showing linebreak *************** *** 429,441 **** int lcs_prec_todo = wp->w_lcs_chars.prec; // prec until it's been used - // saved "extra" items for when draw_state becomes WL_LINE (again) - int saved_n_extra = 0; - char_u *saved_p_extra = NULL; - int saved_c_extra = 0; - int saved_c_final = 0; - int saved_char_attr = 0; - int n_attr = 0; // chars with special attr int n_attr_skip = 0; // chars to skip before using extra_attr int saved_attr2 = 0; // char_attr saved for n_attr --- 498,503 ---- *************** *** 452,458 **** pos_T pos; long v; - int char_attr = 0; // attributes for next character int attr_pri = FALSE; // char_attr has priority int area_highlighting = FALSE; // Visual or incsearch highlighting // in this line --- 514,519 ---- *************** *** 511,517 **** # define filler_lines 0 #endif #ifdef FEAT_DIFF - hlf_T diff_hlf = (hlf_T)0; // type of diff highlighting int change_start = MAXCOL; // first col of changed area int change_end = -1; // last col of changed area #endif --- 572,577 ---- *************** *** 548,592 **** #ifdef FEAT_SYN_HL int cul_attr = 0; // set when 'cursorline' active - // 'cursorlineopt' has "screenline" and cursor is in this line - int cul_screenline = FALSE; - // margin columns for the screen line, needed for when 'cursorlineopt' // contains "screenline" int left_curline_col = 0; int right_curline_col = 0; #endif - // draw_state: items that are drawn in sequence: - #define WL_START 0 // nothing done yet - #ifdef FEAT_CMDWIN - # define WL_CMDLINE (WL_START + 1) // cmdline window column - #else - # define WL_CMDLINE WL_START - #endif - #ifdef FEAT_FOLDING - # define WL_FOLD (WL_CMDLINE + 1) // 'foldcolumn' - #else - # define WL_FOLD WL_CMDLINE - #endif - #ifdef FEAT_SIGNS - # define WL_SIGN (WL_FOLD + 1) // column for signs - #else - # define WL_SIGN WL_FOLD // column for signs - #endif - #define WL_NR (WL_SIGN + 1) // line number - #ifdef FEAT_LINEBREAK - # define WL_BRI (WL_NR + 1) // 'breakindent' - #else - # define WL_BRI WL_NR - #endif - #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) - # define WL_SBR (WL_BRI + 1) // 'showbreak' or 'diff' - #else - # define WL_SBR WL_BRI - #endif - #define WL_LINE (WL_SBR + 1) // text in the line - int draw_state = WL_START; // what to draw next #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) int feedback_col = 0; int feedback_old_attr = -1; --- 608,619 ---- *************** *** 607,613 **** # define VCOL_HLC (wlv.vcol - wlv.vcol_off) # define FIX_FOR_BOGUSCOLS \ { \ ! n_extra += wlv.vcol_off; \ wlv.vcol -= wlv.vcol_off; \ wlv.vcol_off = 0; \ wlv.col -= wlv.boguscols; \ --- 634,640 ---- # define VCOL_HLC (wlv.vcol - wlv.vcol_off) # define FIX_FOR_BOGUSCOLS \ { \ ! wlv.n_extra += wlv.vcol_off; \ wlv.vcol -= wlv.vcol_off; \ wlv.vcol_off = 0; \ wlv.col -= wlv.boguscols; \ *************** *** 838,851 **** if (filler_lines == -1) { if (diff_find_change(wp, lnum, &change_start, &change_end)) ! diff_hlf = HLF_ADD; // added line else if (change_start == 0) ! diff_hlf = HLF_TXD; // changed text else ! diff_hlf = HLF_CHD; // changed line } else ! diff_hlf = HLF_ADD; // added line filler_lines = 0; area_highlighting = TRUE; } --- 865,878 ---- if (filler_lines == -1) { if (diff_find_change(wp, lnum, &change_start, &change_end)) ! wlv.diff_hlf = HLF_ADD; // added line else if (change_start == 0) ! wlv.diff_hlf = HLF_TXD; // changed text else ! wlv.diff_hlf = HLF_CHD; // changed line } else ! wlv.diff_hlf = HLF_ADD; // added line filler_lines = 0; area_highlighting = TRUE; } *************** *** 1111,1122 **** if (!(wp == curwin && VIsual_active) && wp->w_p_culopt_flags != CULOPT_NBR) { ! cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); // Only set line_attr here when "screenline" is not present in // 'cursorlineopt'. Otherwise it's done later. ! if (!cul_screenline) { cul_attr = HL_ATTR(HLF_CUL); # ifdef FEAT_SIGNS --- 1138,1149 ---- if (!(wp == curwin && VIsual_active) && wp->w_p_culopt_flags != CULOPT_NBR) { ! wlv.cul_screenline = (wp->w_p_wrap && (wp->w_p_culopt_flags & CULOPT_SCRLINE)); // Only set line_attr here when "screenline" is not present in // 'cursorlineopt'. Otherwise it's done later. ! if (!wlv.cul_screenline) { cul_attr = HL_ATTR(HLF_CUL); # ifdef FEAT_SIGNS *************** *** 1170,1176 **** } #endif ! win_line_start(wp, &wlv); // Repeat for the whole displayed line. for (;;) --- 1197,1203 ---- } #endif ! win_line_start(wp, &wlv, FALSE); // Repeat for the whole displayed line. for (;;) *************** *** 1184,1193 **** #endif // Skip this quickly when working on the text. ! if (draw_state != WL_LINE) { #ifdef FEAT_SYN_HL ! if (cul_screenline) { cul_attr = 0; line_attr = line_attr_save; --- 1211,1220 ---- #endif // Skip this quickly when working on the text. ! if (wlv.draw_state != WL_LINE) { #ifdef FEAT_SYN_HL ! if (wlv.cul_screenline) { cul_attr = 0; line_attr = line_attr_save; *************** *** 1195,1220 **** #endif #ifdef FEAT_CMDWIN ! if (draw_state == WL_CMDLINE - 1 && n_extra == 0) { ! draw_state = WL_CMDLINE; if (cmdwin_type != 0 && wp == curwin) { // Draw the cmdline character. ! n_extra = 1; ! c_extra = cmdwin_type; ! c_final = NUL; ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_AT)); } } #endif #ifdef FEAT_FOLDING ! if (draw_state == WL_FOLD - 1 && n_extra == 0) { int fdc = compute_foldcolumn(wp, 0); ! draw_state = WL_FOLD; if (fdc > 0) { // Draw the 'foldcolumn'. Allocate a buffer, "extra" may --- 1222,1247 ---- #endif #ifdef FEAT_CMDWIN ! if (wlv.draw_state == WL_CMDLINE - 1 && wlv.n_extra == 0) { ! wlv.draw_state = WL_CMDLINE; if (cmdwin_type != 0 && wp == curwin) { // Draw the cmdline character. ! wlv.n_extra = 1; ! wlv.c_extra = cmdwin_type; ! wlv.c_final = NUL; ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_AT)); } } #endif #ifdef FEAT_FOLDING ! if (wlv.draw_state == WL_FOLD - 1 && wlv.n_extra == 0) { int fdc = compute_foldcolumn(wp, 0); ! wlv.draw_state = WL_FOLD; if (fdc > 0) { // Draw the 'foldcolumn'. Allocate a buffer, "extra" may *************** *** 1223,1239 **** p_extra_free = alloc(MAX_MCO * fdc + 1); if (p_extra_free != NULL) { ! n_extra = (int)fill_foldcolumn(p_extra_free, wp, FALSE, lnum); ! p_extra_free[n_extra] = NUL; ! p_extra = p_extra_free; ! c_extra = NUL; ! c_final = NUL; if (use_cursor_line_sign(wp, lnum)) ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLF)); else ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC)); } } --- 1250,1266 ---- p_extra_free = alloc(MAX_MCO * fdc + 1); if (p_extra_free != NULL) { ! wlv.n_extra = (int)fill_foldcolumn(p_extra_free, wp, FALSE, lnum); ! p_extra_free[wlv.n_extra] = NUL; ! wlv.p_extra = p_extra_free; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; if (use_cursor_line_sign(wp, lnum)) ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLF)); else ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC)); } } *************** *** 1241,1262 **** #endif #ifdef FEAT_SIGNS ! if (draw_state == WL_SIGN - 1 && n_extra == 0) { ! draw_state = WL_SIGN; // Show the sign column when there are any signs in this // buffer or when using Netbeans. if (signcolumn_on(wp)) ! get_sign_display_info(FALSE, wp, lnum, &sattr, wcr_attr, ! wlv.row, startrow, filler_lines, filler_todo, ! &c_extra, &c_final, extra, &p_extra, &n_extra, ! &char_attr); } #endif ! if (draw_state == WL_NR - 1 && n_extra == 0) { ! draw_state = WL_NR; // Display the absolute or relative line number. After the // first fill with blanks when the 'n' flag isn't in 'cpo' if ((wp->w_p_nu || wp->w_p_rnu) --- 1268,1287 ---- #endif #ifdef FEAT_SIGNS ! if (wlv.draw_state == WL_SIGN - 1 && wlv.n_extra == 0) { ! wlv.draw_state = WL_SIGN; // Show the sign column when there are any signs in this // buffer or when using Netbeans. if (signcolumn_on(wp)) ! get_sign_display_info(FALSE, wp, lnum, &wlv, &sattr, ! wcr_attr, filler_lines, filler_todo, extra); } #endif ! if (wlv.draw_state == WL_NR - 1 && wlv.n_extra == 0) { ! wlv.draw_state = WL_NR; // Display the absolute or relative line number. After the // first fill with blanks when the 'n' flag isn't in 'cpo' if ((wp->w_p_nu || wp->w_p_rnu) *************** *** 1269,1278 **** // number. if ((*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u') && sign_present) ! get_sign_display_info(TRUE, wp, lnum, &sattr, wcr_attr, ! wlv.row, startrow, filler_lines, filler_todo, ! &c_extra, &c_final, extra, &p_extra, &n_extra, ! &char_attr); else #endif { --- 1294,1301 ---- // number. if ((*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u') && sign_present) ! get_sign_display_info(TRUE, wp, lnum, &wlv, &sattr, ! wcr_attr, filler_lines, filler_todo, extra); else #endif { *************** *** 1300,1307 **** sprintf((char *)extra, fmt, number_width(wp), num); if (wp->w_skipcol > 0) ! for (p_extra = extra; *p_extra == ' '; ++p_extra) ! *p_extra = '-'; #ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) // reverse line numbers { --- 1323,1331 ---- sprintf((char *)extra, fmt, number_width(wp), num); if (wp->w_skipcol > 0) ! for (wlv.p_extra = extra; *wlv.p_extra == ' '; ! ++wlv.p_extra) ! *wlv.p_extra = '-'; #ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) // reverse line numbers { *************** *** 1319,1335 **** } } #endif ! p_extra = extra; ! c_extra = NUL; ! c_final = NUL; } else { ! c_extra = ' '; ! c_final = NUL; } ! n_extra = number_width(wp) + 1; ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N)); #ifdef FEAT_SYN_HL // When 'cursorline' is set highlight the line number of // the current line differently. --- 1343,1359 ---- } } #endif ! wlv.p_extra = extra; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; } else { ! wlv.c_extra = ' '; ! wlv.c_final = NUL; } ! wlv.n_extra = number_width(wp) + 1; ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_N)); #ifdef FEAT_SYN_HL // When 'cursorline' is set highlight the line number of // the current line differently. *************** *** 1343,1381 **** && (wlv.row == startrow + filler_lines || (wlv.row > startrow + filler_lines && (wp->w_p_culopt_flags & CULOPT_LINE)))) ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_CLN)); #endif if (wp->w_p_rnu && lnum < wp->w_cursor.lnum && HL_ATTR(HLF_LNA) != 0) // Use LineNrAbove ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_LNA)); if (wp->w_p_rnu && lnum > wp->w_cursor.lnum && HL_ATTR(HLF_LNB) != 0) // Use LineNrBelow ! char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_LNB)); } #ifdef FEAT_SIGNS if (num_attr) ! char_attr = num_attr; #endif } } #ifdef FEAT_LINEBREAK ! if (wp->w_briopt_sbr && draw_state == WL_BRI - 1 ! && n_extra == 0 && *get_showbreak_value(wp) != NUL) // draw indent after showbreak value ! draw_state = WL_BRI; ! else if (wp->w_briopt_sbr && draw_state == WL_SBR && n_extra == 0) // After the showbreak, draw the breakindent ! draw_state = WL_BRI - 1; // draw 'breakindent': indent wrapped text accordingly ! if (draw_state == WL_BRI - 1 && n_extra == 0) { ! draw_state = WL_BRI; // if need_showbreak is set, breakindent also applies if (wp->w_p_bri && (wlv.row != startrow || need_showbreak) # ifdef FEAT_DIFF --- 1367,1408 ---- && (wlv.row == startrow + filler_lines || (wlv.row > startrow + filler_lines && (wp->w_p_culopt_flags & CULOPT_LINE)))) ! wlv.char_attr = hl_combine_attr(wcr_attr, ! HL_ATTR(HLF_CLN)); #endif if (wp->w_p_rnu && lnum < wp->w_cursor.lnum && HL_ATTR(HLF_LNA) != 0) // Use LineNrAbove ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_LNA)); if (wp->w_p_rnu && lnum > wp->w_cursor.lnum && HL_ATTR(HLF_LNB) != 0) // Use LineNrBelow ! wlv.char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_LNB)); } #ifdef FEAT_SIGNS if (num_attr) ! wlv.char_attr = num_attr; #endif } } #ifdef FEAT_LINEBREAK ! if (wp->w_briopt_sbr && wlv.draw_state == WL_BRI - 1 ! && wlv.n_extra == 0 ! && *get_showbreak_value(wp) != NUL) // draw indent after showbreak value ! wlv.draw_state = WL_BRI; ! else if (wp->w_briopt_sbr && wlv.draw_state == WL_SBR ! && wlv.n_extra == 0) // After the showbreak, draw the breakindent ! wlv.draw_state = WL_BRI - 1; // draw 'breakindent': indent wrapped text accordingly ! if (wlv.draw_state == WL_BRI - 1 && wlv.n_extra == 0) { ! wlv.draw_state = WL_BRI; // if need_showbreak is set, breakindent also applies if (wp->w_p_bri && (wlv.row != startrow || need_showbreak) # ifdef FEAT_DIFF *************** *** 1383,1441 **** # endif ) { ! char_attr = 0; # ifdef FEAT_DIFF ! if (diff_hlf != (hlf_T)0) ! char_attr = HL_ATTR(diff_hlf); # endif ! p_extra = NULL; ! c_extra = ' '; ! c_final = NUL; ! n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, FALSE)); if (wlv.row == startrow) { ! n_extra -= win_col_off2(wp); ! if (n_extra < 0) ! n_extra = 0; } if (wp->w_skipcol > 0 && wp->w_p_wrap && wp->w_briopt_sbr) need_showbreak = FALSE; // Correct end of highlighted area for 'breakindent', // required when 'linebreak' is also set. if (tocol == wlv.vcol) ! tocol += n_extra; } } #endif #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) ! if (draw_state == WL_SBR - 1 && n_extra == 0) { char_u *sbr; ! draw_state = WL_SBR; # ifdef FEAT_DIFF if (filler_todo > 0) { // Draw "deleted" diff line(s). if (char2cells(wp->w_fill_chars.diff) > 1) { ! c_extra = '-'; ! c_final = NUL; } else { ! c_extra = wp->w_fill_chars.diff; ! c_final = NUL; } # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) ! n_extra = wlv.col + 1; else # endif ! n_extra = wp->w_width - wlv.col; ! char_attr = HL_ATTR(HLF_DED); } # endif # ifdef FEAT_LINEBREAK --- 1410,1468 ---- # endif ) { ! wlv.char_attr = 0; # ifdef FEAT_DIFF ! if (wlv.diff_hlf != (hlf_T)0) ! wlv.char_attr = HL_ATTR(wlv.diff_hlf); # endif ! wlv.p_extra = NULL; ! wlv.c_extra = ' '; ! wlv.c_final = NUL; ! wlv.n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, lnum, FALSE)); if (wlv.row == startrow) { ! wlv.n_extra -= win_col_off2(wp); ! if (wlv.n_extra < 0) ! wlv.n_extra = 0; } if (wp->w_skipcol > 0 && wp->w_p_wrap && wp->w_briopt_sbr) need_showbreak = FALSE; // Correct end of highlighted area for 'breakindent', // required when 'linebreak' is also set. if (tocol == wlv.vcol) ! tocol += wlv.n_extra; } } #endif #if defined(FEAT_LINEBREAK) || defined(FEAT_DIFF) ! if (wlv.draw_state == WL_SBR - 1 && wlv.n_extra == 0) { char_u *sbr; ! wlv.draw_state = WL_SBR; # ifdef FEAT_DIFF if (filler_todo > 0) { // Draw "deleted" diff line(s). if (char2cells(wp->w_fill_chars.diff) > 1) { ! wlv.c_extra = '-'; ! wlv.c_final = NUL; } else { ! wlv.c_extra = wp->w_fill_chars.diff; ! wlv.c_final = NUL; } # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) ! wlv.n_extra = wlv.col + 1; else # endif ! wlv.n_extra = wp->w_width - wlv.col; ! wlv.char_attr = HL_ATTR(HLF_DED); } # endif # ifdef FEAT_LINEBREAK *************** *** 1443,1489 **** if (*sbr != NUL && need_showbreak) { // Draw 'showbreak' at the start of each broken line. ! p_extra = sbr; ! c_extra = NUL; ! c_final = NUL; ! n_extra = (int)STRLEN(sbr); if (wp->w_skipcol == 0 || !wp->w_p_wrap) need_showbreak = FALSE; vcol_sbr = wlv.vcol + MB_CHARLEN(sbr); // Correct end of highlighted area for 'showbreak', // required when 'linebreak' is also set. if (tocol == wlv.vcol) ! tocol += n_extra; // combine 'showbreak' with 'wincolor' ! char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); # ifdef FEAT_SYN_HL // combine 'showbreak' with 'cursorline' if (cul_attr != 0) ! char_attr = hl_combine_attr(char_attr, cul_attr); # endif } # endif } #endif ! if (draw_state == WL_LINE - 1 && n_extra == 0) { ! draw_state = WL_LINE; ! if (saved_n_extra) { // Continue item from end of wrapped line. ! n_extra = saved_n_extra; ! c_extra = saved_c_extra; ! c_final = saved_c_final; ! p_extra = saved_p_extra; ! char_attr = saved_char_attr; } else ! char_attr = wlv.win_attr; } } #ifdef FEAT_SYN_HL ! if (cul_screenline && draw_state == WL_LINE && wlv.vcol >= left_curline_col && wlv.vcol < right_curline_col) { --- 1470,1518 ---- if (*sbr != NUL && need_showbreak) { // Draw 'showbreak' at the start of each broken line. ! wlv.p_extra = sbr; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; ! wlv.n_extra = (int)STRLEN(sbr); if (wp->w_skipcol == 0 || !wp->w_p_wrap) need_showbreak = FALSE; vcol_sbr = wlv.vcol + MB_CHARLEN(sbr); // Correct end of highlighted area for 'showbreak', // required when 'linebreak' is also set. if (tocol == wlv.vcol) ! tocol += wlv.n_extra; // combine 'showbreak' with 'wincolor' ! wlv.char_attr = hl_combine_attr(wlv.win_attr, ! HL_ATTR(HLF_AT)); # ifdef FEAT_SYN_HL // combine 'showbreak' with 'cursorline' if (cul_attr != 0) ! wlv.char_attr = hl_combine_attr(wlv.char_attr, ! cul_attr); # endif } # endif } #endif ! if (wlv.draw_state == WL_LINE - 1 && wlv.n_extra == 0) { ! wlv.draw_state = WL_LINE; ! if (wlv.saved_n_extra) { // Continue item from end of wrapped line. ! wlv.n_extra = wlv.saved_n_extra; ! wlv.c_extra = wlv.saved_c_extra; ! wlv.c_final = wlv.saved_c_final; ! wlv.p_extra = wlv.saved_p_extra; ! wlv.char_attr = wlv.saved_char_attr; } else ! wlv.char_attr = wlv.win_attr; } } #ifdef FEAT_SYN_HL ! if (wlv.cul_screenline && wlv.draw_state == WL_LINE && wlv.vcol >= left_curline_col && wlv.vcol < right_curline_col) { *************** *** 1497,1503 **** // stop here. if (((dollar_vcol >= 0 && wp == curwin && lnum == wp->w_cursor.lnum && wlv.vcol >= (long)wp->w_virtcol) ! || (number_only && draw_state > WL_NR)) #ifdef FEAT_DIFF && filler_todo <= 0 #endif --- 1526,1532 ---- // stop here. if (((dollar_vcol >= 0 && wp == curwin && lnum == wp->w_cursor.lnum && wlv.vcol >= (long)wp->w_virtcol) ! || (number_only && wlv.draw_state > WL_NR)) #ifdef FEAT_DIFF && filler_todo <= 0 #endif *************** *** 1516,1526 **** break; } ! if (draw_state == WL_LINE && (area_highlighting || extra_check)) { // handle Visual or match highlighting in this line if (wlv.vcol == fromcol ! || (has_mbyte && wlv.vcol + 1 == fromcol && n_extra == 0 && (*mb_ptr2cells)(ptr) > 1) || ((int)vcol_prev == fromcol_prev && vcol_prev < wlv.vcol // not at margin --- 1545,1555 ---- break; } ! if (wlv.draw_state == WL_LINE && (area_highlighting || extra_check)) { // handle Visual or match highlighting in this line if (wlv.vcol == fromcol ! || (has_mbyte && wlv.vcol + 1 == fromcol && wlv.n_extra == 0 && (*mb_ptr2cells)(ptr) > 1) || ((int)vcol_prev == fromcol_prev && vcol_prev < wlv.vcol // not at margin *************** *** 1532,1538 **** area_attr = 0; // stop highlighting #ifdef FEAT_SEARCH_EXTRA ! if (!n_extra) { // Check for start/end of 'hlsearch' and other matches. // After end, check for start/end of next match. --- 1561,1567 ---- area_attr = 0; // stop highlighting #ifdef FEAT_SEARCH_EXTRA ! if (!wlv.n_extra) { // Check for start/end of 'hlsearch' and other matches. // After end, check for start/end of next match. *************** *** 1553,1570 **** #endif #ifdef FEAT_DIFF ! if (diff_hlf != (hlf_T)0) { ! if (diff_hlf == HLF_CHD && ptr - line >= change_start ! && n_extra == 0) ! diff_hlf = HLF_TXD; // changed text ! if (diff_hlf == HLF_TXD && ptr - line > change_end ! && n_extra == 0) ! diff_hlf = HLF_CHD; // changed line ! line_attr = HL_ATTR(diff_hlf); if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR ! && (!cul_screenline || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col))) line_attr = hl_combine_attr( line_attr, HL_ATTR(HLF_CUL)); --- 1582,1599 ---- #endif #ifdef FEAT_DIFF ! if (wlv.diff_hlf != (hlf_T)0) { ! if (wlv.diff_hlf == HLF_CHD && ptr - line >= change_start ! && wlv.n_extra == 0) ! wlv.diff_hlf = HLF_TXD; // changed text ! if (wlv.diff_hlf == HLF_TXD && ptr - line > change_end ! && wlv.n_extra == 0) ! wlv.diff_hlf = HLF_CHD; // changed line ! line_attr = HL_ATTR(wlv.diff_hlf); if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR ! && (!wlv.cul_screenline || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col))) line_attr = hl_combine_attr( line_attr, HL_ATTR(HLF_CUL)); *************** *** 1577,1583 **** int pi; int bcol = (int)(ptr - line); ! if (n_extra > 0 # ifdef FEAT_LINEBREAK && !in_linebreak # endif --- 1606,1612 ---- int pi; int bcol = (int)(ptr - line); ! if (wlv.n_extra > 0 # ifdef FEAT_LINEBREAK && !in_linebreak # endif *************** *** 1608,1614 **** } # ifdef FEAT_LINEBREAK ! if (n_extra > 0 && in_linebreak) // not on the next char yet, don't start another prop --bcol; # endif --- 1637,1643 ---- } # ifdef FEAT_LINEBREAK ! if (wlv.n_extra > 0 && in_linebreak) // not on the next char yet, don't start another prop --bcol; # endif *************** *** 1628,1634 **** text_prop_flags = 0; text_prop_type = NULL; text_prop_id = 0; ! if (text_props_active > 0 && n_extra == 0) { int used_tpi = -1; int used_attr = 0; --- 1657,1663 ---- text_prop_flags = 0; text_prop_type = NULL; text_prop_id = 0; ! if (text_props_active > 0 && wlv.n_extra == 0) { int used_tpi = -1; int used_attr = 0; *************** *** 1668,1673 **** --- 1697,1707 ---- char_u *p = ((char_u **)wp->w_buffer ->b_textprop_text.ga_data)[ -text_prop_id - 1]; + + // reset the ID in the copy to avoid it being used + // again + text_props[used_tpi].tp_id = -MAXCOL; + if (p != NULL) { int right = (text_props[used_tpi].tp_flags *************** *** 1677,1686 **** int wrap = (text_props[used_tpi].tp_flags & TP_FLAG_WRAP); ! p_extra = p; ! c_extra = NUL; ! c_final = NUL; ! n_extra = (int)STRLEN(p); extra_attr = used_attr; n_attr = mb_charlen(p); text_prop_attr = 0; --- 1711,1720 ---- int wrap = (text_props[used_tpi].tp_flags & TP_FLAG_WRAP); ! wlv.p_extra = p; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; ! wlv.n_extra = (int)STRLEN(p); extra_attr = used_attr; n_attr = mb_charlen(p); text_prop_attr = 0; *************** *** 1702,1715 **** if ((right || below || !wrap) && wp->w_width > 2) { int added = wp->w_width - wlv.col; ! int n_used = n_extra; char_u *l; int strsize = wrap ! ? vim_strsize(p_extra) ! : textprop_size_after_trunc(wp, ! below, added, p_extra, &n_used); ! if (wrap || right || below || n_used < n_extra) { // Right-align: fill with spaces if (right) --- 1736,1750 ---- if ((right || below || !wrap) && wp->w_width > 2) { int added = wp->w_width - wlv.col; ! int n_used = wlv.n_extra; char_u *l; int strsize = wrap ! ? vim_strsize(wlv.p_extra) ! : textprop_size_after_trunc(wp, ! below, added, wlv.p_extra, &n_used); ! if (wrap || right || below ! || n_used < wlv.n_extra) { // Right-align: fill with spaces if (right) *************** *** 1717,1731 **** if (added < 0 || (below ? wlv.col == 0 || !wp->w_p_wrap ! : n_used < n_extra)) added = 0; // add 1 for NUL, 2 for when '…' is used l = alloc(n_used + added + 3); if (l != NULL) { vim_memset(l, ' ', added); ! vim_strncpy(l + added, p_extra, n_used); ! if (n_used < n_extra) { char_u *lp = l + added + n_used - 1; --- 1752,1767 ---- if (added < 0 || (below ? wlv.col == 0 || !wp->w_p_wrap ! : n_used < wlv.n_extra)) added = 0; // add 1 for NUL, 2 for when '…' is used l = alloc(n_used + added + 3); if (l != NULL) { vim_memset(l, ' ', added); ! vim_strncpy(l + added, wlv.p_extra, ! n_used); ! if (n_used < wlv.n_extra) { char_u *lp = l + added + n_used - 1; *************** *** 1740,1748 **** // change last character to '>' *lp = '>'; } ! vim_free(p_extra_free); ! p_extra = p_extra_free = l; ! n_extra = n_used + added; n_attr_skip = added; } } --- 1776,1784 ---- // change last character to '>' *lp = '>'; } ! vim_free(p_extra_free2); ! wlv.p_extra = p_extra_free2 = l; ! wlv.n_extra = n_used + added; n_attr_skip = added; } } *************** *** 1760,1772 **** ++wlv.row; break; } ! win_line_start(wp, &wlv); } } } - // reset the ID in the copy to avoid it being used - // again - text_props[used_tpi].tp_id = -MAXCOL; // If another text prop follows the condition below at // the last window column must know. --- 1796,1806 ---- ++wlv.row; break; } ! win_line_start(wp, &wlv, TRUE); ! continue; } } } // If another text prop follows the condition below at // the last window column must know. *************** *** 1785,1791 **** #endif #ifdef FEAT_SYN_HL ! if (extra_check && n_extra == 0) { syntax_attr = 0; # ifdef FEAT_TERMINAL --- 1819,1825 ---- #endif #ifdef FEAT_SYN_HL ! if (extra_check && wlv.n_extra == 0) { syntax_attr = 0; # ifdef FEAT_TERMINAL *************** *** 1863,1881 **** #ifdef LINE_ATTR if (area_attr != 0) { ! char_attr = hl_combine_attr(line_attr, area_attr); if (!highlight_match) // let search highlight show in Visual area if possible ! char_attr = hl_combine_attr(search_attr, char_attr); # ifdef FEAT_SYN_HL ! char_attr = hl_combine_attr(syntax_attr, char_attr); # endif } else if (search_attr != 0) { ! char_attr = hl_combine_attr(line_attr, search_attr); # ifdef FEAT_SYN_HL ! char_attr = hl_combine_attr(syntax_attr, char_attr); # endif } else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL) --- 1897,1915 ---- #ifdef LINE_ATTR if (area_attr != 0) { ! wlv.char_attr = hl_combine_attr(line_attr, area_attr); if (!highlight_match) // let search highlight show in Visual area if possible ! wlv.char_attr = hl_combine_attr(search_attr, wlv.char_attr); # ifdef FEAT_SYN_HL ! wlv.char_attr = hl_combine_attr(syntax_attr, wlv.char_attr); # endif } else if (search_attr != 0) { ! wlv.char_attr = hl_combine_attr(line_attr, search_attr); # ifdef FEAT_SYN_HL ! wlv.char_attr = hl_combine_attr(syntax_attr, wlv.char_attr); # endif } else if (line_attr != 0 && ((fromcol == -10 && tocol == MAXCOL) *************** *** 1885,1925 **** // Use line_attr when not in the Visual or 'incsearch' area // (area_attr may be 0 when "noinvcur" is set). # ifdef FEAT_SYN_HL ! char_attr = hl_combine_attr(syntax_attr, line_attr); # else ! char_attr = line_attr; # endif attr_pri = FALSE; } #else if (area_attr != 0) ! char_attr = area_attr; else if (search_attr != 0) ! char_attr = search_attr; #endif else { attr_pri = FALSE; #ifdef FEAT_SYN_HL ! char_attr = syntax_attr; #else ! char_attr = 0; #endif } #ifdef FEAT_PROP_POPUP // override with text property highlight when "override" is TRUE if (text_prop_type != NULL && (text_prop_flags & PT_FLAG_OVERRIDE)) ! char_attr = hl_combine_attr(char_attr, text_prop_attr); #endif } // combine attribute with 'wincolor' if (wlv.win_attr != 0) { ! if (char_attr == 0) ! char_attr = wlv.win_attr; else ! char_attr = hl_combine_attr(wlv.win_attr, char_attr); } // Get the next character to put on the screen. --- 1919,1959 ---- // Use line_attr when not in the Visual or 'incsearch' area // (area_attr may be 0 when "noinvcur" is set). # ifdef FEAT_SYN_HL ! wlv.char_attr = hl_combine_attr(syntax_attr, line_attr); # else ! wlv.char_attr = line_attr; # endif attr_pri = FALSE; } #else if (area_attr != 0) ! wlv.char_attr = area_attr; else if (search_attr != 0) ! wlv.char_attr = search_attr; #endif else { attr_pri = FALSE; #ifdef FEAT_SYN_HL ! wlv.char_attr = syntax_attr; #else ! wlv.char_attr = 0; #endif } #ifdef FEAT_PROP_POPUP // override with text property highlight when "override" is TRUE if (text_prop_type != NULL && (text_prop_flags & PT_FLAG_OVERRIDE)) ! wlv.char_attr = hl_combine_attr(wlv.char_attr, text_prop_attr); #endif } // combine attribute with 'wincolor' if (wlv.win_attr != 0) { ! if (wlv.char_attr == 0) ! wlv.char_attr = wlv.win_attr; else ! wlv.char_attr = hl_combine_attr(wlv.win_attr, wlv.char_attr); } // Get the next character to put on the screen. *************** *** 1927,1941 **** // The "p_extra" points to the extra stuff that is inserted to // represent special characters (non-printable stuff) and other // things. When all characters are the same, c_extra is used. ! // If c_final is set, it will compulsorily be used at the end. // "p_extra" must end in a NUL to avoid mb_ptr2len() reads past // "p_extra[n_extra]". // For the '$' of the 'list' option, n_extra == 1, p_extra == "". ! if (n_extra > 0) { ! if (c_extra != NUL || (n_extra == 1 && c_final != NUL)) { ! c = (n_extra == 1 && c_final != NUL) ? c_final : c_extra; mb_c = c; // doesn't handle non-utf-8 multi-byte! if (enc_utf8 && utf_char2len(c) > 1) { --- 1961,1976 ---- // The "p_extra" points to the extra stuff that is inserted to // represent special characters (non-printable stuff) and other // things. When all characters are the same, c_extra is used. ! // If wlv.c_final is set, it will compulsorily be used at the end. // "p_extra" must end in a NUL to avoid mb_ptr2len() reads past // "p_extra[n_extra]". // For the '$' of the 'list' option, n_extra == 1, p_extra == "". ! if (wlv.n_extra > 0) { ! if (wlv.c_extra != NUL || (wlv.n_extra == 1 && wlv.c_final != NUL)) { ! c = (wlv.n_extra == 1 && wlv.c_final != NUL) ! ? wlv.c_final : wlv.c_extra; mb_c = c; // doesn't handle non-utf-8 multi-byte! if (enc_utf8 && utf_char2len(c) > 1) { *************** *** 1948,1954 **** } else { ! c = *p_extra; if (has_mbyte) { mb_c = c; --- 1983,1989 ---- } else { ! c = *wlv.p_extra; if (has_mbyte) { mb_c = c; *************** *** 1956,1968 **** { // If the UTF-8 character is more than one byte: // Decode it into "mb_c". ! mb_l = utfc_ptr2len(p_extra); mb_utf8 = FALSE; ! if (mb_l > n_extra) mb_l = 1; else if (mb_l > 1) { ! mb_c = utfc_ptr2char(p_extra, u8cc); mb_utf8 = TRUE; c = 0xc0; } --- 1991,2003 ---- { // If the UTF-8 character is more than one byte: // Decode it into "mb_c". ! mb_l = utfc_ptr2len(wlv.p_extra); mb_utf8 = FALSE; ! if (mb_l > wlv.n_extra) mb_l = 1; else if (mb_l > 1) { ! mb_c = utfc_ptr2char(wlv.p_extra, u8cc); mb_utf8 = TRUE; c = 0xc0; } *************** *** 1971,1980 **** { // if this is a DBCS character, put it in "mb_c" mb_l = MB_BYTE2LEN(c); ! if (mb_l >= n_extra) mb_l = 1; else if (mb_l > 1) ! mb_c = (c << 8) + p_extra[1]; } if (mb_l == 0) // at the NUL at end-of-line mb_l = 1; --- 2006,2015 ---- { // if this is a DBCS character, put it in "mb_c" mb_l = MB_BYTE2LEN(c); ! if (mb_l >= wlv.n_extra) mb_l = 1; else if (mb_l > 1) ! mb_c = (c << 8) + wlv.p_extra[1]; } if (mb_l == 0) // at the NUL at end-of-line mb_l = 1; *************** *** 2001,2020 **** // put the pointer back to output the double-width // character at the start of the next line. ! ++n_extra; ! --p_extra; } else { ! n_extra -= mb_l - 1; ! p_extra += mb_l - 1; } } ! ++p_extra; } ! --n_extra; #if defined(FEAT_LINEBREAK) && defined(FEAT_PROP_POPUP) ! if (n_extra <= 0) in_linebreak = FALSE; #endif } --- 2036,2055 ---- // put the pointer back to output the double-width // character at the start of the next line. ! ++wlv.n_extra; ! --wlv.p_extra; } else { ! wlv.n_extra -= mb_l - 1; ! wlv.p_extra += mb_l - 1; } } ! ++wlv.p_extra; } ! --wlv.n_extra; #if defined(FEAT_LINEBREAK) && defined(FEAT_PROP_POPUP) ! if (wlv.n_extra <= 0) in_linebreak = FALSE; #endif } *************** *** 2023,2029 **** #ifdef FEAT_LINEBREAK int c0; #endif - VIM_CLEAR(p_extra_free); prev_ptr = ptr; // Get a character from the line itself. --- 2058,2063 ---- *************** *** 2078,2096 **** if (wp->w_p_rl) // reverse rl_mirror(extra); # endif ! p_extra = extra; ! c = *p_extra; ! mb_c = mb_ptr2char_adv(&p_extra); mb_utf8 = (c >= 0x80); ! n_extra = (int)STRLEN(p_extra); ! c_extra = NUL; ! c_final = NUL; if (area_attr == 0 && search_attr == 0) { ! n_attr = n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr } } else if (mb_l == 0) // at the NUL at end-of-line --- 2112,2130 ---- if (wp->w_p_rl) // reverse rl_mirror(extra); # endif ! wlv.p_extra = extra; ! c = *wlv.p_extra; ! mb_c = mb_ptr2char_adv(&wlv.p_extra); mb_utf8 = (c >= 0x80); ! wlv.n_extra = (int)STRLEN(wlv.p_extra); ! wlv.c_extra = NUL; ! wlv.c_final = NUL; if (area_attr == 0 && search_attr == 0) { ! n_attr = wlv.n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = wlv.char_attr; // save current attr } } else if (mb_l == 0) // at the NUL at end-of-line *************** *** 2150,2166 **** mb_l = 2; STRCPY(extra, "XX"); } ! p_extra = extra; ! n_extra = (int)STRLEN(extra) - 1; ! c_extra = NUL; ! c_final = NUL; ! c = *p_extra++; if (area_attr == 0 && search_attr == 0) { ! n_attr = n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr } mb_c = c; } --- 2184,2201 ---- mb_l = 2; STRCPY(extra, "XX"); } ! wlv.p_extra = extra; ! wlv.n_extra = (int)STRLEN(extra) - 1; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; ! c = *wlv.p_extra++; if (area_attr == 0 && search_attr == 0) { ! n_attr = wlv.n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_8)); ! // save current attr ! saved_attr2 = wlv.char_attr; } mb_c = c; } *************** *** 2194,2211 **** // If a double-width char doesn't fit at the left side display // a '<' in the first column. Don't do this for unprintable // characters. ! if (n_skip > 0 && mb_l > 1 && n_extra == 0) { ! n_extra = 1; ! c_extra = MB_FILLER_CHAR; ! c_final = NUL; c = ' '; if (area_attr == 0 && search_attr == 0) { ! n_attr = n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_AT)); ! saved_attr2 = char_attr; // save current attr } mb_c = c; mb_utf8 = FALSE; --- 2229,2246 ---- // If a double-width char doesn't fit at the left side display // a '<' in the first column. Don't do this for unprintable // characters. ! if (n_skip > 0 && mb_l > 1 && wlv.n_extra == 0) { ! wlv.n_extra = 1; ! wlv.c_extra = MB_FILLER_CHAR; ! wlv.c_final = NUL; c = ' '; if (area_attr == 0 && search_attr == 0) { ! n_attr = wlv.n_extra + 1; extra_attr = hl_combine_attr( wlv.win_attr, HL_ATTR(HLF_AT)); ! saved_attr2 = wlv.char_attr; // save current attr } mb_c = c; mb_utf8 = FALSE; *************** *** 2297,2305 **** if (spell_attr != 0) { if (!attr_pri) ! char_attr = hl_combine_attr(char_attr, spell_attr); else ! char_attr = hl_combine_attr(spell_attr, char_attr); } #endif #ifdef FEAT_LINEBREAK --- 2332,2342 ---- if (spell_attr != 0) { if (!attr_pri) ! wlv.char_attr = hl_combine_attr(wlv.char_attr, ! spell_attr); else ! wlv.char_attr = hl_combine_attr(spell_attr, ! wlv.char_attr); } #endif #ifdef FEAT_LINEBREAK *************** *** 2313,2327 **** chartabsize_T cts; init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, p); ! n_extra = win_lbr_chartabsize(&cts, NULL) - 1; // We have just drawn the showbreak value, no need to add // space for it again. if (wlv.vcol == vcol_sbr) { ! n_extra -= MB_CHARLEN(get_showbreak_value(wp)); ! if (n_extra < 0) ! n_extra = 0; } if (on_last_col && c != TAB) // Do not continue search/match highlighting over the --- 2350,2364 ---- chartabsize_T cts; init_chartabsize_arg(&cts, wp, lnum, wlv.vcol, line, p); ! wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; // We have just drawn the showbreak value, no need to add // space for it again. if (wlv.vcol == vcol_sbr) { ! wlv.n_extra -= MB_CHARLEN(get_showbreak_value(wp)); ! if (wlv.n_extra < 0) ! wlv.n_extra = 0; } if (on_last_col && c != TAB) // Do not continue search/match highlighting over the *************** *** 2329,2348 **** // include the complete width of the character search_attr = 0; ! if (c == TAB && n_extra + wlv.col > wp->w_width) # ifdef FEAT_VARTABS ! n_extra = tabstop_padding(wlv.vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; # else ! n_extra = (int)wp->w_buffer->b_p_ts - wlv.vcol % (int)wp->w_buffer->b_p_ts - 1; # endif ! c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; ! c_final = NUL; # if defined(FEAT_PROP_POPUP) ! if (n_extra > 0 && c != TAB) in_linebreak = TRUE; # endif if (VIM_ISWHITE(c)) --- 2366,2385 ---- // include the complete width of the character search_attr = 0; ! if (c == TAB && wlv.n_extra + wlv.col > wp->w_width) # ifdef FEAT_VARTABS ! wlv.n_extra = tabstop_padding(wlv.vcol, wp->w_buffer->b_p_ts, wp->w_buffer->b_p_vts_array) - 1; # else ! wlv.n_extra = (int)wp->w_buffer->b_p_ts - wlv.vcol % (int)wp->w_buffer->b_p_ts - 1; # endif ! wlv.c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; ! wlv.c_final = NUL; # if defined(FEAT_PROP_POPUP) ! if (wlv.n_extra > 0 && c != TAB) in_linebreak = TRUE; # endif if (VIM_ISWHITE(c)) *************** *** 2395,2401 **** n_attr = 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr } mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) --- 2432,2438 ---- n_attr = 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = wlv.char_attr; // save current attr } mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) *************** *** 2435,2441 **** n_attr = 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr } mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) --- 2472,2478 ---- n_attr = 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = wlv.char_attr; // save current attr } mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) *************** *** 2481,2494 **** if (!wp->w_p_lbr || !wp->w_p_list) #endif // tab amount depends on current column ! n_extra = tab_len; #ifdef FEAT_LINEBREAK else { char_u *p; int len; int i; ! int saved_nextra = n_extra; # ifdef FEAT_CONCEAL if (wlv.vcol_off > 0) --- 2518,2531 ---- if (!wp->w_p_lbr || !wp->w_p_list) #endif // tab amount depends on current column ! wlv.n_extra = tab_len; #ifdef FEAT_LINEBREAK else { char_u *p; int len; int i; ! int saved_nextra = wlv.n_extra; # ifdef FEAT_CONCEAL if (wlv.vcol_off > 0) *************** *** 2497,2518 **** // boguscols before FIX_FOR_BOGUSCOLS macro from above if (wp->w_p_list && wp->w_lcs_chars.tab1 ! && old_boguscols > 0 ! && n_extra > tab_len) ! tab_len += n_extra - tab_len; # endif ! // If n_extra > 0, it gives the number of chars, to // use for a tab, else we need to calculate the width // for a tab. len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2)); if (wp->w_lcs_chars.tab3) len += mb_char2len(wp->w_lcs_chars.tab3); ! if (n_extra > 0) ! len += n_extra - tab_len; c = wp->w_lcs_chars.tab1; p = alloc(len + 1); if (p == NULL) ! n_extra = 0; else { vim_memset(p, ' ', len); --- 2534,2555 ---- // boguscols before FIX_FOR_BOGUSCOLS macro from above if (wp->w_p_list && wp->w_lcs_chars.tab1 ! && old_boguscols > 0 ! && wlv.n_extra > tab_len) ! tab_len += wlv.n_extra - tab_len; # endif ! // If wlv.n_extra > 0, it gives the number of chars, to // use for a tab, else we need to calculate the width // for a tab. len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2)); if (wp->w_lcs_chars.tab3) len += mb_char2len(wp->w_lcs_chars.tab3); ! if (wlv.n_extra > 0) ! len += wlv.n_extra - tab_len; c = wp->w_lcs_chars.tab1; p = alloc(len + 1); if (p == NULL) ! wlv.n_extra = 0; else { vim_memset(p, ' ', len); *************** *** 2533,2547 **** if (wp->w_lcs_chars.tab3 && i == tab_len - 1) lcs = wp->w_lcs_chars.tab3; p += mb_char2bytes(lcs, p); ! n_extra += mb_char2len(lcs) - (saved_nextra > 0 ? 1 : 0); } ! p_extra = p_extra_free; # ifdef FEAT_CONCEAL // n_extra will be increased by FIX_FOX_BOGUSCOLS // macro below, so need to adjust for that here if (wlv.vcol_off > 0) ! n_extra -= wlv.vcol_off; # endif } } --- 2570,2584 ---- if (wp->w_lcs_chars.tab3 && i == tab_len - 1) lcs = wp->w_lcs_chars.tab3; p += mb_char2bytes(lcs, p); ! wlv.n_extra += mb_char2len(lcs) - (saved_nextra > 0 ? 1 : 0); } ! wlv.p_extra = p_extra_free; # ifdef FEAT_CONCEAL // n_extra will be increased by FIX_FOX_BOGUSCOLS // macro below, so need to adjust for that here if (wlv.vcol_off > 0) ! wlv.n_extra -= wlv.vcol_off; # endif } } *************** *** 2561,2567 **** // Make sure, the highlighting for the tab char will be // correctly set further below (effectively reverts the // FIX_FOR_BOGSUCOLS macro). ! if (n_extra == tab_len + vc_saved && wp->w_p_list && wp->w_lcs_chars.tab1) tab_len += vc_saved; } --- 2598,2604 ---- // Make sure, the highlighting for the tab char will be // correctly set further below (effectively reverts the // FIX_FOR_BOGSUCOLS macro). ! if (wlv.n_extra == tab_len + vc_saved && wp->w_p_list && wp->w_lcs_chars.tab1) tab_len += vc_saved; } *************** *** 2569,2588 **** mb_utf8 = FALSE; // don't draw as UTF-8 if (wp->w_p_list) { ! c = (n_extra == 0 && wp->w_lcs_chars.tab3) ? wp->w_lcs_chars.tab3 : wp->w_lcs_chars.tab1; #ifdef FEAT_LINEBREAK if (wp->w_p_lbr) ! c_extra = NUL; // using p_extra from above else #endif ! c_extra = wp->w_lcs_chars.tab2; ! c_final = wp->w_lcs_chars.tab3; n_attr = tab_len + 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) { --- 2606,2625 ---- mb_utf8 = FALSE; // don't draw as UTF-8 if (wp->w_p_list) { ! c = (wlv.n_extra == 0 && wp->w_lcs_chars.tab3) ? wp->w_lcs_chars.tab3 : wp->w_lcs_chars.tab1; #ifdef FEAT_LINEBREAK if (wp->w_p_lbr) ! wlv.c_extra = NUL; // using p_extra from above else #endif ! wlv.c_extra = wp->w_lcs_chars.tab2; ! wlv.c_final = wp->w_lcs_chars.tab3; n_attr = tab_len + 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = wlv.char_attr; // save current attr mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) { *************** *** 2593,2600 **** } else { ! c_final = NUL; ! c_extra = ' '; c = ' '; } } --- 2630,2637 ---- } else { ! wlv.c_final = NUL; ! wlv.c_extra = ' '; c = ' '; } } *************** *** 2620,2626 **** // "$". if ( # ifdef FEAT_DIFF ! diff_hlf == (hlf_T)0 # ifdef LINE_ATTR && # endif --- 2657,2663 ---- // "$". if ( # ifdef FEAT_DIFF ! wlv.diff_hlf == (hlf_T)0 # ifdef LINE_ATTR && # endif *************** *** 2635,2647 **** // beyond end of line. if (area_highlighting && virtual_active() && tocol != MAXCOL && wlv.vcol < tocol) ! n_extra = 0; else { ! p_extra = at_end_str; ! n_extra = 1; ! c_extra = NUL; ! c_final = NUL; } } if (wp->w_p_list && wp->w_lcs_chars.eol > 0) --- 2672,2684 ---- // beyond end of line. if (area_highlighting && virtual_active() && tocol != MAXCOL && wlv.vcol < tocol) ! wlv.n_extra = 0; else { ! wlv.p_extra = at_end_str; ! wlv.n_extra = 1; ! wlv.c_extra = NUL; ! wlv.c_final = NUL; } } if (wp->w_p_list && wp->w_lcs_chars.eol > 0) *************** *** 2668,2707 **** } else if (c != NUL) { ! p_extra = transchar_buf(wp->w_buffer, c); ! if (n_extra == 0) ! n_extra = byte2cells(c) - 1; #ifdef FEAT_RIGHTLEFT if ((dy_flags & DY_UHEX) && wp->w_p_rl) ! rl_mirror(p_extra); // reverse "<12>" #endif ! c_extra = NUL; ! c_final = NUL; #ifdef FEAT_LINEBREAK if (wp->w_p_lbr) { char_u *p; ! c = *p_extra; ! p = alloc(n_extra + 1); ! vim_memset(p, ' ', n_extra); ! STRNCPY(p, p_extra + 1, STRLEN(p_extra) - 1); ! p[n_extra] = NUL; vim_free(p_extra_free); ! p_extra_free = p_extra = p; } else #endif { ! n_extra = byte2cells(c) - 1; ! c = *p_extra++; } if (!attr_pri) { ! n_attr = n_extra + 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = char_attr; // save current attr } mb_utf8 = FALSE; // don't draw as UTF-8 } --- 2705,2744 ---- } else if (c != NUL) { ! wlv.p_extra = transchar_buf(wp->w_buffer, c); ! if (wlv.n_extra == 0) ! wlv.n_extra = byte2cells(c) - 1; #ifdef FEAT_RIGHTLEFT if ((dy_flags & DY_UHEX) && wp->w_p_rl) ! rl_mirror(wlv.p_extra); // reverse "<12>" #endif ! wlv.c_extra = NUL; ! wlv.c_final = NUL; #ifdef FEAT_LINEBREAK if (wp->w_p_lbr) { char_u *p; ! c = *wlv.p_extra; ! p = alloc(wlv.n_extra + 1); ! vim_memset(p, ' ', wlv.n_extra); ! STRNCPY(p, wlv.p_extra + 1, STRLEN(wlv.p_extra) - 1); ! p[wlv.n_extra] = NUL; vim_free(p_extra_free); ! p_extra_free = wlv.p_extra = p; } else #endif { ! wlv.n_extra = byte2cells(c) - 1; ! c = *wlv.p_extra++; } if (!attr_pri) { ! n_attr = wlv.n_extra + 1; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_8)); ! saved_attr2 = wlv.char_attr; // save current attr } mb_utf8 = FALSE; // don't draw as UTF-8 } *************** *** 2723,2729 **** #if defined(LINE_ATTR) else if (( # ifdef FEAT_DIFF ! diff_hlf != (hlf_T)0 || # endif # ifdef FEAT_TERMINAL wlv.win_attr != 0 || --- 2760,2766 ---- #if defined(LINE_ATTR) else if (( # ifdef FEAT_DIFF ! wlv.diff_hlf != (hlf_T)0 || # endif # ifdef FEAT_TERMINAL wlv.win_attr != 0 || *************** *** 2747,2788 **** ++did_line_attr; // don't do search HL for the rest of the line ! if (line_attr != 0 && char_attr == search_attr && (did_line_attr > 1 || (wp->w_p_list && wp->w_lcs_chars.eol > 0))) ! char_attr = line_attr; # ifdef FEAT_DIFF ! if (diff_hlf == HLF_TXD) { ! diff_hlf = HLF_CHD; ! if (vi_attr == 0 || char_attr != vi_attr) { ! char_attr = HL_ATTR(diff_hlf); if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR ! && (!cul_screenline || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col))) ! char_attr = hl_combine_attr( ! char_attr, HL_ATTR(HLF_CUL)); } } # endif # ifdef FEAT_TERMINAL if (wlv.win_attr != 0) { ! char_attr = wlv.win_attr; if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR) { ! if (!cul_screenline || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col)) ! char_attr = hl_combine_attr( ! char_attr, HL_ATTR(HLF_CUL)); } else if (line_attr) ! char_attr = hl_combine_attr(char_attr, line_attr); } # endif } --- 2784,2827 ---- ++did_line_attr; // don't do search HL for the rest of the line ! if (line_attr != 0 && wlv.char_attr == search_attr && (did_line_attr > 1 || (wp->w_p_list && wp->w_lcs_chars.eol > 0))) ! wlv.char_attr = line_attr; # ifdef FEAT_DIFF ! if (wlv.diff_hlf == HLF_TXD) { ! wlv.diff_hlf = HLF_CHD; ! if (vi_attr == 0 || wlv.char_attr != vi_attr) { ! wlv.char_attr = HL_ATTR(wlv.diff_hlf); if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR ! && (!wlv.cul_screenline || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col))) ! wlv.char_attr = hl_combine_attr( ! wlv.char_attr, HL_ATTR(HLF_CUL)); } } # endif # ifdef FEAT_TERMINAL if (wlv.win_attr != 0) { ! wlv.char_attr = wlv.win_attr; if (wp->w_p_cul && lnum == wp->w_cursor.lnum && wp->w_p_culopt_flags != CULOPT_NBR) { ! if (!wlv.cul_screenline ! || (wlv.vcol >= left_curline_col && wlv.vcol <= right_curline_col)) ! wlv.char_attr = hl_combine_attr( ! wlv.char_attr, HL_ATTR(HLF_CUL)); } else if (line_attr) ! wlv.char_attr = hl_combine_attr(wlv.char_attr, ! line_attr); } # endif } *************** *** 2797,2803 **** && !(lnum_in_visual_area && vim_strchr(wp->w_p_cocu, 'v') == NULL)) { ! char_attr = conceal_attr; if (((prev_syntax_id != syntax_seqnr && (syntax_flags & HL_CONCEAL) != 0) || has_match_conc > 1) --- 2836,2842 ---- && !(lnum_in_visual_area && vim_strchr(wp->w_p_cocu, 'v') == NULL)) { ! wlv.char_attr = conceal_attr; if (((prev_syntax_id != syntax_seqnr && (syntax_flags & HL_CONCEAL) != 0) || has_match_conc > 1) *************** *** 2819,2843 **** prev_syntax_id = syntax_seqnr; ! if (n_extra > 0) ! wlv.vcol_off += n_extra; ! wlv.vcol += n_extra; ! if (wp->w_p_wrap && n_extra > 0) { # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) { ! wlv.col -= n_extra; ! wlv.boguscols -= n_extra; } else # endif { ! wlv.boguscols += n_extra; ! wlv.col += n_extra; } } ! n_extra = 0; n_attr = 0; } else if (n_skip == 0) --- 2858,2882 ---- prev_syntax_id = syntax_seqnr; ! if (wlv.n_extra > 0) ! wlv.vcol_off += wlv.n_extra; ! wlv.vcol += wlv.n_extra; ! if (wp->w_p_wrap && wlv.n_extra > 0) { # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) { ! wlv.col -= wlv.n_extra; ! wlv.boguscols -= wlv.n_extra; } else # endif { ! wlv.boguscols += wlv.n_extra; ! wlv.col += wlv.n_extra; } } ! wlv.n_extra = 0; n_attr = 0; } else if (n_skip == 0) *************** *** 2871,2877 **** #ifdef FEAT_CONCEAL // In the cursor line and we may be concealing characters: correct // the cursor column when we reach its position. ! if (!did_wcol && draw_state == WL_LINE && wp == curwin && lnum == wp->w_cursor.lnum && conceal_cursor_line(wp) && (int)wp->w_virtcol <= wlv.vcol + n_skip) --- 2910,2916 ---- #ifdef FEAT_CONCEAL // In the cursor line and we may be concealing characters: correct // the cursor column when we reach its position. ! if (!did_wcol && wlv.draw_state == WL_LINE && wp == curwin && lnum == wp->w_cursor.lnum && conceal_cursor_line(wp) && (int)wp->w_virtcol <= wlv.vcol + n_skip) *************** *** 2894,2908 **** // Use "extra_attr", but don't override visual selection highlighting. // Don't use "extra_attr" until n_attr_skip is zero. if (n_attr_skip == 0 && n_attr > 0 ! && draw_state == WL_LINE && !attr_pri) { #ifdef LINE_ATTR if (line_attr) ! char_attr = hl_combine_attr(extra_attr, line_attr); else #endif ! char_attr = extra_attr; } #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) --- 2933,2947 ---- // Use "extra_attr", but don't override visual selection highlighting. // Don't use "extra_attr" until n_attr_skip is zero. if (n_attr_skip == 0 && n_attr > 0 ! && wlv.draw_state == WL_LINE && !attr_pri) { #ifdef LINE_ATTR if (line_attr) ! wlv.char_attr = hl_combine_attr(extra_attr, line_attr); else #endif ! wlv.char_attr = extra_attr; } #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) *************** *** 2915,2921 **** && (State & MODE_INSERT) && !p_imdisable && im_is_preediting() ! && draw_state == WL_LINE) { colnr_T tcol; --- 2954,2960 ---- && (State & MODE_INSERT) && !p_imdisable && im_is_preediting() ! && wlv.draw_state == WL_LINE) { colnr_T tcol; *************** *** 2928,2943 **** if (feedback_old_attr < 0) { feedback_col = 0; ! feedback_old_attr = char_attr; } ! char_attr = im_get_feedback_attr(feedback_col); ! if (char_attr < 0) ! char_attr = feedback_old_attr; feedback_col++; } else if (feedback_old_attr >= 0) { ! char_attr = feedback_old_attr; feedback_old_attr = -1; feedback_col = 0; } --- 2967,2982 ---- if (feedback_old_attr < 0) { feedback_col = 0; ! feedback_old_attr = wlv.char_attr; } ! wlv.char_attr = im_get_feedback_attr(feedback_col); ! if (wlv.char_attr < 0) ! wlv.char_attr = feedback_old_attr; feedback_col++; } else if (feedback_old_attr >= 0) { ! wlv.char_attr = feedback_old_attr; feedback_old_attr = -1; feedback_col = 0; } *************** *** 2954,2960 **** #ifdef FEAT_DIFF && filler_todo <= 0 #endif ! && draw_state > WL_NR && c != NUL) { c = wp->w_lcs_chars.prec; --- 2993,2999 ---- #ifdef FEAT_DIFF && filler_todo <= 0 #endif ! && wlv.draw_state > WL_NR && c != NUL) { c = wp->w_lcs_chars.prec; *************** *** 2963,2971 **** { // Double-width character being overwritten by the "precedes" // character, need to fill up half the character. ! c_extra = MB_FILLER_CHAR; ! c_final = NUL; ! n_extra = 1; n_attr = 2; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); } --- 3002,3010 ---- { // Double-width character being overwritten by the "precedes" // character, need to fill up half the character. ! wlv.c_extra = MB_FILLER_CHAR; ! wlv.c_final = NUL; ! wlv.n_extra = 1; n_attr = 2; extra_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); } *************** *** 2980,2987 **** mb_utf8 = FALSE; // don't draw as UTF-8 if (!attr_pri) { ! saved_attr3 = char_attr; // save current attr ! char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); n_attr3 = 1; } } --- 3019,3026 ---- mb_utf8 = FALSE; // don't draw as UTF-8 if (!attr_pri) { ! saved_attr3 = wlv.char_attr; // save current attr ! wlv.char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); n_attr3 = 1; } } *************** *** 3017,3023 **** && !(wp == curwin && VIsual_active)) # endif # ifdef FEAT_DIFF ! && diff_hlf == (hlf_T)0 # endif # if defined(LINE_ATTR) && did_line_attr <= 1 --- 3056,3062 ---- && !(wp == curwin && VIsual_active)) # endif # ifdef FEAT_DIFF ! && wlv.diff_hlf == (hlf_T)0 # endif # if defined(LINE_ATTR) && did_line_attr <= 1 *************** *** 3060,3069 **** // Use attributes from match with highest priority among // 'search_hl' and the match list. get_search_match_hl(wp, &screen_search_hl, ! (long)(ptr - line), &char_attr); } #endif ! ScreenAttrs[wlv.off] = char_attr; ScreenCols[wlv.off] = MAXCOL; #ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) --- 3099,3108 ---- // Use attributes from match with highest priority among // 'search_hl' and the match list. get_search_match_hl(wp, &screen_search_hl, ! (long)(ptr - line), &wlv.char_attr); } #endif ! ScreenAttrs[wlv.off] = wlv.char_attr; ScreenCols[wlv.off] = MAXCOL; #ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) *************** *** 3104,3110 **** // Show "extends" character from 'listchars' if beyond the line end and // 'list' is set. if (wp->w_lcs_chars.ext != NUL ! && draw_state == WL_LINE && wp->w_p_list && !wp->w_p_wrap #ifdef FEAT_DIFF --- 3143,3149 ---- // Show "extends" character from 'listchars' if beyond the line end and // 'list' is set. if (wp->w_lcs_chars.ext != NUL ! && wlv.draw_state == WL_LINE && wp->w_p_list && !wp->w_p_wrap #ifdef FEAT_DIFF *************** *** 3117,3126 **** wlv.col == wp->w_width - 1) && (*ptr != NUL || (wp->w_p_list && lcs_eol_one > 0) ! || (n_extra && (c_extra != NUL || *p_extra != NUL)))) { c = wp->w_lcs_chars.ext; ! char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) { --- 3156,3166 ---- wlv.col == wp->w_width - 1) && (*ptr != NUL || (wp->w_p_list && lcs_eol_one > 0) ! || (wlv.n_extra && (wlv.c_extra != NUL ! || *wlv.p_extra != NUL)))) { c = wp->w_lcs_chars.ext; ! wlv.char_attr = hl_combine_attr(wlv.win_attr, HL_ATTR(HLF_AT)); mb_c = c; if (enc_utf8 && utf_char2len(c) > 1) { *************** *** 3144,3153 **** // Also highlight the 'colorcolumn' if 'breakindent' and/or 'showbreak' // options are set vcol_save_attr = -1; ! if (((draw_state == WL_LINE || ! draw_state == WL_BRI || ! draw_state == WL_SBR) && !lnum_in_visual_area ! && search_attr == 0 && area_attr == 0) # ifdef FEAT_DIFF && filler_todo <= 0 # endif --- 3184,3195 ---- // Also highlight the 'colorcolumn' if 'breakindent' and/or 'showbreak' // options are set vcol_save_attr = -1; ! if (((wlv.draw_state == WL_LINE ! || wlv.draw_state == WL_BRI ! || wlv.draw_state == WL_SBR) ! && !lnum_in_visual_area ! && search_attr == 0 ! && area_attr == 0) # ifdef FEAT_DIFF && filler_todo <= 0 # endif *************** *** 3156,3168 **** if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum) { ! vcol_save_attr = char_attr; ! char_attr = hl_combine_attr(char_attr, HL_ATTR(HLF_CUC)); } else if (wlv.draw_color_col && VCOL_HLC == *wlv.color_cols) { ! vcol_save_attr = char_attr; ! char_attr = hl_combine_attr(char_attr, HL_ATTR(HLF_MC)); } } #endif --- 3198,3211 ---- if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum) { ! vcol_save_attr = wlv.char_attr; ! wlv.char_attr = hl_combine_attr(wlv.char_attr, ! HL_ATTR(HLF_CUC)); } else if (wlv.draw_color_col && VCOL_HLC == *wlv.color_cols) { ! vcol_save_attr = wlv.char_attr; ! wlv.char_attr = hl_combine_attr(wlv.char_attr, HL_ATTR(HLF_MC)); } } #endif *************** *** 3170,3176 **** // Store character to be displayed. // Skip characters that are left of the screen for 'nowrap'. vcol_prev = wlv.vcol; ! if (draw_state < WL_LINE || n_skip <= 0) { // Store the character. #if defined(FEAT_RIGHTLEFT) --- 3213,3219 ---- // Store character to be displayed. // Skip characters that are left of the screen for 'nowrap'. vcol_prev = wlv.vcol; ! if (wlv.draw_state < WL_LINE || n_skip <= 0) { // Store the character. #if defined(FEAT_RIGHTLEFT) *************** *** 3213,3219 **** multi_attr = 0; } else ! ScreenAttrs[wlv.off] = char_attr; ScreenCols[wlv.off] = (colnr_T)(prev_ptr - line); --- 3256,3262 ---- multi_attr = 0; } else ! ScreenAttrs[wlv.off] = wlv.char_attr; ScreenCols[wlv.off] = (colnr_T)(prev_ptr - line); *************** *** 3228,3234 **** else // DBCS: Put second byte in the second screen char. ScreenLines[wlv.off] = mb_c & 0xff; ! if (draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 #endif --- 3271,3277 ---- else // DBCS: Put second byte in the second screen char. ScreenLines[wlv.off] = mb_c & 0xff; ! if (wlv.draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 #endif *************** *** 3268,3275 **** { --n_skip; ++wlv.vcol_off; ! if (n_extra > 0) ! wlv.vcol_off += n_extra; if (wp->w_p_wrap) { // Special voodoo required if 'wrap' is on. --- 3311,3318 ---- { --n_skip; ++wlv.vcol_off; ! if (wlv.n_extra > 0) ! wlv.vcol_off += wlv.n_extra; if (wp->w_p_wrap) { // Special voodoo required if 'wrap' is on. *************** *** 3283,3304 **** // trailing junk to be written out of the screen line // we are building, 'boguscols' keeps track of the number // of bad columns we have advanced. ! if (n_extra > 0) { ! wlv.vcol += n_extra; # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) { ! wlv.col -= n_extra; ! wlv.boguscols -= n_extra; } else # endif { ! wlv.col += n_extra; ! wlv.boguscols += n_extra; } ! n_extra = 0; n_attr = 0; } --- 3326,3347 ---- // trailing junk to be written out of the screen line // we are building, 'boguscols' keeps track of the number // of bad columns we have advanced. ! if (wlv.n_extra > 0) { ! wlv.vcol += wlv.n_extra; # ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) { ! wlv.col -= wlv.n_extra; ! wlv.boguscols -= wlv.n_extra; } else # endif { ! wlv.col += wlv.n_extra; ! wlv.boguscols += wlv.n_extra; } ! wlv.n_extra = 0; n_attr = 0; } *************** *** 3335,3344 **** } else { ! if (n_extra > 0) { ! wlv.vcol += n_extra; ! n_extra = 0; n_attr = 0; } } --- 3378,3387 ---- } else { ! if (wlv.n_extra > 0) { ! wlv.vcol += wlv.n_extra; ! wlv.n_extra = 0; n_attr = 0; } } *************** *** 3350,3356 **** // Only advance the "wlv.vcol" when after the 'number' or // 'relativenumber' column. ! if (draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 #endif --- 3393,3399 ---- // Only advance the "wlv.vcol" when after the 'number' or // 'relativenumber' column. ! if (wlv.draw_state > WL_NR #ifdef FEAT_DIFF && filler_todo <= 0 #endif *************** *** 3359,3375 **** #ifdef FEAT_SYN_HL if (vcol_save_attr >= 0) ! char_attr = vcol_save_attr; #endif // restore attributes after "predeces" in 'listchars' ! if (draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0) ! char_attr = saved_attr3; // restore attributes after last 'listchars' or 'number' char ! if (n_attr > 0 && draw_state == WL_LINE && n_attr_skip == 0 && --n_attr == 0) ! char_attr = saved_attr2; if (n_attr_skip > 0) --n_attr_skip; --- 3402,3418 ---- #ifdef FEAT_SYN_HL if (vcol_save_attr >= 0) ! wlv.char_attr = vcol_save_attr; #endif // restore attributes after "predeces" in 'listchars' ! if (wlv.draw_state > WL_NR && n_attr3 > 0 && --n_attr3 == 0) ! wlv.char_attr = saved_attr3; // restore attributes after last 'listchars' or 'number' char ! if (n_attr > 0 && wlv.draw_state == WL_LINE && n_attr_skip == 0 && --n_attr == 0) ! wlv.char_attr = saved_attr2; if (n_attr_skip > 0) --n_attr_skip; *************** *** 3380,3386 **** wp->w_p_rl ? (wlv.col < 0) : #endif (wlv.col >= wp->w_width)) ! && (draw_state != WL_LINE || *ptr != NUL #ifdef FEAT_DIFF || filler_todo > 0 --- 3423,3429 ---- wp->w_p_rl ? (wlv.col < 0) : #endif (wlv.col >= wp->w_width)) ! && (wlv.draw_state != WL_LINE || *ptr != NUL #ifdef FEAT_DIFF || filler_todo > 0 *************** *** 3389,3396 **** || text_prop_follows #endif || (wp->w_p_list && wp->w_lcs_chars.eol != NUL ! && p_extra != at_end_str) ! || (n_extra != 0 && (c_extra != NUL || *p_extra != NUL))) ) { #ifdef FEAT_CONCEAL --- 3432,3440 ---- || text_prop_follows #endif || (wp->w_p_list && wp->w_lcs_chars.eol != NUL ! && wlv.p_extra != at_end_str) ! || (wlv.n_extra != 0 && (wlv.c_extra != NUL ! || *wlv.p_extra != NUL))) ) { #ifdef FEAT_CONCEAL *************** *** 3418,3424 **** break; // When the window is too narrow draw all "@" lines. ! if (draw_state != WL_LINE #ifdef FEAT_DIFF && filler_todo <= 0 #endif --- 3462,3468 ---- break; // When the window is too narrow draw all "@" lines. ! if (wlv.draw_state != WL_LINE #ifdef FEAT_DIFF && filler_todo <= 0 #endif *************** *** 3495,3519 **** } } ! win_line_start(wp, &wlv); - // reset the drawing state for the start of a wrapped line - draw_state = WL_START; - saved_n_extra = n_extra; - saved_p_extra = p_extra; - saved_c_extra = c_extra; - saved_c_final = c_final; - #ifdef FEAT_SYN_HL - if (!(cul_screenline - # ifdef FEAT_DIFF - && diff_hlf == (hlf_T)0 - # endif - )) - saved_char_attr = char_attr; - else - #endif - saved_char_attr = 0; - n_extra = 0; lcs_prec_todo = wp->w_lcs_chars.prec; #ifdef FEAT_LINEBREAK if (!dont_use_showbreak --- 3539,3546 ---- } } ! win_line_start(wp, &wlv, TRUE); lcs_prec_todo = wp->w_lcs_chars.prec; #ifdef FEAT_LINEBREAK if (!dont_use_showbreak *************** *** 3545,3550 **** --- 3572,3578 ---- #ifdef FEAT_PROP_POPUP vim_free(text_props); vim_free(text_prop_idxs); + vim_free(p_extra_free2); #endif vim_free(p_extra_free); *** ../vim-9.0.0152/src/testdir/test_textprop.vim 2022-08-06 13:47:16.212982332 +0100 --- src/testdir/test_textprop.vim 2022-08-06 15:42:24.326934307 +0100 *************** *** 2443,2448 **** --- 2443,2451 ---- let buf = RunVimInTerminal('-S XscriptPropsAfterNowrap', #{rows: 8, cols: 60}) call VerifyScreenDump(buf, 'Test_prop_with_text_after_nowrap_1', {}) + call term_sendkeys(buf, ":set signcolumn=yes foldcolumn=3\") + call VerifyScreenDump(buf, 'Test_prop_with_text_after_nowrap_2', {}) + call StopVimInTerminal(buf) call delete('XscriptPropsAfterNowrap') endfunc *** ../vim-9.0.0152/src/testdir/dumps/Test_prop_with_text_after_nowrap_2.dump 2022-08-06 15:58:31.386940143 +0100 --- src/testdir/dumps/Test_prop_with_text_after_nowrap_2.dump 2022-08-06 15:44:15.283043203 +0100 *************** *** 0 **** --- 1,8 ---- + | +0#0000e05#a8a8a8255@4|o+0#0000000#ffffff0|n|e| @51 + | +0#0000e05#a8a8a8255@4| +0#ffffff16#e000002|B|e|l|o|w| |t|h|e| |l|i|n|e| | +0#0000000#ffffff0@38 + | +0#0000e05#a8a8a8255@4|t+0#0000000#ffffff0|w|o| @51 + | +0#0000e05#a8a8a8255@4|a+0#0000000#ffff4012|n|o|t|h|e|r| +0&#ffffff0@47 + | +0#0000e05#a8a8a8255@4|O+0#ffffff16#e000002|n|e| |M|o|r|e| |H|e|r|e| +0#0000000#ffffff0@41 + | +0#0000e05#a8a8a8255@4|t+0#0000000#ffffff0|h|r|e>e| @49 + |~+0#4040ff13&| @58 + | +0#0000000&@41|3|,|5| @10|A|l@1| *** ../vim-9.0.0152/src/version.c 2022-08-06 14:21:48.902455645 +0100 --- src/version.c 2022-08-06 15:44:08.071037507 +0100 *************** *** 737,738 **** --- 737,740 ---- { /* Add new patch number below this line */ + /**/ + 153, /**/ -- hundred-and-one symptoms of being an internet addict: 255. You work for a newspaper and your editor asks you to write an article about Internet addiction...in the "first person." /// 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 ///