diff options
-rw-r--r-- | src/nvim/cmdexpand.c | 2 | ||||
-rw-r--r-- | src/nvim/highlight_group.c | 32 | ||||
-rw-r--r-- | src/nvim/testdir/test_syntax.vim | 12 |
3 files changed, 36 insertions, 10 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c index abf36734b9..c16ed37c9a 100644 --- a/src/nvim/cmdexpand.c +++ b/src/nvim/cmdexpand.c @@ -2059,7 +2059,7 @@ static int ExpandOther(expand_T *xp, regmatch_T *rmp, int *num_file, char ***fil { EXPAND_MENUNAMES, get_menu_names, false, true }, { EXPAND_SYNTAX, get_syntax_name, true, true }, { EXPAND_SYNTIME, get_syntime_arg, true, true }, - { EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, true }, + { EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, false }, { EXPAND_EVENTS, expand_get_event_name, true, false }, { EXPAND_AUGROUP, expand_get_augroup_name, true, false }, { EXPAND_CSCOPE, get_cscope_name, true, true }, diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 30c39a3158..4c207fdb53 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -79,6 +79,8 @@ typedef struct { int sg_rgb_sp_idx; ///< RGB special color index int sg_blend; ///< blend level (0-100 inclusive), -1 if unset + + int sg_parent; ///< parent of @nested.group } HlGroup; enum { @@ -1375,6 +1377,11 @@ static void highlight_list_one(const int id) return; } + // don't list specialized groups if a parent is used instead + if (sgp->sg_parent && sgp->sg_cleared) { + return; + } + didh = highlight_list_arg(id, didh, LIST_ATTR, sgp->sg_cterm, NULL, "cterm"); didh = highlight_list_arg(id, didh, LIST_INT, @@ -1661,7 +1668,12 @@ static void set_hl_attr(int idx) int syn_name2id(const char *name) FUNC_ATTR_NONNULL_ALL { - return syn_name2id_len(name, STRLEN(name)); + if (name[0] == '@') { + // if we look up @aaa.bbb, we have to consider @aaa as well + return syn_check_group(name, strlen(name)); + } else { + return syn_name2id_len(name, STRLEN(name)); + } } /// Lookup a highlight group name and return its ID. @@ -1758,6 +1770,14 @@ static int syn_add_group(const char *name, size_t len) } } + int scoped_parent = 0; + if (len > 1 && name[0] == '@') { + char *delim = xmemrchr(name, '.', len); + if (delim) { + scoped_parent = syn_check_group(name, (size_t)(delim - name)); + } + } + // First call for this growarray: init growing array. if (highlight_ga.ga_data == NULL) { highlight_ga.ga_itemsize = sizeof(HlGroup); @@ -1783,6 +1803,9 @@ static int syn_add_group(const char *name, size_t len) hlgp->sg_rgb_sp_idx = kColorIdxNone; hlgp->sg_blend = -1; hlgp->sg_name_u = arena_memdupz(&highlight_arena, name, len); + hlgp->sg_parent = scoped_parent; + // will get set to false by caller if settings are added + hlgp->sg_cleared = true; vim_strup((char_u *)hlgp->sg_name_u); int id = highlight_ga.ga_len; // ID is index plus one @@ -1844,10 +1867,13 @@ int syn_ns_get_final_id(int *ns_id, int hl_id) continue; } - if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) { + if (sgp->sg_link > 0 && sgp->sg_link <= highlight_ga.ga_len) { + hl_id = sgp->sg_link; + } else if (sgp->sg_cleared && sgp->sg_parent > 0) { + hl_id = sgp->sg_parent; + } else { break; } - hl_id = sgp->sg_link; } return hl_id; diff --git a/src/nvim/testdir/test_syntax.vim b/src/nvim/testdir/test_syntax.vim index af93a37739..85f27dd043 100644 --- a/src/nvim/testdir/test_syntax.vim +++ b/src/nvim/testdir/test_syntax.vim @@ -188,22 +188,22 @@ func Test_syntax_completion() call assert_equal('"syn sync ccomment clear fromstart linebreaks= linecont lines= match maxlines= minlines= region', @:) " Check that clearing "Aap" avoids it showing up before Boolean. - hi Aap ctermfg=blue + hi @Aap ctermfg=blue call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn list Aap Boolean Character ', @:) - hi clear Aap + call assert_match('^"syn list @Aap @boolean @character ', @:) + hi clear @Aap call feedkeys(":syn list \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn list Boolean Character ', @:) + call assert_match('^"syn list @boolean @character ', @:) call feedkeys(":syn match \<C-A>\<C-B>\"\<CR>", 'tx') - call assert_match('^"syn match Boolean Character ', @:) + call assert_match('^"syn match @boolean @character ', @:) endfunc func Test_echohl_completion() call feedkeys(":echohl no\<C-A>\<C-B>\"\<CR>", 'tx') " call assert_equal('"echohl NonText Normal none', @:) - call assert_equal('"echohl NonText Normal NormalFloat NormalNC none', @:) + call assert_equal('"echohl NonText Normal NormalFloat none', @:) endfunc func Test_syntax_arg_skipped() |