]> granicus.if.org Git - vim/commitdiff
patch 8.2.3664: cannot adjust sign highlighting for 'cursorline' v8.2.3664
authorBram Moolenaar <Bram@vim.org>
Wed, 24 Nov 2021 16:20:13 +0000 (16:20 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 24 Nov 2021 16:20:13 +0000 (16:20 +0000)
Problem:    Cannot adjust sign highlighting for 'cursorline'.
Solution:   Add CursorLineSign and CursorLineFold highlight groups.
            (Gregory Anders, closes #9201)

12 files changed:
runtime/doc/sign.txt
runtime/doc/syntax.txt
src/drawline.c
src/highlight.c
src/optiondefs.h
src/popupwin.c
src/proto/sign.pro
src/sign.c
src/structs.h
src/testdir/test_signs.vim
src/version.c
src/vim.h

index 57f7dc764915d64f1d99d63580251cccab532398..96658e544da7b9b9b6912529262d9c46dbb78328 100644 (file)
@@ -53,6 +53,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
@@ -171,6 +173,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*
 
@@ -393,6 +402,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.
 
                If the sign named {name} already exists, then the attributes
                of the sign are updated.
@@ -437,6 +449,9 @@ sign_getdefined([{name}])                           *sign_getdefined()*
                   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.
index db0f70f176c3c8af776ebefb03f0420ea42810b7..08d3f5f1116c3cc738a65ee7a1ed1f589232873c 100644 (file)
@@ -5251,6 +5251,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|
index 7d6f669ba1a4f6074a0baa34b3542f35b3dd23e1..e68a602858c5dd898528ce51815f06c8fe366a88 100644 (file)
@@ -76,6 +76,17 @@ margin_columns_win(win_T *wp, int *left_col, int *right_col)
 #endif
 
 #ifdef FEAT_SIGNS
+/*
+ * Return TRUE if CursorLineSign highlight is to be used.
+ */
+    static int
+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.
@@ -85,7 +96,7 @@ margin_columns_win(win_T *wp, int *left_col, int *right_col)
 get_sign_display_info(
        int             nrcol,
        win_T           *wp,
-       linenr_T        lnum UNUSED,
+       linenr_T        lnum,
        sign_attrs_T    *sattr,
        int             wcr_attr,
        int             row,
@@ -111,7 +122,10 @@ get_sign_display_info(
        *n_extrap = number_width(wp) + 1;
     else
     {
-       *char_attrp = hl_combine_attr(wcr_attr, HL_ATTR(HLF_SC));
+       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;
     }
 
@@ -176,7 +190,11 @@ get_sign_display_info(
                    *c_finalp = NUL;
                    *n_extrap = (int)STRLEN(*pp_extra);
                }
-               *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;
            }
     }
 }
@@ -1051,7 +1069,12 @@ win_line(
                        p_extra = p_extra_free;
                        c_extra = NUL;
                        c_final = NUL;
-                       char_attr = hl_combine_attr(wcr_attr, HL_ATTR(HLF_FC));
+                       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));
                    }
                }
            }
index 77ad0bc78c1466822f4dfb1577a37ca3fdb1ae6e..fe4f089ed46016381d230ac9cda76c9c313bbe7d 100644 (file)
@@ -153,6 +153,8 @@ static char *(highlight_init_both[]) = {
     "lCursor guibg=fg guifg=bg", // should be different, but what?
 #endif
     "default link QuickFixLine Search",
+    "default link CursorLineSign SignColumn",
+    "default link CursorLineFold FoldColumn",
     CENT("Normal cterm=NONE", "Normal gui=NONE"),
     NULL
 };
index d85c2333047bf70e18a7fea51a1cd9ab8db3f274..d46cfadc000eb9132121e4f23fa36cf15f341092 100644 (file)
@@ -298,7 +298,7 @@ struct vimoption
 # define ISP_LATIN1 (char_u *)"@,161-255"
 #endif
 
-# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow,N:CursorLineNr,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,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
+# define HIGHLIGHT_INIT "8:SpecialKey,~:EndOfBuffer,@: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,X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine,z:StatusLineTerm,Z:StatusLineTermNC"
 
 // Default python version for pyx* commands
 #if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
index d5f8d26ee058efc373118e250a64f6b5e361195b..0ff26e1a24175e3b9f116e1d57d7e14592d1d80c 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);
+           sign_define_by_name(sign_name, NULL, (char_u *)linehl, NULL, NULL, NULL);
        }
 
        sign_place(&sign_id, (char_u *)"PopUpMenu", sign_name,
index bda8372a24169ae2e945da9e06966175bc78d344..4e8abb3845a1484f47cc9f69ac9f49be9855e870 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);
+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);
index ea584dfe3f3ae227cb27738b471aa1eb80552fd8..a4c89679b44feabbd42134e113f6cad891064cd2 100644 (file)
@@ -32,6 +32,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
 };
 
 static sign_T  *first_sign = NULL;
@@ -517,6 +518,8 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr)
                sattr->sat_texthl = syn_id2attr(sp->sn_text_hl);
            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);
            sattr->sat_priority = sign->se_priority;
 
            // If there is another sign next with the same priority, may
@@ -540,6 +543,8 @@ buf_get_signattrs(win_T *wp, linenr_T lnum, sign_attrs_T *sattr)
                        sattr->sat_texthl = syn_id2attr(next_sp->sn_text_hl);
                    if (sp->sn_line_hl <= 0 && next_sp->sn_line_hl > 0)
                        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);
                }
            }
            return TRUE;
@@ -1035,7 +1040,8 @@ sign_define_by_name(
        char_u  *icon,
        char_u  *linehl,
        char_u  *text,
-       char_u  *texthl)
+       char_u  *texthl,
+       char_u  *culhl)
 {
     sign_T     *sp_prev;
     sign_T     *sp;
@@ -1077,6 +1083,9 @@ sign_define_by_name(
     if (texthl != NULL)
        sp->sn_text_hl = syn_check_group(texthl, (int)STRLEN(texthl));
 
+    if (culhl != NULL)
+       sp->sn_cul_hl = syn_check_group(culhl, (int)STRLEN(culhl));
+
     return OK;
 }
 
@@ -1298,6 +1307,7 @@ 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;
     int failed = FALSE;
 
     // set values for a defined sign.
@@ -1327,6 +1337,11 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
            arg += 7;
            texthl = vim_strnsave(arg, p - arg);
        }
+       else if (STRNCMP(arg, "culhl=", 6) == 0)
+       {
+           arg += 6;
+           culhl = vim_strnsave(arg, p - arg);
+       }
        else
        {
            semsg(_(e_invarg2), arg);
@@ -1336,12 +1351,13 @@ sign_define_cmd(char_u *sign_name, char_u *cmdline)
     }
 
     if (!failed)
-       sign_define_by_name(sign_name, icon, linehl, text, texthl);
+       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);
 }
 
 /*
@@ -1712,6 +1728,13 @@ sign_getinfo(sign_T *sp, dict_T *retdict)
            p = (char_u *)"NONE";
        dict_add_string(retdict, "texthl", (char_u *)p);
     }
+    if (sp->sn_cul_hl > 0)
+    {
+       p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE);
+       if (p == NULL)
+           p = (char_u *)"NONE";
+       dict_add_string(retdict, "culhl", (char_u *)p);
+    }
 }
 
 /*
@@ -1883,6 +1906,15 @@ sign_list_defined(sign_T *sp)
        else
            msg_puts((char *)p);
     }
+    if (sp->sn_cul_hl > 0)
+    {
+       msg_puts(" culhl=");
+       p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, FALSE);
+       if (p == NULL)
+           msg_puts("NONE");
+       else
+           msg_puts((char *)p);
+    }
 }
 
 /*
@@ -2173,6 +2205,7 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
     char_u     *linehl = NULL;
     char_u     *text = NULL;
     char_u     *texthl = NULL;
+    char_u     *culhl = NULL;
     int                retval = -1;
 
     if (name_arg == NULL)
@@ -2191,9 +2224,10 @@ sign_define_from_dict(char_u *name_arg, dict_T *dict)
        linehl = dict_get_string(dict, (char_u *)"linehl", TRUE);
        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) == OK)
+    if (sign_define_by_name(name, icon, linehl, text, texthl, culhl) == OK)
        retval = 0;
 
 cleanup:
@@ -2202,6 +2236,7 @@ cleanup:
     vim_free(linehl);
     vim_free(text);
     vim_free(texthl);
+    vim_free(culhl);
 
     return retval;
 }
index 9e0f64e623a41b2bfd0ecdebe45d11aa70a15c84..d9d3e30c378f20eeb769e2e9afe560865adba0ba 100644 (file)
@@ -853,6 +853,7 @@ typedef struct sign_attrs_S {
     char_u     *sat_text;
     int                sat_texthl;
     int                sat_linehl;
+    int                sat_culhl;
     int                sat_priority;
 } sign_attrs_T;
 
index b77725c7d160e6c1f4d91adee1f57a72c842eb9f..80f7160b100a7e1e476262321f722df897c67213 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 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'}))
index b4e24644573fbddc300d12c0fd6d084571747454..4356be14eeb6cf2a47fcbfcac3cb1305390d1f1e 100644 (file)
@@ -757,6 +757,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3664,
 /**/
     3663,
 /**/
index 6c5a1099c33f59ec4f4490bd4e4a8893feedfc12..7c4d12c93d874070f3277c815305014d244227a8 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -1411,6 +1411,8 @@ typedef enum
     , HLF_LNA      // LineNrAbove
     , HLF_LNB      // LineNrBelow
     , HLF_CLN      // current line number
+    , 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
@@ -1451,7 +1453,7 @@ typedef enum
 // The HL_FLAGS must be in the same order as the HLF_ enums!
 // When changing this also adjust the default for 'highlight'.
 #define HL_FLAGS {'8', '~', '@', 'd', 'e', 'h', 'i', 'l', 'm', 'M', \
-                 'n', 'a', 'b', 'N', 'r', 's', 'S', 'c', 't', 'v', 'V', \
+                 'n', 'a', 'b', 'N', 'G', 'O', 'r', 's', 'S', 'c', 't', 'v', 'V', \
                  'w', 'W', 'f', 'F', 'A', 'C', 'D', 'T', '-', '>', \
                  'B', 'P', 'R', 'L', \
                  '+', '=', 'x', 'X', '*', '#', '_', '!', '.', 'o', 'q', \