]> granicus.if.org Git - vim/commitdiff
patch 8.2.3874: cannot highlight the number column for a sign v8.2.3874
authorJames McCoy <jamessan@jamessan.com>
Wed, 22 Dec 2021 19:45:28 +0000 (19:45 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 22 Dec 2021 19:45:28 +0000 (19:45 +0000)
Problem:    Cannot highlight the number column for a sign.
Solution:   Add the "numhl" argument. (James McCoy, closes #9381)

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
src/version.c

index 3e71ba14e50092b796344f9d3dd9ca4449a9ec07..b4e7761659c21d08dbf80a7db762771962843f59 100644 (file)
@@ -5601,8 +5601,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        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.
+       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
index 7976cecca839cf8a4da2d9bb3a01fb2a350a93f7..125e59215864cc5e2b4ca6865ce809ca5d2b3c4e 100644 (file)
@@ -140,6 +140,11 @@ See |sign_define()| for the equivalent Vim script function.
                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
@@ -396,6 +401,8 @@ sign_define({list})
                   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
@@ -443,6 +450,8 @@ sign_getdefined([{name}])                           *sign_getdefined()*
                   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
index 3106196e9de46370f2129d39ca55c59829c18474..7125b800f69cd9a13b17972ebefb2eb994df52e9 100644 (file)
@@ -377,6 +377,7 @@ win_line(
 #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,6 +700,8 @@ win_line(
 
 #ifdef FEAT_SIGNS
     sign_present = buf_get_signattrs(wp, lnum, &sattr);
+    if (sign_present)
+       num_attr = sattr.sat_numhl;
 #endif
 
 #ifdef LINE_ATTR
@@ -1206,6 +1209,10 @@ win_line(
                          char_attr = hl_combine_attr(wcr_attr,
                                                             HL_ATTR(HLF_LNB));
                    }
+#ifdef FEAT_SIGNS
+                   if (num_attr)
+                       char_attr = num_attr;
+#endif
                }
            }
 
index 266e1134858805ef611c62b79403622d5270fa9f..7b742617880b69f7bc590c367540decfdbe0c6ca 100644 (file)
@@ -632,7 +632,7 @@ popup_highlight_curline(win_T *wp)
 
            if (syn_name2id((char_u *)linehl) == 0)
                linehl = "PmenuSel";
-           sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL);
+           sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL, NULL);
        }
 
        sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
index 4e8abb3845a1484f47cc9f69ac9f49be9855e870..a042bad7f19096cab79124d753d37c1619a0b9e7 100644 (file)
@@ -8,7 +8,7 @@ int buf_findsigntype_id(buf_T *buf, linenr_T lnum, int typenr);
 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_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);
index e358ee97527122bfc2df32ad6bfd43edee595400..50210d092da0e0c005b00c463a0833e062ecf601 100644 (file)
@@ -33,6 +33,7 @@ struct sign
     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,6 +521,8 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr)
                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,6 +548,8 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr)
                        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,7 +1046,8 @@ sign_define_by_name(
        char_u  *linehl,
        char_u  *text,
        char_u  *texthl,
-       char_u  *culhl)
+       char_u  *culhl,
+       char_u  *numhl)
 {
     sign_T     *sp_prev;
     sign_T     *sp;
@@ -1101,6 +1107,14 @@ sign_define_by_name(
            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,6 +1337,7 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
     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,6 +1372,11 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
            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,13 +1386,14 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
     }
 
     if (!failed)
-       sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl);
+       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,6 +1771,13 @@ sign_getinfo(sign_T *sp, dict_T *retdict)
            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,6 +1958,15 @@ sign_list_defined(sign_T *sp)
        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,7 +2088,7 @@ get_sign_name(expand_T *xp UNUSED, int idx)
        {
            char *define_arg[] =
            {
-               "icon=", "linehl=", "text=", "texthl=", NULL
+               "culhl=", "icon=", "linehl=", "numhl=", "text=", "texthl=", NULL
            };
            return (char_u *)define_arg[idx];
        }
@@ -2176,7 +2213,9 @@ set_context_in_sign_cmd(expand_T *xp, char_u *arg)
        {
            case SIGNCMD_DEFINE:
                if (STRNCMP(last, "texthl", 6) == 0
-                       || STRNCMP(last, "linehl", 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,6 +2260,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
     char_u     *text = NULL;
     char_u     *texthl = NULL;
     char_u     *culhl = NULL;
+    char_u     *numhl = NULL;
     int                retval = -1;
 
     if (name_arg == NULL)
@@ -2240,9 +2280,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
        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) == OK)
+    if (sign_define_by_name(name, icon, linehl, text, texthl, culhl, numhl) == OK)
        retval = 0;
 
 cleanup:
@@ -2252,6 +2293,7 @@ cleanup:
     vim_free(text);
     vim_free(texthl);
     vim_free(culhl);
+    vim_free(numhl);
 
     return retval;
 }
index 7023ac3d342d23bda1b0ec10fd8a7407c0b039cd..41604537fee54c7592a982aea63245b2415a587a 100644 (file)
@@ -854,6 +854,7 @@ typedef struct sign_attrs_S {
     int                sat_texthl;
     int                sat_linehl;
     int                sat_culhl;
+    int                sat_numhl;
     int                sat_priority;
 } sign_attrs_T;
 
index a1ffdf5cfd13c3c9e59e81ba94db9140428b85aa..77bb049ace5b3113aa4f31a3468aa180ff3dc24e 100644 (file)
@@ -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 culhl=Search icon=../../pixmaps/stock_vim_find_help.png')
+  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$', a)
+             \ 'linehl=Error texthl=Title culhl=Search numhl=Number$', a)
 
   let a=execute('sign list Sign1')
   call assert_equal("\nsign Sign1 text=x ", a)
@@ -127,26 +127,34 @@ func Test_sign()
   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
+  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
+  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,15 +226,13 @@ func Test_sign_completion()
   call assert_equal('"sign define jump list place undefine unplace', @:)
 
   call feedkeys(":sign define Sign \<C-A>\<C-B>\"\<CR>", 'tx')
-  call assert_equal('"sign define Sign icon= linehl= text= texthl=', @:)
+  call assert_equal('"sign define Sign culhl= icon= linehl= numhl= text= texthl=', @:)
 
-  call feedkeys(":sign define Sign linehl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
-  call assert_equal('"sign define Sign linehl=SpellBad SpellCap ' .
-             \ 'SpellLocal SpellRare', @:)
-
-  call feedkeys(":sign define Sign texthl=Spell\<C-A>\<C-B>\"\<CR>", 'tx')
-  call assert_equal('"sign define Sign texthl=SpellBad SpellCap ' .
-             \ 'SpellLocal SpellRare', @:)
+  for hl in ['culhl', 'linehl', 'numhl', 'texthl']
+    call feedkeys(":sign define Sign "..hl.."=Spell\<C-A>\<C-B>\"\<CR>", '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,20 +423,21 @@ func Test_sign_funcs()
 
   " Tests for sign_define()
   let attr = {'text' : '=>', 'linehl' : 'Search', 'texthl' : 'Error',
-              \ 'culhl': 'Visual'}
+              \ 'culhl': 'Visual', 'numhl': 'Number'}
   call assert_equal(0, "sign1"->sign_define(attr))
-  call assert_equal([{'name' : 'sign1', 'texthl' : 'Error',
-             \ 'linehl' : 'Search', 'culhl' : 'Visual', 'text' : '=>'}],
+  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', 'icon' : 'sign2.ico'}
+             \ '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' : '!!',
-              \ 'icon' : 'sign2.ico'}], "sign2"->sign_getdefined())
+              \ 'numhl': 'Number', 'icon' : 'sign2.ico'}],
+              \ "sign2"->sign_getdefined())
 
   " Test for a sign name with digits
   call assert_equal(0, sign_define(0002, {'linehl' : 'StatusLine'}))
index 53d3b57e102f6f3fd5079c80fb0a5bb37e40313c..072e88431b6e6c53df22fe5494d307c95e2b3938 100644 (file)
@@ -749,6 +749,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3874,
 /**/
     3873,
 /**/