summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/syntax.txt1
-rw-r--r--src/highlight.c30
-rw-r--r--src/testdir/test_highlight.vim52
-rw-r--r--src/version.c2
4 files changed, 66 insertions, 19 deletions
diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 9c5656719..1d4dd1fec 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -4809,6 +4809,7 @@ in their own color.
highlighting for groups added by the user!
Uses the current value of 'background' to decide which
default colors to use.
+ If there was a default link, restore it. |:hi-link|
:hi[ghlight] clear {group-name}
:hi[ghlight] {group-name} NONE
diff --git a/src/highlight.c b/src/highlight.c
index 017507924..85745024c 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -73,6 +73,7 @@ typedef struct
char_u *sg_gui_sp_name;// GUI special color name
#endif
int sg_link; // link to this highlight group ID
+ int sg_deflink; // default link; restored in highlight_clear()
int sg_set; // combination of SG_* flags
#ifdef FEAT_EVAL
sctx_T sg_script_ctx; // script in which the group was last set
@@ -715,6 +716,7 @@ do_highlight(
char_u *to_end;
int from_id;
int to_id;
+ hl_group_T *hlgroup = NULL;
from_end = skiptowhite(from_start);
to_start = skipwhite(from_end);
@@ -740,7 +742,14 @@ do_highlight(
else
to_id = syn_check_group(to_start, (int)(to_end - to_start));
- if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0))
+ if (from_id > 0)
+ {
+ hlgroup = &HL_TABLE()[from_id - 1];
+ if (dodefault && (forceit || hlgroup->sg_deflink == 0))
+ hlgroup->sg_deflink = to_id;
+ }
+
+ if (from_id > 0 && (!init || hlgroup->sg_set == 0))
{
/*
* Don't allow a link when there already is some highlighting
@@ -752,21 +761,20 @@ do_highlight(
if (SOURCING_NAME == NULL && !dodefault)
emsg(_("E414: group has settings, highlight link ignored"));
}
- else if (HL_TABLE()[from_id - 1].sg_link != to_id
+ else if (hlgroup->sg_link != to_id
#ifdef FEAT_EVAL
- || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid
- != current_sctx.sc_sid
+ || hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
#endif
- || HL_TABLE()[from_id - 1].sg_cleared)
+ || hlgroup->sg_cleared)
{
if (!init)
- HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
- HL_TABLE()[from_id - 1].sg_link = to_id;
+ hlgroup->sg_set |= SG_LINK;
+ hlgroup->sg_link = to_id;
#ifdef FEAT_EVAL
- HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
- HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += SOURCING_LNUM;
+ hlgroup->sg_script_ctx = current_sctx;
+ hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
#endif
- HL_TABLE()[from_id - 1].sg_cleared = FALSE;
+ hlgroup->sg_cleared = FALSE;
redraw_all_later(SOME_VALID);
// Only call highlight_changed() once after multiple changes.
@@ -1684,6 +1692,8 @@ highlight_clear(int idx)
HL_TABLE()[idx].sg_gui_attr = 0;
#endif
#ifdef FEAT_EVAL
+ // Restore any default link.
+ HL_TABLE()[idx].sg_link = HL_TABLE()[idx].sg_deflink;
// Clear the script ID only when there is no link, since that is not
// cleared.
if (HL_TABLE()[idx].sg_link == 0)
diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim
index 5db2c57cb..5ad0c9414 100644
--- a/src/testdir/test_highlight.vim
+++ b/src/testdir/test_highlight.vim
@@ -832,10 +832,47 @@ func Test_highlight_term_attr()
hi clear
endfunc
-" Test default highlighting is restored
-func Test_highlight_restore_defaults()
- hi! link TestLink Identifier
- hi! TestHi ctermbg=red
+func Test_highlight_clear_restores_links()
+ let aaa_id = hlID('aaa')
+ call assert_equal(aaa_id, 0)
+
+ " create default link aaa --> bbb
+ hi def link aaa bbb
+ let id_aaa = hlID('aaa')
+ let hl_aaa_bbb = HighlightArgs('aaa')
+
+ " try to redefine default link aaa --> ccc; check aaa --> bbb
+ hi def link aaa ccc
+ call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
+
+ " clear aaa; check aaa --> bbb
+ hi clear aaa
+ call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
+
+ " link aaa --> ccc; clear aaa; check aaa --> bbb
+ hi link aaa ccc
+ let id_ccc = hlID('ccc')
+ call assert_equal(synIDtrans(id_aaa), id_ccc)
+ hi clear aaa
+ call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
+
+ " forcibly set default link aaa --> ddd
+ hi! def link aaa ddd
+ let id_ddd = hlID('ddd')
+ let hl_aaa_ddd = HighlightArgs('aaa')
+ call assert_equal(synIDtrans(id_aaa), id_ddd)
+
+ " link aaa --> eee; clear aaa; check aaa --> ddd
+ hi link aaa eee
+ let eee_id = hlID('eee')
+ call assert_equal(synIDtrans(id_aaa), eee_id)
+ hi clear aaa
+ call assert_equal(HighlightArgs('aaa'), hl_aaa_ddd)
+endfunc
+
+func Test_highlight_default_colorscheme_restores_links()
+ hi link TestLink Identifier
+ hi TestHi ctermbg=red
let hlTestLinkPre = HighlightArgs('TestLink')
let hlTestHiPre = HighlightArgs('TestHi')
@@ -846,19 +883,16 @@ func Test_highlight_restore_defaults()
syntax reset
endif
let g:colors_name = 'test'
- hi! link TestLink ErrorMsg
- hi! TestHi ctermbg=green
+ hi link TestLink ErrorMsg
+ hi TestHi ctermbg=green
" Restore default highlighting
colorscheme default
- syntax on
" 'default' should work no matter if highlight group was cleared
hi def link TestLink Identifier
hi def TestHi ctermbg=red
-
let hlTestLinkPost = HighlightArgs('TestLink')
let hlTestHiPost = HighlightArgs('TestHi')
-
call assert_equal(hlTestLinkPre, hlTestLinkPost)
call assert_equal(hlTestHiPre, hlTestHiPost)
hi clear
diff --git a/src/version.c b/src/version.c
index 9d87cdb7d..f7e172051 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1703,
+/**/
1702,
/**/
1701,