aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2021-12-05 15:36:54 -0500
committerJames McCoy <jamessan@jamessan.com>2021-12-08 21:47:58 -0500
commite8f9262125535bea8c7fcf833a715b569e07996e (patch)
treeecbbd94671bac26098f270f016c6f02956047bfc
parent2cd815c0af3eded9771df94532b4fb3817f2d3c6 (diff)
downloadrneovim-e8f9262125535bea8c7fcf833a715b569e07996e.tar.gz
rneovim-e8f9262125535bea8c7fcf833a715b569e07996e.tar.bz2
rneovim-e8f9262125535bea8c7fcf833a715b569e07996e.zip
vim-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 vim/vim#9201) https://github.com/vim/vim/commit/e413ea04b716effb28eb49dbc98ad3f9f761545a
-rw-r--r--runtime/doc/sign.txt18
-rw-r--r--runtime/doc/syntax.txt4
-rw-r--r--src/nvim/highlight_defs.h4
-rw-r--r--src/nvim/option.c1
-rw-r--r--src/nvim/screen.c41
-rw-r--r--src/nvim/sign.c39
-rw-r--r--src/nvim/sign_defs.h1
-rw-r--r--src/nvim/syntax.c2
-rw-r--r--src/nvim/testdir/test_signs.vim16
-rw-r--r--test/functional/ui/cursor_spec.lua4
10 files changed, 107 insertions, 23 deletions
diff --git a/runtime/doc/sign.txt b/runtime/doc/sign.txt
index 895ee5ebef..641e193b5e 100644
--- a/runtime/doc/sign.txt
+++ b/runtime/doc/sign.txt
@@ -47,6 +47,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
@@ -156,6 +158,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*
@@ -377,6 +386,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.
numhl highlight group used for 'number' column at the
associated line. Overrides |hl-LineNr|,
|hl-CursorLineNr|.
@@ -425,9 +437,13 @@ sign_getdefined([{name}]) *sign_getdefined()*
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.
numhl highlight group used for 'number' column at the
associated line. Overrides |hl-LineNr|,
- |hl-CursorLineNr|.
+ |hl-CursorLineNr|; not present if not set.
Returns an empty List if there are no signs and when {name} is
not found.
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index b57b8bfd5c..d49809599d 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -5127,6 +5127,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|
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index d4d53c4126..50a03e0c02 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -65,6 +65,8 @@ typedef enum {
HLF_LNA, // LineNrAbove
HLF_LNB, // LineNrBelow
HLF_CLN, // current line number when 'cursorline' is set
+ 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
@@ -122,6 +124,8 @@ EXTERN const char *hlf_names[] INIT(= {
[HLF_LNA] = "LineNrAbove",
[HLF_LNB] = "LineNrBelow",
[HLF_CLN] = "CursorLineNr",
+ [HLF_CLS] = "CursorLineSign",
+ [HLF_CLF] = "CursorLineFold",
[HLF_R] = "Question",
[HLF_S] = "StatusLine",
[HLF_SNC] = "StatusLineNC",
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 1fe2e1d04c..92c27378ee 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -262,6 +262,7 @@ typedef struct vimoption {
#define HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@: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," \
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index a666b9c8b0..6d3142451f 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2746,7 +2746,11 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
p_extra = p_extra_free;
c_extra = NUL;
c_final = NUL;
- char_attr = win_hl_attr(wp, HLF_FC);
+ if (use_cursor_line_sign(wp, lnum)) {
+ char_attr = win_hl_attr(wp, HLF_CLF);
+ } else {
+ char_attr = win_hl_attr(wp, HLF_FC);
+ }
}
}
@@ -2757,7 +2761,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
* buffer or when using Netbeans. */
int count = win_signcol_count(wp);
if (count > 0) {
- get_sign_display_info(false, wp, sattrs, row,
+ get_sign_display_info(false, wp, lnum, sattrs, row,
startrow, filler_lines, filler_todo, count,
&c_extra, &c_final, extra, sizeof(extra),
&p_extra, &n_extra,
@@ -2778,7 +2782,7 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
if (*wp->w_p_scl == 'n' && *(wp->w_p_scl + 1) == 'u'
&& num_signs > 0) {
int count = win_signcol_count(wp);
- get_sign_display_info(true, wp, sattrs, row,
+ get_sign_display_info(true, wp, lnum, sattrs, row,
startrow, filler_lines, filler_todo, count,
&c_extra, &c_final, extra, sizeof(extra),
&p_extra, &n_extra,
@@ -4617,6 +4621,14 @@ void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off)
}
}
+// Return true if CursorLineSign highlight is to be used.
+static bool 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.
// Otherwise the sign is going to be displayed in the sign column.
@@ -4624,11 +4636,11 @@ void screen_adjust_grid(ScreenGrid **grid, int *row_off, int *col_off)
// @param count max number of signs
// @param[out] n_extrap number of characters from pp_extra to display
// @param[in, out] sign_idxp Index of the displayed sign
-static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[], int row,
- int startrow, int filler_lines, int filler_todo, int count,
- int *c_extrap, int *c_finalp, char_u *extra, size_t extra_size,
- char_u **pp_extra, int *n_extrap, int *char_attrp,
- int *draw_statep, int *sign_idxp)
+static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, sign_attrs_T sattrs[],
+ int row, int startrow, int filler_lines, int filler_todo,
+ int count, int *c_extrap, int *c_finalp, char_u *extra,
+ size_t extra_size, char_u **pp_extra, int *n_extrap,
+ int *char_attrp, int *draw_statep, int *sign_idxp)
{
// Draw cells with the sign value or blank.
*c_extrap = ' ';
@@ -4636,7 +4648,11 @@ static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[],
if (nrcol) {
*n_extrap = number_width(wp) + 1;
} else {
- *char_attrp = win_hl_attr(wp, HLF_SC);
+ if (use_cursor_line_sign(wp, lnum)) {
+ *char_attrp = win_hl_attr(wp, HLF_CLS);
+ } else {
+ *char_attrp = win_hl_attr(wp, HLF_SC);
+ }
*n_extrap = win_signcol_width(wp);
}
@@ -4676,7 +4692,12 @@ static void get_sign_display_info(bool nrcol, win_T *wp, sign_attrs_T sattrs[],
(*pp_extra)[*n_extrap] = NUL;
}
}
- *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;
+ }
}
}
diff --git a/src/nvim/sign.c b/src/nvim/sign.c
index fca73dc9f2..d2faac2b94 100644
--- a/src/nvim/sign.c
+++ b/src/nvim/sign.c
@@ -31,6 +31,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
int sn_num_hl; // highlight ID for line number
};
@@ -499,6 +500,9 @@ int buf_get_signattrs(buf_T *buf, linenr_T lnum, sign_attrs_T sattrs[])
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);
+ }
if (sp->sn_num_hl != 0) {
sattr.sat_numhl = syn_id2attr(sp->sn_num_hl);
}
@@ -901,7 +905,7 @@ static int sign_define_init_text(sign_T *sp, char_u *text)
/// Define a new sign or update an existing sign
int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text, char_u *texthl,
- char *numhl)
+ char_u *culhl, char *numhl)
{
sign_T *sp_prev;
sign_T *sp;
@@ -946,6 +950,10 @@ int sign_define_by_name(char_u *name, char_u *icon, char_u *linehl, char_u *text
sp->sn_text_hl = syn_check_group((char *)texthl, (int)STRLEN(texthl));
}
+ if (culhl != NULL) {
+ sp->sn_cul_hl = syn_check_group((char *)culhl, (int)STRLEN(culhl));
+ }
+
if (numhl != NULL) {
sp->sn_num_hl = syn_check_group(numhl, (int)STRLEN(numhl));
}
@@ -1133,6 +1141,7 @@ static void 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;
char_u *numhl = NULL;
int failed = false;
@@ -1155,6 +1164,9 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
} else if (STRNCMP(arg, "texthl=", 7) == 0) {
arg += 7;
texthl = vim_strnsave(arg, (size_t)(p - arg));
+ } else if (STRNCMP(arg, "culhl=", 6) == 0) {
+ arg += 6;
+ culhl = vim_strnsave(arg, (size_t)(p - arg));
} else if (STRNCMP(arg, "numhl=", 6) == 0) {
arg += 6;
numhl = vim_strnsave(arg, (size_t)(p - arg));
@@ -1166,13 +1178,14 @@ static void sign_define_cmd(char_u *sign_name, char_u *cmdline)
}
if (!failed) {
- sign_define_by_name(sign_name, icon, linehl, text, texthl, (char *)numhl);
+ sign_define_by_name(sign_name, icon, linehl, text, texthl, culhl, (char *)numhl);
}
xfree(icon);
xfree(text);
xfree(linehl);
xfree(texthl);
+ xfree(culhl);
xfree(numhl);
}
@@ -1481,6 +1494,13 @@ static void sign_getinfo(sign_T *sp, dict_T *retdict)
}
tv_dict_add_str(retdict, S_LEN("texthl"), (char *)p);
}
+ if (sp->sn_cul_hl > 0) {
+ p = get_highlight_name_ext(NULL, sp->sn_cul_hl - 1, false);
+ if (p == NULL) {
+ p = "NONE";
+ }
+ tv_dict_add_str(retdict, S_LEN("culhl"), (char *)p);
+ }
if (sp->sn_num_hl > 0) {
p = get_highlight_name_ext(NULL, sp->sn_num_hl - 1, false);
if (p == NULL) {
@@ -1609,6 +1629,16 @@ static void sign_list_defined(sign_T *sp)
msg_puts(p);
}
}
+ if (sp->sn_cul_hl > 0) {
+ msg_puts(" culhl=");
+ const char *const p = get_highlight_name_ext(NULL,
+ sp->sn_cul_hl - 1, false);
+ if (p == NULL) {
+ msg_puts("NONE");
+ } else {
+ msg_puts(p);
+ }
+ }
if (sp->sn_num_hl > 0) {
msg_puts(" numhl=");
const char *const p = get_highlight_name_ext(NULL,
@@ -1847,6 +1877,7 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict)
char *linehl = NULL;
char *text = NULL;
char *texthl = NULL;
+ char *culhl = NULL;
char *numhl = NULL;
int retval = -1;
@@ -1866,11 +1897,12 @@ int sign_define_from_dict(const char *name_arg, dict_T *dict)
linehl = tv_dict_get_string(dict, "linehl", true);
text = tv_dict_get_string(dict, "text", true);
texthl = tv_dict_get_string(dict, "texthl", true);
+ culhl = tv_dict_get_string(dict, "culhl", true);
numhl = tv_dict_get_string(dict, "numhl", true);
}
if (sign_define_by_name((char_u *)name, (char_u *)icon, (char_u *)linehl,
- (char_u *)text, (char_u *)texthl, numhl)
+ (char_u *)text, (char_u *)texthl, (char_u *)culhl, numhl)
== OK) {
retval = 0;
}
@@ -1881,6 +1913,7 @@ cleanup:
xfree(linehl);
xfree(text);
xfree(texthl);
+ xfree(culhl);
xfree(numhl);
return retval;
diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h
index 46436b2c8e..c734502878 100644
--- a/src/nvim/sign_defs.h
+++ b/src/nvim/sign_defs.h
@@ -38,6 +38,7 @@ typedef struct sign_attrs_S {
char_u *sat_text;
int sat_texthl;
int sat_linehl;
+ int sat_culhl;
int sat_numhl;
} sign_attrs_T;
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index cb243668ce..7eb33d8fdc 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -6175,6 +6175,8 @@ static const char *highlight_init_both[] = {
"default link LineNrAbove LineNr",
"default link LineNrBelow LineNr",
"default link QuickFixLine Search",
+ "default link CursorLineSign SignColumn",
+ "default link CursorLineFold FoldColumn",
"default link Substitute Search",
"default link Whitespace NonText",
"default link MsgSeparator StatusLine",
diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim
index f287256396..35c80b375a 100644
--- a/src/nvim/testdir/test_signs.vim
+++ b/src/nvim/testdir/test_signs.vim
@@ -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'}))
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index 9c035c728b..03cd4bfd06 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -212,10 +212,10 @@ describe('ui/cursor', function()
if m.blinkwait then m.blinkwait = 700 end
end
if m.hl_id then
- m.hl_id = 58
+ m.hl_id = 60
m.attr = {background = Screen.colors.DarkGray}
end
- if m.id_lm then m.id_lm = 59 end
+ if m.id_lm then m.id_lm = 61 end
end
-- Assert the new expectation.