diff options
author | James McCoy <jamessan@jamessan.com> | 2021-12-05 15:36:54 -0500 |
---|---|---|
committer | James McCoy <jamessan@jamessan.com> | 2021-12-08 21:47:58 -0500 |
commit | e8f9262125535bea8c7fcf833a715b569e07996e (patch) | |
tree | ecbbd94671bac26098f270f016c6f02956047bfc | |
parent | 2cd815c0af3eded9771df94532b4fb3817f2d3c6 (diff) | |
download | rneovim-e8f9262125535bea8c7fcf833a715b569e07996e.tar.gz rneovim-e8f9262125535bea8c7fcf833a715b569e07996e.tar.bz2 rneovim-e8f9262125535bea8c7fcf833a715b569e07996e.zip |
vim-patch:8.2.3664: cannot adjust sign highlighting for 'cursorline'
Problem: Cannot adjust sign highlighting for 'cursorline'.
Solution: Add CursorLineSign and CursorLineFold highlight groups.
(Gregory Anders, closes vim/vim#9201)
https://github.com/vim/vim/commit/e413ea04b716effb28eb49dbc98ad3f9f761545a
-rw-r--r-- | runtime/doc/sign.txt | 18 | ||||
-rw-r--r-- | runtime/doc/syntax.txt | 4 | ||||
-rw-r--r-- | src/nvim/highlight_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/option.c | 1 | ||||
-rw-r--r-- | src/nvim/screen.c | 41 | ||||
-rw-r--r-- | src/nvim/sign.c | 39 | ||||
-rw-r--r-- | src/nvim/sign_defs.h | 1 | ||||
-rw-r--r-- | src/nvim/syntax.c | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_signs.vim | 16 | ||||
-rw-r--r-- | test/functional/ui/cursor_spec.lua | 4 |
10 files changed, 107 insertions, 23 deletions
diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt index 895ee5ebef..641e193b5e 100644 --- a/runtime/doc/sign.txt +++ b/runtime/doc/sign.txt @@ -47,6 +47,8 @@ The color of the column is set with the SignColumn highlight group :highlight SignColumn guibg=darkgrey < +If 'cursorline' is enabled, then the CursorLineSign highlight group is used +|hl-CursorLineSign|. *sign-identifier* Each placed sign is identified by a number called the sign identifier. This identifier is used to jump to the sign or to remove the sign. The identifier @@ -156,6 +158,13 @@ See |sign_getdefined()| for the equivalent Vim script function. :sign list {name} Lists one defined sign and its attributes. + culhl={group} + Highlighting group used for the text item when the cursor is + on the same line as the sign and 'cursorline' is enabled. + + Example: > + :sign define MySign text=>> texthl=Search linehl=DiffText +< PLACING SIGNS *:sign-place* *E158* @@ -377,6 +386,9 @@ sign_define({list}) text text that is displayed when there is no icon or the GUI is not being used. texthl highlight group used for the text item + culhl highlight group used for the text item when + the cursor is on the same line as the sign and + 'cursorline' is enabled. numhl highlight group used for 'number' column at the associated line. Overrides |hl-LineNr|, |hl-CursorLineNr|. @@ -425,9 +437,13 @@ sign_getdefined([{name}]) *sign_getdefined()* or the GUI is not being used. texthl highlight group used for the text item; not present if not set. + culhl highlight group used for the text item when + the cursor is on the same line as the sign and + 'cursorline' is enabled; not present if not + set. numhl highlight group used for 'number' column at the associated line. Overrides |hl-LineNr|, - |hl-CursorLineNr|. + |hl-CursorLineNr|; not present if not set. Returns an empty List if there are no signs and when {name} is not found. diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index b57b8bfd5c..d49809599d 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -5127,6 +5127,10 @@ LineNrBelow Line number for when the 'relativenumber' *hl-CursorLineNr* CursorLineNr Like LineNr when 'cursorline' is set and 'cursorlineopt' contains "number" or is "both", for the cursor line. + *hl-CursorLineSign* +CursorLineSign Like SignColumn when 'cursorline' is set for the cursor line. + *hl-CursorLineFold* +CursorLineFold Like FoldColumn when 'cursorline' is set for the cursor line. *hl-MatchParen* MatchParen The character under the cursor or just before it, if it is a paired bracket, and its match. |pi_paren.txt| diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h index d4d53c4126..50a03e0c02 100644 --- a/src/nvim/highlight_defs.h +++ b/src/nvim/highlight_defs.h @@ -65,6 +65,8 @@ typedef enum { HLF_LNA, // LineNrAbove HLF_LNB, // LineNrBelow HLF_CLN, // current line number when 'cursorline' is set + HLF_CLS, // current line sign column + HLF_CLF, // current line fold HLF_R, // return to continue message and yes/no questions HLF_S, // status lines HLF_SNC, // status lines of not-current windows @@ -122,6 +124,8 @@ EXTERN const char *hlf_names[] INIT(= { [HLF_LNA] = "LineNrAbove", [HLF_LNB] = "LineNrBelow", [HLF_CLN] = "CursorLineNr", + [HLF_CLS] = "CursorLineSign", + [HLF_CLF] = "CursorLineFold", [HLF_R] = "Question", [HLF_S] = "StatusLine", [HLF_SNC] = "StatusLineNC", diff --git a/src/nvim/option.c b/src/nvim/option.c index 1fe2e1d04c..92c27378ee 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -262,6 +262,7 @@ typedef struct vimoption { #define HIGHLIGHT_INIT \ "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \ "i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr," \ + "G:CursorLineSign,O:CursorLineFold" \ "r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg," \ "W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn," \ "-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar," \ diff --git a/src/nvim/screen.c b/src/nvim/screen.c index a666b9c8b0..6d3142451f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2746,7 +2746,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc p_extra = p_extra_free; c_extra = NUL; c_final = NUL; - char_attr = win_hl_attr(wp, HLF_FC); + if (use_cursor_line_sign(wp, lnum)) { + char_attr = win_hl_attr(wp, HLF_CLF); + } else { + char_attr = win_hl_attr(wp, HLF_FC); + } } } @@ -2757,7 +2761,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc * buffer or when using Netbeans. */ int count = win_signcol_count(wp); if (count > 0) { - get_sign_display_info(false, wp, sattrs, row, + get_sign_display_info(false, wp, lnum, sattrs, row, startrow, filler_lines, filler_todo, count, &c_extra, &c_final, extra, sizeof(extra), &p_extra, &n_extra, @@ -2778,7 +2782,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u' && num_signs > 0) { int count = win_signcol_count(wp); - get_sign_display_info(true, wp, sattrs, row, + get_sign_display_info(true, wp, lnum, sattrs, row, startrow, filler_lines, filler_todo, count, &c_extra, &c_final, extra, sizeof(extra), &p_extra, &n_extra, @@ -4617,6 +4621,14 @@ void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off) } } +// Return true if CursorLineSign highlight is to be used. +static bool use_cursor_line_sign(win_T *wp, linenr_T lnum) +{ + return wp->w_p_cul + && lnum == wp->w_cursor.lnum + && (wp->w_p_culopt_flags & CULOPT_NBR); +} + // Get information needed to display the sign in line 'lnum' in window 'wp'. // If 'nrcol' is TRUE, the sign is going to be displayed in the number column. // Otherwise the sign is going to be displayed in the sign column. @@ -4624,11 +4636,11 @@ void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off) // @param count max number of signs // @param[out] n_extrap number of characters from pp_extra to display // @param[in, out] sign_idxp Index of the displayed sign -static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[], int row, - int startrow, int filler_lines, int filler_todo, int count, - int *c_extrap, int *c_finalp, char_u *extra, size_t extra_size, - char_u **pp_extra, int *n_extrap, int *char_attrp, - int *draw_statep, int *sign_idxp) +static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, sign_attrs_T sattrs[], + int row, int startrow, int filler_lines, int filler_todo, + int count, int *c_extrap, int *c_finalp, char_u *extra, + size_t extra_size, char_u **pp_extra, int *n_extrap, + int *char_attrp, int *draw_statep, int *sign_idxp) { // Draw cells with the sign value or blank. *c_extrap = ' '; @@ -4636,7 +4648,11 @@ static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[], if (nrcol) { *n_extrap = number_width(wp) + 1; } else { - *char_attrp = win_hl_attr(wp, HLF_SC); + if (use_cursor_line_sign(wp, lnum)) { + *char_attrp = win_hl_attr(wp, HLF_CLS); + } else { + *char_attrp = win_hl_attr(wp, HLF_SC); + } *n_extrap = win_signcol_width(wp); } @@ -4676,7 +4692,12 @@ static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[], (*pp_extra)[*n_extrap] = NUL; } } - *char_attrp = sattr->sat_texthl; + + if (use_cursor_line_sign(wp, lnum) && sattr->sat_culhl > 0) { + *char_attrp = sattr->sat_culhl; + } else { + *char_attrp = sattr->sat_texthl; + } } } diff --git a/src/nvim/sign.c b/src/nvim/sign.c index fca73dc9f2..d2faac2b94 100644 --- a/src/nvim/sign.c +++ b/src/nvim/sign.c @@ -31,6 +31,7 @@ struct sign { char_u *sn_text; // text used instead of pixmap int sn_line_hl; // highlight ID for line int sn_text_hl; // highlight ID for text + int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set int sn_num_hl; // highlight ID for line number }; @@ -499,6 +500,9 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[]) if (sp->sn_line_hl != 0) { sattr.sat_linehl = syn_id2attr(sp->sn_line_hl); } + if (sp->sn_cul_hl != 0) { + sattr.sat_culhl = syn_id2attr(sp->sn_cul_hl); + } if (sp->sn_num_hl != 0) { sattr.sat_numhl = syn_id2attr(sp->sn_num_hl); } @@ -901,7 +905,7 @@ static int sign_define_init_text(sign_T *sp, char_u *text) /// Define a new sign or update an existing sign int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, - char *numhl) + char_u *culhl, char *numhl) { sign_T *sp_prev; sign_T *sp; @@ -946,6 +950,10 @@ int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text sp->sn_text_hl = syn_check_group((char *)texthl, (int)STRLEN(texthl)); } + if (culhl != NULL) { + sp->sn_cul_hl = syn_check_group((char *)culhl, (int)STRLEN(culhl)); + } + if (numhl != NULL) { sp->sn_num_hl = syn_check_group(numhl, (int)STRLEN(numhl)); } @@ -1133,6 +1141,7 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) char_u *text = NULL; char_u *linehl = NULL; char_u *texthl = NULL; + char_u *culhl = NULL; char_u *numhl = NULL; int failed = false; @@ -1155,6 +1164,9 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) } else if (STRNCMP(arg, "texthl=", 7) == 0) { arg += 7; texthl = vim_strnsave(arg, (size_t)(p - arg)); + } else if (STRNCMP(arg, "culhl=", 6) == 0) { + arg += 6; + culhl = vim_strnsave(arg, (size_t)(p - arg)); } else if (STRNCMP(arg, "numhl=", 6) == 0) { arg += 6; numhl = vim_strnsave(arg, (size_t)(p - arg)); @@ -1166,13 +1178,14 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline) } if (!failed) { - sign_define_by_name(sign_name, icon, linehl, text, texthl, (char *)numhl); + sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, (char *)numhl); } xfree(icon); xfree(text); xfree(linehl); xfree(texthl); + xfree(culhl); xfree(numhl); } @@ -1481,6 +1494,13 @@ static void sign_getinfo(sign_T *sp, dict_T *retdict) } tv_dict_add_str(retdict, S_LEN("texthl"), (char *)p); } + if (sp->sn_cul_hl > 0) { + p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, false); + if (p == NULL) { + p = "NONE"; + } + tv_dict_add_str(retdict, S_LEN("culhl"), (char *)p); + } if (sp->sn_num_hl > 0) { p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, false); if (p == NULL) { @@ -1609,6 +1629,16 @@ static void sign_list_defined(sign_T *sp) msg_puts(p); } } + if (sp->sn_cul_hl > 0) { + msg_puts(" culhl="); + const char *const p = get_highlight_name_ext(NULL, + sp->sn_cul_hl - 1, false); + if (p == NULL) { + msg_puts("NONE"); + } else { + msg_puts(p); + } + } if (sp->sn_num_hl > 0) { msg_puts(" numhl="); const char *const p = get_highlight_name_ext(NULL, @@ -1847,6 +1877,7 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict) char *linehl = NULL; char *text = NULL; char *texthl = NULL; + char *culhl = NULL; char *numhl = NULL; int retval = -1; @@ -1866,11 +1897,12 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict) linehl = tv_dict_get_string(dict, "linehl", true); text = tv_dict_get_string(dict, "text", true); texthl = tv_dict_get_string(dict, "texthl", true); + culhl = tv_dict_get_string(dict, "culhl", true); numhl = tv_dict_get_string(dict, "numhl", true); } if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl, - (char_u *)text, (char_u *)texthl, numhl) + (char_u *)text, (char_u *)texthl, (char_u *)culhl, numhl) == OK) { retval = 0; } @@ -1881,6 +1913,7 @@ cleanup: xfree(linehl); xfree(text); xfree(texthl); + xfree(culhl); xfree(numhl); return retval; diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 46436b2c8e..c734502878 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -38,6 +38,7 @@ typedef struct sign_attrs_S { char_u *sat_text; int sat_texthl; int sat_linehl; + int sat_culhl; int sat_numhl; } sign_attrs_T; diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index cb243668ce..7eb33d8fdc 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6175,6 +6175,8 @@ static const char *highlight_init_both[] = { "default link LineNrAbove LineNr", "default link LineNrBelow LineNr", "default link QuickFixLine Search", + "default link CursorLineSign SignColumn", + "default link CursorLineFold FoldColumn", "default link Substitute Search", "default link Whitespace NonText", "default link MsgSeparator StatusLine", diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim index f287256396..35c80b375a 100644 --- a/src/nvim/testdir/test_signs.vim +++ b/src/nvim/testdir/test_signs.vim @@ -15,13 +15,13 @@ func Test_sign() " the icon name when listing signs. sign define Sign1 text=x - call Sign_command_ignore_error('sign define Sign2 text=xy texthl=Title linehl=Error icon=../../pixmaps/stock_vim_find_help.png') + call Sign_command_ignore_error('sign define Sign2 text=xy texthl=Title linehl=Error culhl=Search icon=../../pixmaps/stock_vim_find_help.png') " Test listing signs. let a=execute('sign list') call assert_match('^\nsign Sign1 text=x \nsign Sign2 ' . \ 'icon=../../pixmaps/stock_vim_find_help.png .*text=xy ' . - \ 'linehl=Error texthl=Title$', a) + \ 'linehl=Error texthl=Title culhl=Search$', a) let a=execute('sign list Sign1') call assert_equal("\nsign Sign1 text=x ", a) @@ -392,19 +392,21 @@ func Test_sign_funcs() call sign_undefine() " Tests for sign_define() - let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error'} + let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error', + \ 'culhl': 'Visual'} call assert_equal(0, "sign1"->sign_define(attr)) call assert_equal([{'name' : 'sign1', 'texthl' : 'Error', - \ 'linehl' : 'Search', 'text' : '=>'}], sign_getdefined()) + \ 'linehl' : 'Search', 'culhl': 'Visual', 'text' : '=>'}], + \ sign_getdefined()) " Define a new sign without attributes and then update it call sign_define("sign2") let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange', - \ 'icon' : 'sign2.ico'} + \ 'culhl': 'DiffDelete', 'icon' : 'sign2.ico'} call Sign_define_ignore_error("sign2", attr) call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange', - \ 'linehl' : 'DiffAdd', 'text' : '!!', 'icon' : 'sign2.ico'}], - \ "sign2"->sign_getdefined()) + \ 'linehl' : 'DiffAdd', 'culhl' : 'DiffDelete', 'text' : '!!', + \ 'icon' : 'sign2.ico'}], "sign2"->sign_getdefined()) " Test for a sign name with digits call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'})) diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua index 9c035c728b..03cd4bfd06 100644 --- a/test/functional/ui/cursor_spec.lua +++ b/test/functional/ui/cursor_spec.lua @@ -212,10 +212,10 @@ describe('ui/cursor', function() if m.blinkwait then m.blinkwait = 700 end end if m.hl_id then - m.hl_id = 58 + m.hl_id = 60 m.attr = {background = Screen.colors.DarkGray} end - if m.id_lm then m.id_lm = 59 end + if m.id_lm then m.id_lm = 61 end end -- Assert the new expectation. |