diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 19 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 66 | ||||
-rw-r--r-- | src/nvim/screen.c | 21 | ||||
-rw-r--r-- | src/nvim/sign_defs.h | 21 | ||||
-rw-r--r-- | src/nvim/testdir/test_signs.vim | 6 |
5 files changed, 85 insertions, 48 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 68f6ff303b..ce6aa69239 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -5084,13 +5084,16 @@ linenr_T buf_change_sign_type( return (linenr_T)0; } -int buf_getsigntype( - buf_T *buf, - linenr_T lnum, - int type /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ - ) +/// Gets a sign from a given line. +/// In case of multiple signs, returns the most recently placed one. +/// +/// @param buf Buffer in which to search +/// @param lnum Line in which to search +/// @param type Type of sign to look for +/// @return Identifier of the first matching sign, or 0 +int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type) { - signlist_T *sign; /* a sign in a b_signlist */ + signlist_T *sign; // a sign in a b_signlist for (sign = buf->b_signlist; sign != NULL; sign = sign->next) { if (sign->lnum == lnum @@ -5098,7 +5101,9 @@ int buf_getsigntype( || (type == SIGN_TEXT && sign_get_text(sign->typenr) != NULL) || (type == SIGN_LINEHL - && sign_get_attr(sign->typenr, TRUE) != 0))) { + && sign_get_attr(sign->typenr, SIGN_LINEHL) != 0) + || (type == SIGN_NUMHL + && sign_get_attr(sign->typenr, SIGN_NUMHL) != 0))) { return sign->typenr; } } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 4710ae669b..bce0c35f67 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -5471,13 +5471,14 @@ void ex_helptags(exarg_T *eap) struct sign { - sign_T *sn_next; /* next sign in list */ - int sn_typenr; /* type number of sign */ - char_u *sn_name; /* name of sign */ - char_u *sn_icon; /* name of pixmap */ - 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 */ + sign_T *sn_next; // next sign in list + int sn_typenr; // type number of sign + char_u *sn_name; // name of sign + char_u *sn_icon; // name of pixmap + 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_num_hl; // highlight ID for line number }; static sign_T *first_sign = NULL; @@ -5675,6 +5676,9 @@ void ex_sign(exarg_T *eap) } else if (STRNCMP(arg, "texthl=", 7) == 0) { arg += 7; sp->sn_text_hl = syn_check_group(arg, (int)(p - arg)); + } else if (STRNCMP(arg, "numhl=", 6) == 0) { + arg += 6; + sp->sn_num_hl = syn_check_group(arg, (int)(p - arg)); } else { EMSG2(_(e_invarg2), arg); return; @@ -5901,6 +5905,16 @@ static void sign_list_defined(sign_T *sp) msg_puts(p); } } + if (sp->sn_num_hl > 0) { + msg_puts(" numhl="); + const char *const p = get_highlight_name_ext(NULL, + sp->sn_num_hl - 1, false); + if (p == NULL) { + msg_puts("NONE"); + } else { + msg_puts(p); + } + } } /* @@ -5918,25 +5932,33 @@ static void sign_undefine(sign_T *sp, sign_T *sp_prev) xfree(sp); } -/* - * Get highlighting attribute for sign "typenr". - * If "line" is TRUE: line highl, if FALSE: text highl. - */ -int sign_get_attr(int typenr, int line) +/// Gets highlighting attribute for sign "typenr" corresponding to "type". +int sign_get_attr(int typenr, SignType type) { sign_T *sp; + int sign_hl = 0; - for (sp = first_sign; sp != NULL; sp = sp->sn_next) + for (sp = first_sign; sp != NULL; sp = sp->sn_next) { if (sp->sn_typenr == typenr) { - if (line) { - if (sp->sn_line_hl > 0) - return syn_id2attr(sp->sn_line_hl); - } else { - if (sp->sn_text_hl > 0) - return syn_id2attr(sp->sn_text_hl); + switch (type) { + case SIGN_TEXT: + sign_hl = sp->sn_text_hl; + break; + case SIGN_LINEHL: + sign_hl = sp->sn_line_hl; + break; + case SIGN_NUMHL: + sign_hl = sp->sn_num_hl; + break; + default: + abort(); + } + if (sign_hl > 0) { + return syn_id2attr(sign_hl); } break; } + } return 0; } @@ -5997,7 +6019,8 @@ char_u * get_sign_name(expand_T *xp, int idx) case EXP_SUBCMD: return (char_u *)cmds[idx]; case EXP_DEFINE: { - char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", NULL }; + char *define_arg[] = { "icon=", "linehl=", "text=", "texthl=", "numhl=", + NULL }; return (char_u *)define_arg[idx]; } case EXP_PLACE: { @@ -6120,7 +6143,8 @@ void set_context_in_sign_cmd(expand_T *xp, char_u *arg) { case SIGNCMD_DEFINE: if (STRNCMP(last, "texthl", p - last) == 0 - || STRNCMP(last, "linehl", p - last) == 0) { + || STRNCMP(last, "linehl", p - last) == 0 + || STRNCMP(last, "numhl", p - last) == 0) { xp->xp_context = EXPAND_HIGHLIGHT; } else if (STRNCMP(last, "icon", p - last) == 0) { xp->xp_context = EXPAND_FILES; diff --git a/src/nvim/screen.c b/src/nvim/screen.c index ec4b31c40d..a5b07bb49f 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -2486,7 +2486,7 @@ win_line ( // If this line has a sign with line highlighting set line_attr. v = buf_getsigntype(wp->w_buffer, lnum, SIGN_LINEHL); if (v != 0) { - line_attr = sign_get_attr((int)v, true); + line_attr = sign_get_attr((int)v, SIGN_LINEHL); } // Highlight the current line in the quickfix window. @@ -2794,7 +2794,7 @@ win_line ( p_extra = extra; p_extra[n_extra] = NUL; } - char_attr = sign_get_attr(text_sign, FALSE); + char_attr = sign_get_attr(text_sign, SIGN_TEXT); } } } @@ -2841,12 +2841,17 @@ win_line ( c_extra = ' '; n_extra = number_width(wp) + 1; char_attr = win_hl_attr(wp, HLF_N); - // When 'cursorline' is set highlight the line number of - // the current line differently. - // TODO(vim): Can we use CursorLine instead of CursorLineNr - // when CursorLineNr isn't set? - if ((wp->w_p_cul || wp->w_p_rnu) - && lnum == wp->w_cursor.lnum) { + + int num_sign = buf_getsigntype(wp->w_buffer, lnum, SIGN_NUMHL); + if (num_sign != 0) { + // :sign defined with "numhl" highlight. + char_attr = sign_get_attr(num_sign, SIGN_NUMHL); + } else if ((wp->w_p_cul || wp->w_p_rnu) + && lnum == wp->w_cursor.lnum) { + // When 'cursorline' is set highlight the line number of + // the current line differently. + // TODO(vim): Can we use CursorLine instead of CursorLineNr + // when CursorLineNr isn't set? char_attr = win_hl_attr(wp, HLF_CLN); } } diff --git a/src/nvim/sign_defs.h b/src/nvim/sign_defs.h index 3778f4287e..4443fd8a2e 100644 --- a/src/nvim/sign_defs.h +++ b/src/nvim/sign_defs.h @@ -9,17 +9,20 @@ typedef struct signlist signlist_T; struct signlist { - int id; /* unique identifier for each placed sign */ - linenr_T lnum; /* line number which has this sign */ - int typenr; /* typenr of sign */ - signlist_T *next; /* next signlist entry */ + int id; // unique identifier for each placed sign + linenr_T lnum; // line number which has this sign + int typenr; // typenr of sign + signlist_T *next; // next signlist entry }; -/* type argument for buf_getsigntype() */ -#define SIGN_ANY 0 -#define SIGN_LINEHL 1 -#define SIGN_ICON 2 -#define SIGN_TEXT 3 +// type argument for buf_getsigntype() and sign_get_attr() +typedef enum { + SIGN_ANY, + SIGN_LINEHL, + SIGN_ICON, + SIGN_TEXT, + SIGN_NUMHL, +} SignType; diff --git a/src/nvim/testdir/test_signs.vim b/src/nvim/testdir/test_signs.vim index a967435346..d3c6d05f4f 100644 --- a/src/nvim/testdir/test_signs.vim +++ b/src/nvim/testdir/test_signs.vim @@ -14,7 +14,7 @@ func Test_sign() " the icon name when listing signs. sign define Sign1 text=x try - sign define Sign2 text=xy texthl=Title linehl=Error icon=../../pixmaps/stock_vim_find_help.png + sign define Sign2 text=xy texthl=Title linehl=Error numhl=Number icon=../../pixmaps/stock_vim_find_help.png catch /E255:/ " ignore error: E255: Couldn't read in sign data! " This error can happen when running in gui. @@ -23,7 +23,7 @@ func Test_sign() " 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) + call assert_match("^\nsign Sign1 text=x \nsign Sign2 icon=../../pixmaps/stock_vim_find_help.png .*text=xy linehl=Error texthl=Title numhl=Number$", a) let a=execute('sign list Sign1') call assert_equal("\nsign Sign1 text=x ", a) @@ -140,7 +140,7 @@ 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 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', @:) |