0
0
mirror of https://github.com/vim/vim.git synced 2025-08-30 20:43:35 -04:00

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 #9201)
This commit is contained in:
Bram Moolenaar 2021-11-24 16:20:13 +00:00
parent 1f2453fec6
commit e413ea04b7
12 changed files with 104 additions and 18 deletions

View 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.

View 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|

View 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));
}
}
}

View 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
};

View 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)

View 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,

View 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);

View 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;
}

View 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;

View 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'}))

View File

@ -757,6 +757,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3664,
/**/
3663,
/**/

View File

@ -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', \