From 5712911d6a4da6e41ca9cf0bd9d67c40e7d1001a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 22 Mar 2025 21:35:24 +0100 Subject: [PATCH 1/6] Fix `colorcolumn` when `linebreak` is on The color column used to change its position when `linebreak` is on and the window is resized. The expected behaviour for a color column would be that it is always on the same character no matter how often the line wraps. An own variable was introduced that tracks the amount of characters that were inserted due to the `linebreak` and/or the `breakindent` option. This is used to evaluate the position of the color column. There is still an issue that the end of the screen line gets highlighted for some reason. --- src/drawline.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/drawline.c b/src/drawline.c index 84a1d895ba..637c785cc9 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -128,6 +128,7 @@ typedef struct { long vcol_sbr; // virtual column after showbreak int need_showbreak; // overlong line, skipping first x chars int dont_use_showbreak; // do not use 'showbreak' + int lbr_padding; // inserted columns for linebreak #endif #ifdef FEAT_PROP_POPUP int text_prop_above_count; @@ -520,6 +521,8 @@ handle_breakindent(win_T *wp, winlinevars_T *wlv) wlv->c_final = NUL; wlv->n_extra = get_breakindent_win(wp, ml_get_buf(wp->w_buffer, wlv->lnum, FALSE)); + wlv->lbr_padding += get_breakindent_win(wp, + ml_get_buf(wp->w_buffer, wlv->lnum, FALSE)); if (wlv->row == wlv->startrow) { wlv->n_extra -= win_col_off2(wp); @@ -910,7 +913,7 @@ draw_screen_line(win_T *wp, winlinevars_T *wlv) // edge for 'cursorcolumn'. wlv->col -= wlv->boguscols; wlv->boguscols = 0; -# define VCOL_HLC (wlv->vcol - wlv->vcol_off_co - wlv->vcol_off_tp) +# define VCOL_HLC (wlv->vcol - wlv->vcol_off_co - wlv->vcol_off_tp - wlv->lbr_padding) # else # define VCOL_HLC (wlv->vcol - wlv->vcol_off_tp) # endif @@ -1273,7 +1276,7 @@ win_line( int is_concealing = FALSE; int did_wcol = FALSE; int old_boguscols = 0; -# define VCOL_HLC (wlv.vcol - wlv.vcol_off_co - wlv.vcol_off_tp) +# define VCOL_HLC (wlv.vcol - wlv.vcol_off_co - wlv.vcol_off_tp - wlv.lbr_padding) # define FIX_FOR_BOGUSCOLS \ { \ wlv.n_extra += wlv.vcol_off_co; \ @@ -3083,6 +3086,7 @@ win_line( cts.cts_has_prop_with_text = FALSE; # endif wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; + wlv.lbr_padding += win_lbr_chartabsize(&cts, NULL) - 1; clear_chartabsize_arg(&cts); if (on_last_col && c != TAB) From 1fa342978b2d4f0702291cd23f3e2f19c7848e91 Mon Sep 17 00:00:00 2001 From: Matthias Rader Date: Sun, 23 Mar 2025 10:49:12 +0100 Subject: [PATCH 2/6] Fix color column for leading tabs --- src/drawline.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/drawline.c b/src/drawline.c index 637c785cc9..98fc1229c9 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -3085,8 +3085,7 @@ win_line( // do not want virtual text counted here cts.cts_has_prop_with_text = FALSE; # endif - wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; - wlv.lbr_padding += win_lbr_chartabsize(&cts, NULL) - 1; + wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; clear_chartabsize_arg(&cts); if (on_last_col && c != TAB) @@ -3108,8 +3107,11 @@ win_line( wlv.c_extra = mb_off > 0 ? MB_FILLER_CHAR : ' '; wlv.c_final = NUL; # ifdef FEAT_PROP_POPUP - if (wlv.n_extra > 0 && c != TAB) - in_linebreak = TRUE; + if (wlv.n_extra > 0 && c != TAB) + { + in_linebreak = TRUE; + wlv.lbr_padding += win_lbr_chartabsize(&cts, NULL) - 1; + } # endif if (VIM_ISWHITE(c)) { From b291fcde08d4950dc928ebd38b4ab6d3b8efd5eb Mon Sep 17 00:00:00 2001 From: Matthias Rader Date: Sun, 23 Mar 2025 13:38:39 +0100 Subject: [PATCH 3/6] Fix `linebreak` + `colorcolumn` edge case When the color column was exactly on the character that is the last character before the break, the color column would be set incorrectly. This only leaves tests regarding `cursorcolumn` and `showbreak` failing. --- src/drawline.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/drawline.c b/src/drawline.c index 98fc1229c9..fb4b9fa509 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -147,6 +147,7 @@ typedef struct { // with win_attr if needed int n_attr_skip; // chars to skip before using extra_attr int c_extra; // extra chars, all the same + int is_extra; int c_final; // final char, mandatory if set int extra_for_textprop; // n_extra set for textprop int start_extra_for_textprop; // extra_for_textprop was just set @@ -3085,7 +3086,7 @@ win_line( // do not want virtual text counted here cts.cts_has_prop_with_text = FALSE; # endif - wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; + wlv.n_extra = win_lbr_chartabsize(&cts, NULL) - 1; clear_chartabsize_arg(&cts); if (on_last_col && c != TAB) @@ -3110,7 +3111,17 @@ win_line( if (wlv.n_extra > 0 && c != TAB) { in_linebreak = TRUE; - wlv.lbr_padding += win_lbr_chartabsize(&cts, NULL) - 1; + + // edge case: current col is colorcol + 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)); + } + + wlv.lbr_padding += win_lbr_chartabsize(&cts, NULL) - 1; + wlv.is_extra = 1; } # endif if (VIM_ISWHITE(c)) @@ -3997,7 +4008,7 @@ win_line( wlv.char_attr = hl_combine_attr(wlv.char_attr, HL_ATTR(HLF_CUC)); } - else if (wlv.draw_color_col && VCOL_HLC == *wlv.color_cols) + else if (wlv.draw_color_col && VCOL_HLC == *wlv.color_cols && !wlv.is_extra) { vcol_save_attr = wlv.char_attr; wlv.char_attr = hl_combine_attr(wlv.char_attr, HL_ATTR(HLF_MC)); @@ -4433,6 +4444,10 @@ win_line( #endif } + + if (wlv.n_extra == 0) + wlv.is_extra = 0; + } // for every character in the line #ifdef FEAT_PROP_POPUP vim_free(text_props); From 9d20f13472bd0e2daef6a6373c3e1c8ee0ee8f27 Mon Sep 17 00:00:00 2001 From: Matthias Rader Date: Sun, 8 Jun 2025 21:13:05 +0200 Subject: [PATCH 4/6] Fix showbreak and cursorcolumn This changes the behaviour of how the showbreak option is treated in combination with color column. Previously the color column could also be displayed on the "virtual text" of the showbreak text. As this is not what the color column is supposed to be, the color column now skips the showbreak columns and only displays in actual text or after the actual text. --- src/drawline.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/drawline.c b/src/drawline.c index fb4b9fa509..8fc5c69185 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -129,6 +129,7 @@ typedef struct { int need_showbreak; // overlong line, skipping first x chars int dont_use_showbreak; // do not use 'showbreak' int lbr_padding; // inserted columns for linebreak + int sbr_padding; #endif #ifdef FEAT_PROP_POPUP int text_prop_above_count; @@ -587,6 +588,7 @@ handle_showbreak_and_filler(win_T *wp, winlinevars_T *wlv) wlv->c_final = NUL; wlv->n_extra = (int)STRLEN(sbr); wlv->vcol_sbr = wlv->vcol + MB_CHARLEN(sbr); + wlv->sbr_padding += MB_CHARLEN(sbr); // Correct start of highlighted area for 'showbreak'. if (wlv->fromcol >= wlv->vcol && wlv->fromcol < wlv->vcol_sbr) @@ -920,7 +922,8 @@ draw_screen_line(win_T *wp, winlinevars_T *wlv) # endif if (wlv->draw_color_col) - wlv->draw_color_col = advance_color_col(VCOL_HLC, &wlv->color_cols); + wlv->draw_color_col = + advance_color_col(VCOL_HLC - wlv->sbr_padding, &wlv->color_cols); if (((wp->w_p_cuc && (int)wp->w_virtcol >= VCOL_HLC - wlv->eol_hl_off @@ -963,10 +966,11 @@ draw_screen_line(win_T *wp, winlinevars_T *wlv) if (wlv->line_attr != 0) attr = hl_combine_attr(attr, wlv->line_attr); # endif - if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol + if (wp->w_p_cuc && + VCOL_HLC == (long)wp->w_virtcol - wlv->lbr_padding && wlv->lnum != wp->w_cursor.lnum) attr = hl_combine_attr(attr, HL_ATTR(HLF_CUC)); - else if (wlv->draw_color_col && VCOL_HLC == *wlv->color_cols) + else if (wlv->draw_color_col && VCOL_HLC - wlv->sbr_padding == *wlv->color_cols) attr = hl_combine_attr(attr, HL_ATTR(HLF_MC)); ScreenAttrs[wlv->off] = attr; ScreenCols[wlv->off] = wlv->vcol; @@ -1343,7 +1347,8 @@ win_line( // Check for columns to display for 'colorcolumn'. wlv.color_cols = wp->w_p_cc_cols; if (wlv.color_cols != NULL) - wlv.draw_color_col = advance_color_col(VCOL_HLC, &wlv.color_cols); + wlv.draw_color_col = + advance_color_col(VCOL_HLC - wlv.sbr_padding, &wlv.color_cols); #endif #ifdef FEAT_TERMINAL @@ -3981,7 +3986,8 @@ win_line( #ifdef FEAT_SYN_HL // advance to the next 'colorcolumn' if (wlv.draw_color_col) - wlv.draw_color_col = advance_color_col(VCOL_HLC, &wlv.color_cols); + wlv.draw_color_col = + advance_color_col(VCOL_HLC - wlv.sbr_padding, &wlv.color_cols); // Highlight the cursor column if 'cursorcolumn' is set. But don't // highlight the cursor position itself. @@ -4001,14 +4007,14 @@ win_line( # endif ) { - if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol + if (wp->w_p_cuc && VCOL_HLC == (long)wp->w_virtcol - wlv.lbr_padding && 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 && !wlv.is_extra) + else if (wlv.draw_color_col && VCOL_HLC - wlv.sbr_padding == *wlv.color_cols && !wlv.is_extra) { vcol_save_attr = wlv.char_attr; wlv.char_attr = hl_combine_attr(wlv.char_attr, HL_ATTR(HLF_MC)); From 7537365198cf550a7bcca45cd8e2f5c7994c778f Mon Sep 17 00:00:00 2001 From: Matthias Rader Date: Mon, 9 Jun 2025 10:07:51 +0200 Subject: [PATCH 5/6] Change expected 'conceal' test results Two tests that use the `conceal`, `cursorcolumn`, `linebreak`, `showbreak` and `colorcolumn` feature failed, due to changes in how the color column is placed. Previously, the color column used to change its position based on the window width and did not respect the `showbreak` characters. As the highlighted character is now always consistent, regardless of the window's width, the test now reflects this changed behaviour. Signed-off-by: Matthias Rader --- src/testdir/dumps/Test_conceal_cuc_01.dump | 4 ++-- src/testdir/dumps/Test_conceal_cuc_02.dump | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/testdir/dumps/Test_conceal_cuc_01.dump b/src/testdir/dumps/Test_conceal_cuc_01.dump index bf4281999c..c2235458ff 100644 --- a/src/testdir/dumps/Test_conceal_cuc_01.dump +++ b/src/testdir/dumps/Test_conceal_cuc_01.dump @@ -1,8 +1,8 @@ |o+0&#ffffff0|n|e| |o|n|e| |o|n|e| @1|o|n|e| |o|n|e| |o|n|e| |o+0&#e0e0e08|n+0&#ffffff0|e| @11 -| +0#4040ff13&|>@2| |o+0#0000000&|n|e| |o+0&#ffd7d7255|n+0&#ffffff0|e| |o|n|e| |o|n|e| @19 +| +0#4040ff13&|>@2| |o+0#0000000&|n|e| |o|n|e| |o|n|e| |o+0&#ffd7d7255|n+0&#ffffff0|e| @19 |t|w|o| |t|w|o| |t|w|o| |t|w|o| |||h|i|d@1|e|n||| >h|e|r|e| |t|w|o| |t|w|o| @2 |t|h|r|e@1| @1|t|h|r|e@1| |t|h|r|e@1| |t|h|r|e@1| |t+0&#e0e0e08|h+0&#ffffff0|r|e@1| @9 -| +0#4040ff13&|>@2| |t+0#0000000&|h|r|e|e+0&#ffd7d7255| +0&#ffffff0|t|h|r|e@1| |t|h|r|e@1| |t|h|r|e@1| @11 +| +0#4040ff13&|>@2| |t+0#0000000&|h|r|e@1| |t|h|r|e|e+0&#ffd7d7255| +0&#ffffff0|t|h|r|e@1| |t|h|r|e@1| @11 |~+0#4040ff13&| @38 |~| @38 |~| @38 diff --git a/src/testdir/dumps/Test_conceal_cuc_02.dump b/src/testdir/dumps/Test_conceal_cuc_02.dump index 1b6662e985..427a8e28b7 100644 --- a/src/testdir/dumps/Test_conceal_cuc_02.dump +++ b/src/testdir/dumps/Test_conceal_cuc_02.dump @@ -1,8 +1,8 @@ |o+0&#ffffff0|n|e| |o|n|e| |o|n|e| @1|o|n|e| |o|n|e| |o|n|e| |o|n|e| @11 -| +0#4040ff13&|>@2| |o+0#0000000&|n|e| |o+0&#ffd7d7255|n+0&#ffffff0|e| |o|n|e| |o|n|e| @19 +| +0#4040ff13&|>@2| |o+0#0000000&|n|e| |o|n|e| |o|n|e| |o+0&#ffd7d7255|n+0&#ffffff0|e| @19 |t|w|o| |t|w|o| |t|w|o| |t|w|o| |||h|i|d@1|e|n||| |h|e|r|e| |t|w|o| |t|w>o| @2 |t|h|r|e@1| @1|t|h|r|e@1| |t|h|r|e@1| |t|h|r|e@1| |t|h|r|e@1| @9 -| +0#4040ff13&|>@2| |t+0#0000000&|h|r|e|e+0&#ffd7d7255| +0&#ffffff0|t|h|r|e@1| |t|h|r|e@1| |t|h|r|e@1| @11 +| +0#4040ff13&|>@2| |t+0#0000000&|h|r|e@1| |t|h|r|e|e+0&#ffd7d7255| +0&#ffffff0|t|h|r|e@1| |t|h|r|e@1| @11 |~+0#4040ff13&| @38 |~| @38 |~| @38 From 74763a77a98c91ba551287d7465845fd9689a52f Mon Sep 17 00:00:00 2001 From: Matthias Rader Date: Mon, 9 Jun 2025 17:29:02 +0200 Subject: [PATCH 6/6] Change expectation in color column test --- src/testdir/dumps/Test_colorcolumn_2.dump | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testdir/dumps/Test_colorcolumn_2.dump b/src/testdir/dumps/Test_colorcolumn_2.dump index 44e0e7a2da..44aa2296d1 100644 --- a/src/testdir/dumps/Test_colorcolumn_2.dump +++ b/src/testdir/dumps/Test_colorcolumn_2.dump @@ -1,5 +1,5 @@ ->T+0&#ffffff0|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|e|d| |o|v|e|r| |t|h|e| @3| +0&#ffd7d7255 -@1| +0&#ffffff0|l+0&#ffd7d7255|a+0&#ffffff0|z|y| |d|o|g|s| @28 +>T+0&#ffffff0|h|e| |q|u|i|c|k| |b|r|o|w|n| |f|o|x| |j|u|m|p|e|d| |o|v|e|r| |t|h|e| @4 +@2|l|a|z|y+0&#ffd7d7255| |d+0&#ffffff0|o+0&#ffd7d7255|g+0&#ffffff0|s| @28 |~+0#4040ff13&| @38 |~| @38 |~| @38