To: vim_dev@googlegroups.com Subject: Patch 8.2.3874 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3874 Problem: Cannot highlight the number column for a sign. Solution: Add the "numhl" argument. (James McCoy, closes #9381) Files: runtime/doc/options.txt, runtime/doc/sign.txt, src/drawline.c, src/popupwin.c, src/proto/sign.pro, src/sign.c, src/structs.h, src/testdir/test_signs.vim *** ../vim-8.2.3873/runtime/doc/options.txt 2021-12-21 09:11:45.625393271 +0000 --- runtime/doc/options.txt 2021-12-22 19:38:40.671087595 +0000 *************** *** 5601,5608 **** number. When a long, wrapped line doesn't start with the first character, '-' characters are put before the number. ! See |hl-LineNr| and |hl-CursorLineNr| for the highlighting used for ! the number. *number_relativenumber* The 'relativenumber' option changes the displayed number to be relative to the cursor. Together with 'number' there are these --- 5601,5608 ---- number. When a long, wrapped line doesn't start with the first character, '-' characters are put before the number. ! For highlighting see |hl-LineNr|, and |hl-CursorLineNr|, and the ! |:sign-define| "numhl" argument. *number_relativenumber* The 'relativenumber' option changes the displayed number to be relative to the cursor. Together with 'number' there are these *** ../vim-8.2.3873/runtime/doc/sign.txt 2021-11-24 16:19:41.385010087 +0000 --- runtime/doc/sign.txt 2021-12-22 19:38:40.671087595 +0000 *************** *** 140,145 **** --- 140,150 ---- Highlighting group used for the whole line the sign is placed in. Most useful is defining a background color. + numhl={group} + Highlighting group used for the line number on the line where + the sign is placed. Overrides |hl-LineNr|, |hl-LineNrAbove|, + |hl-LineNrBelow|, and |hl-CursorLineNr|. + text={text} *E239* Define the text that is displayed when there is no icon or the GUI is not being used. Only printable characters are allowed *************** *** 383,388 **** --- 401,408 ---- icon full path to the bitmap file for the sign. linehl highlight group used for the whole line the sign is placed in. + numhl highlight group used for the line number where + the sign is placed. 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 *************** *** 428,441 **** following entries: icon full path to the bitmap file of the sign linehl highlight group used for the whole line the ! sign is placed in. name name of the sign 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. Returns an empty List if there are no signs and when {name} is not found. --- 448,465 ---- following entries: icon full path to the bitmap file of the sign linehl highlight group used for the whole line the ! sign is placed in; not present if not set name name of the sign + numhl highlight group used for the line number where + the sign is placed; not present if not set 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; 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 Returns an empty List if there are no signs and when {name} is not found. *** ../vim-8.2.3873/src/drawline.c 2021-12-02 19:46:38.798969031 +0000 --- src/drawline.c 2021-12-22 19:38:40.671087595 +0000 *************** *** 377,382 **** --- 377,383 ---- #ifdef FEAT_SIGNS int sign_present = FALSE; sign_attrs_T sattr; + int num_attr = 0; // attribute for the number column #endif #ifdef FEAT_ARABIC int prev_c = 0; // previous Arabic character *************** *** 699,704 **** --- 700,707 ---- #ifdef FEAT_SIGNS sign_present = buf_get_signattrs(wp, lnum, &sattr); + if (sign_present) + num_attr = sattr.sat_numhl; #endif #ifdef LINE_ATTR *************** *** 1206,1211 **** --- 1209,1218 ---- char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_LNB)); } + #ifdef FEAT_SIGNS + if (num_attr) + char_attr = num_attr; + #endif } } *** ../vim-8.2.3873/src/popupwin.c 2021-12-09 10:50:48.566865615 +0000 --- src/popupwin.c 2021-12-22 19:38:40.671087595 +0000 *************** *** 632,638 **** if (syn_name2id((char_u *)linehl) == 0) linehl = "PmenuSel"; ! sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL); } sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name, --- 632,638 ---- if (syn_name2id((char_u *)linehl) == 0) linehl = "PmenuSel"; ! sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL, NULL); } sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name, *** ../vim-8.2.3873/src/proto/sign.pro 2021-11-24 16:19:41.389010087 +0000 --- src/proto/sign.pro 2021-12-22 19:38:40.671087595 +0000 *************** *** 8,14 **** int buf_signcount(buf_T *buf, linenr_T lnum); void buf_delete_signs(buf_T *buf, char_u *group); void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); ! int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl); int sign_exists_by_name(char_u *name); int sign_undefine_by_name(char_u *name, int give_error); int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); --- 8,14 ---- int buf_signcount(buf_T *buf, linenr_T lnum); void buf_delete_signs(buf_T *buf, char_u *group); void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after); ! int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl, char_u *culhl, char_u *numhl); int sign_exists_by_name(char_u *name); int sign_undefine_by_name(char_u *name, int give_error); int sign_place(int *sign_id, char_u *sign_group, char_u *sign_name, buf_T *buf, linenr_T lnum, int prio); *** ../vim-8.2.3873/src/sign.c 2021-12-05 19:09:59.799706687 +0000 --- src/sign.c 2021-12-22 19:38:40.671087595 +0000 *************** *** 33,38 **** --- 33,39 ---- 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 }; static sign_T *first_sign = NULL; *************** *** 520,525 **** --- 521,528 ---- 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); sattr->sat_priority = sign->se_priority; // If there is another sign next with the same priority, may *************** *** 545,550 **** --- 548,555 ---- sattr->sat_linehl = syn_id2attr(next_sp->sn_line_hl); if (sp->sn_cul_hl <= 0 && next_sp->sn_cul_hl > 0) sattr->sat_culhl = syn_id2attr(next_sp->sn_cul_hl); + if (sp->sn_num_hl <= 0 && next_sp->sn_num_hl > 0) + sattr->sat_numhl = syn_id2attr(next_sp->sn_num_hl); } } return TRUE; *************** *** 1041,1047 **** char_u *linehl, char_u *text, char_u *texthl, ! char_u *culhl) { sign_T *sp_prev; sign_T *sp; --- 1046,1053 ---- char_u *linehl, char_u *text, char_u *texthl, ! char_u *culhl, ! char_u *numhl) { sign_T *sp_prev; sign_T *sp; *************** *** 1101,1106 **** --- 1107,1120 ---- sp->sn_cul_hl = syn_check_group(culhl, (int)STRLEN(culhl)); } + if (numhl != NULL) + { + if (*numhl == NUL) + sp->sn_num_hl = 0; + else + sp->sn_num_hl = syn_check_group(numhl, (int)STRLEN(numhl)); + } + return OK; } *************** *** 1323,1328 **** --- 1337,1343 ---- char_u *linehl = NULL; char_u *texthl = NULL; char_u *culhl = NULL; + char_u *numhl = NULL; int failed = FALSE; // set values for a defined sign. *************** *** 1357,1362 **** --- 1372,1382 ---- arg += 6; culhl = vim_strnsave(arg, p - arg); } + else if (STRNCMP(arg, "numhl=", 6) == 0) + { + arg += 6; + numhl = vim_strnsave(arg, p - arg); + } else { semsg(_(e_invarg2), arg); *************** *** 1366,1378 **** } if (!failed) ! sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl); vim_free(icon); vim_free(text); vim_free(linehl); vim_free(texthl); vim_free(culhl); } /* --- 1386,1399 ---- } if (!failed) ! sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, numhl); vim_free(icon); vim_free(text); vim_free(linehl); vim_free(texthl); vim_free(culhl); + vim_free(numhl); } /* *************** *** 1750,1755 **** --- 1771,1783 ---- p = (char_u *)"NONE"; dict_add_string(retdict, "culhl", (char_u *)p); } + if (sp->sn_num_hl > 0) + { + p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); + if (p == NULL) + p = (char_u *)"NONE"; + dict_add_string(retdict, "numhl", (char_u *)p); + } } /* *************** *** 1930,1935 **** --- 1958,1972 ---- else msg_puts((char *)p); } + if (sp->sn_num_hl > 0) + { + msg_puts(" numhl="); + p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, FALSE); + if (p == NULL) + msg_puts("NONE"); + else + msg_puts((char *)p); + } } /* *************** *** 2051,2057 **** { char *define_arg[] = { ! "icon=", "linehl=", "text=", "texthl=", NULL }; return (char_u *)define_arg[idx]; } --- 2088,2094 ---- { char *define_arg[] = { ! "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL }; return (char_u *)define_arg[idx]; } *************** *** 2176,2182 **** { case SIGNCMD_DEFINE: if (STRNCMP(last, "texthl", 6) == 0 ! || STRNCMP(last, "linehl", 6) == 0) xp->xp_context = EXPAND_HIGHLIGHT; else if (STRNCMP(last, "icon", 4) == 0) xp->xp_context = EXPAND_FILES; --- 2213,2221 ---- { case SIGNCMD_DEFINE: if (STRNCMP(last, "texthl", 6) == 0 ! || STRNCMP(last, "linehl", 6) == 0 ! || STRNCMP(last, "culhl", 5) == 0 ! || STRNCMP(last, "numhl", 5) == 0) xp->xp_context = EXPAND_HIGHLIGHT; else if (STRNCMP(last, "icon", 4) == 0) xp->xp_context = EXPAND_FILES; *************** *** 2221,2226 **** --- 2260,2266 ---- char_u *text = NULL; char_u *texthl = NULL; char_u *culhl = NULL; + char_u *numhl = NULL; int retval = -1; if (name_arg == NULL) *************** *** 2240,2248 **** text = dict_get_string(dict, (char_u *)"text", TRUE); texthl = dict_get_string(dict, (char_u *)"texthl", TRUE); culhl = dict_get_string(dict, (char_u *)"culhl", TRUE); } ! if (sign_define_by_name(name, icon, linehl, text, texthl, culhl) == OK) retval = 0; cleanup: --- 2280,2289 ---- text = dict_get_string(dict, (char_u *)"text", TRUE); texthl = dict_get_string(dict, (char_u *)"texthl", TRUE); culhl = dict_get_string(dict, (char_u *)"culhl", TRUE); + numhl = dict_get_string(dict, (char_u *)"numhl", TRUE); } ! if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK) retval = 0; cleanup: *************** *** 2252,2257 **** --- 2293,2299 ---- vim_free(text); vim_free(texthl); vim_free(culhl); + vim_free(numhl); return retval; } *** ../vim-8.2.3873/src/structs.h 2021-12-22 18:19:22.602372473 +0000 --- src/structs.h 2021-12-22 19:38:40.671087595 +0000 *************** *** 854,859 **** --- 854,860 ---- int sat_texthl; int sat_linehl; int sat_culhl; + int sat_numhl; int sat_priority; } sign_attrs_T; *** ../vim-8.2.3873/src/testdir/test_signs.vim 2021-12-05 19:09:59.799706687 +0000 --- src/testdir/test_signs.vim 2021-12-22 19:38:40.671087595 +0000 *************** *** 15,27 **** " 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 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 culhl=Search$', a) let a=execute('sign list Sign1') call assert_equal("\nsign Sign1 text=x ", a) --- 15,27 ---- " 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 culhl=Search numhl=Number 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 culhl=Search numhl=Number$', a) let a=execute('sign list Sign1') call assert_equal("\nsign Sign1 text=x ", a) *************** *** 127,152 **** call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:') " an empty highlight argument for an existing sign clears it ! sign define SignY texthl=TextHl culhl=CulHl linehl=LineHl let sl = sign_getdefined('SignY')[0] call assert_equal('TextHl', sl.texthl) call assert_equal('CulHl', sl.culhl) call assert_equal('LineHl', sl.linehl) ! sign define SignY texthl= culhl=CulHl linehl=LineHl let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'texthl')) call assert_equal('CulHl', sl.culhl) call assert_equal('LineHl', sl.linehl) sign define SignY linehl= let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'linehl')) call assert_equal('CulHl', sl.culhl) sign define SignY culhl= let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'culhl')) sign undefine SignY --- 127,160 ---- call assert_fails("sign define Sign4 text=\\ ab linehl=Comment", 'E239:') " an empty highlight argument for an existing sign clears it ! sign define SignY texthl=TextHl culhl=CulHl linehl=LineHl numhl=NumHl let sl = sign_getdefined('SignY')[0] call assert_equal('TextHl', sl.texthl) call assert_equal('CulHl', sl.culhl) call assert_equal('LineHl', sl.linehl) + call assert_equal('NumHl', sl.numhl) ! sign define SignY texthl= culhl=CulHl linehl=LineHl numhl=NumHl let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'texthl')) call assert_equal('CulHl', sl.culhl) call assert_equal('LineHl', sl.linehl) + call assert_equal('NumHl', sl.numhl) sign define SignY linehl= let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'linehl')) call assert_equal('CulHl', sl.culhl) + call assert_equal('NumHl', sl.numhl) sign define SignY culhl= let sl = sign_getdefined('SignY')[0] call assert_false(has_key(sl, 'culhl')) + call assert_equal('NumHl', sl.numhl) + + sign define SignY numhl= + let sl = sign_getdefined('SignY')[0] + call assert_false(has_key(sl, 'numhl')) sign undefine SignY *************** *** 218,232 **** call assert_equal('"sign define jump list place undefine unplace', @:) call feedkeys(":sign define Sign \\\"\", 'tx') ! call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:) ! call feedkeys(":sign define Sign linehl=Spell\\\"\", 'tx') ! call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' . ! \ 'SpellLocal SpellRare', @:) ! ! call feedkeys(":sign define Sign texthl=Spell\\\"\", 'tx') ! call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' . ! \ 'SpellLocal SpellRare', @:) call writefile(repeat(["Sun is shining"], 30), "XsignOne") call writefile(repeat(["Sky is blue"], 30), "XsignTwo") --- 226,238 ---- call assert_equal('"sign define jump list place undefine unplace', @:) call feedkeys(":sign define Sign \\\"\", 'tx') ! call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:) ! for hl in ['culhl', 'linehl', 'numhl', 'texthl'] ! call feedkeys(":sign define Sign "..hl.."=Spell\\\"\", 'tx') ! call assert_equal('"sign define Sign '..hl..'=SpellBad SpellCap ' . ! \ 'SpellLocal SpellRare', @:) ! endfor call writefile(repeat(["Sun is shining"], 30), "XsignOne") call writefile(repeat(["Sky is blue"], 30), "XsignTwo") *************** *** 417,436 **** " Tests for sign_define() 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', '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', ! \ 'culhl': 'DiffDelete', 'icon' : 'sign2.ico'} call Sign_define_ignore_error("sign2", attr) call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange', \ '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'})) --- 423,443 ---- " Tests for sign_define() let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error', ! \ 'culhl': 'Visual', 'numhl': 'Number'} call assert_equal(0, "sign1"->sign_define(attr)) ! call assert_equal([{'name' : 'sign1', 'texthl' : 'Error', 'linehl' : 'Search', ! \ 'culhl' : 'Visual', 'numhl': 'Number', 'text' : '=>'}], \ sign_getdefined()) " Define a new sign without attributes and then update it call sign_define("sign2") let attr = {'text' : '!!', 'linehl' : 'DiffAdd', 'texthl' : 'DiffChange', ! \ 'culhl': 'DiffDelete', 'numhl': 'Number', 'icon' : 'sign2.ico'} call Sign_define_ignore_error("sign2", attr) call assert_equal([{'name' : 'sign2', 'texthl' : 'DiffChange', \ 'linehl' : 'DiffAdd', 'culhl' : 'DiffDelete', 'text' : '!!', ! \ 'numhl': 'Number', 'icon' : 'sign2.ico'}], ! \ "sign2"->sign_getdefined()) " Test for a sign name with digits call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'})) *** ../vim-8.2.3873/src/version.c 2021-12-22 19:19:04.776883141 +0000 --- src/version.c 2021-12-22 19:41:57.474806284 +0000 *************** *** 751,752 **** --- 751,754 ---- { /* Add new patch number below this line */ + /**/ + 3874, /**/ -- From "know your smileys": :-X My lips are sealed /// 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 ///