Problem: Cannot adjust sign highlighting for 'cursorline'.
Solution: Add CursorLineSign and CursorLineFold highlight groups.
(Gregory Anders, closes #9201)
: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
: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*
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.
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.
*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|
#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.
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,
*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;
}
*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;
}
}
}
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));
}
}
}
"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
};
# 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)
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,
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);
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;
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
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;
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;
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;
}
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.
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);
}
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);
}
/*
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);
+ }
}
/*
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);
+ }
}
/*
char_u *linehl = NULL;
char_u *text = NULL;
char_u *texthl = NULL;
+ char_u *culhl = NULL;
int retval = -1;
if (name_arg == NULL)
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:
vim_free(linehl);
vim_free(text);
vim_free(texthl);
+ vim_free(culhl);
return retval;
}
char_u *sat_text;
int sat_texthl;
int sat_linehl;
+ int sat_culhl;
int sat_priority;
} sign_attrs_T;
" 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)
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'}))
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 3664,
/**/
3663,
/**/
, 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
// 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', \