Skip to content

Commit 213da55

Browse files
committed
patch 8.2.1703: ":highlight clear" does not restore default link
Problem: ":highlight clear" does not restore default link. Solution: Remember the default link and restore it. (Antony Scriven, closes #6970, closes #4405)
1 parent da69764 commit 213da55

File tree

4 files changed

+66
-19
lines changed

4 files changed

+66
-19
lines changed

runtime/doc/syntax.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4809,6 +4809,7 @@ in their own color.
48094809
highlighting for groups added by the user!
48104810
Uses the current value of 'background' to decide which
48114811
default colors to use.
4812+
If there was a default link, restore it. |:hi-link|
48124813

48134814
:hi[ghlight] clear {group-name}
48144815
:hi[ghlight] {group-name} NONE

src/highlight.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ typedef struct
7373
char_u *sg_gui_sp_name;// GUI special color name
7474
#endif
7575
int sg_link; // link to this highlight group ID
76+
int sg_deflink; // default link; restored in highlight_clear()
7677
int sg_set; // combination of SG_* flags
7778
#ifdef FEAT_EVAL
7879
sctx_T sg_script_ctx; // script in which the group was last set
@@ -715,6 +716,7 @@ do_highlight(
715716
char_u *to_end;
716717
int from_id;
717718
int to_id;
719+
hl_group_T *hlgroup = NULL;
718720

719721
from_end = skiptowhite(from_start);
720722
to_start = skipwhite(from_end);
@@ -740,7 +742,14 @@ do_highlight(
740742
else
741743
to_id = syn_check_group(to_start, (int)(to_end - to_start));
742744

743-
if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0))
745+
if (from_id > 0)
746+
{
747+
hlgroup = &HL_TABLE()[from_id - 1];
748+
if (dodefault && (forceit || hlgroup->sg_deflink == 0))
749+
hlgroup->sg_deflink = to_id;
750+
}
751+
752+
if (from_id > 0 && (!init || hlgroup->sg_set == 0))
744753
{
745754
/*
746755
* Don't allow a link when there already is some highlighting
@@ -752,21 +761,20 @@ do_highlight(
752761
if (SOURCING_NAME == NULL && !dodefault)
753762
emsg(_("E414: group has settings, highlight link ignored"));
754763
}
755-
else if (HL_TABLE()[from_id - 1].sg_link != to_id
764+
else if (hlgroup->sg_link != to_id
756765
#ifdef FEAT_EVAL
757-
|| HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid
758-
!= current_sctx.sc_sid
766+
|| hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
759767
#endif
760-
|| HL_TABLE()[from_id - 1].sg_cleared)
768+
|| hlgroup->sg_cleared)
761769
{
762770
if (!init)
763-
HL_TABLE()[from_id - 1].sg_set |= SG_LINK;
764-
HL_TABLE()[from_id - 1].sg_link = to_id;
771+
hlgroup->sg_set |= SG_LINK;
772+
hlgroup->sg_link = to_id;
765773
#ifdef FEAT_EVAL
766-
HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx;
767-
HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += SOURCING_LNUM;
774+
hlgroup->sg_script_ctx = current_sctx;
775+
hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
768776
#endif
769-
HL_TABLE()[from_id - 1].sg_cleared = FALSE;
777+
hlgroup->sg_cleared = FALSE;
770778
redraw_all_later(SOME_VALID);
771779

772780
// Only call highlight_changed() once after multiple changes.
@@ -1684,6 +1692,8 @@ highlight_clear(int idx)
16841692
HL_TABLE()[idx].sg_gui_attr = 0;
16851693
#endif
16861694
#ifdef FEAT_EVAL
1695+
// Restore any default link.
1696+
HL_TABLE()[idx].sg_link = HL_TABLE()[idx].sg_deflink;
16871697
// Clear the script ID only when there is no link, since that is not
16881698
// cleared.
16891699
if (HL_TABLE()[idx].sg_link == 0)

src/testdir/test_highlight.vim

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,47 @@ func Test_highlight_term_attr()
832832
hi clear
833833
endfunc
834834

835-
" Test default highlighting is restored
836-
func Test_highlight_restore_defaults()
837-
hi! link TestLink Identifier
838-
hi! TestHi ctermbg=red
835+
func Test_highlight_clear_restores_links()
836+
let aaa_id = hlID('aaa')
837+
call assert_equal(aaa_id, 0)
838+
839+
" create default link aaa --> bbb
840+
hi def link aaa bbb
841+
let id_aaa = hlID('aaa')
842+
let hl_aaa_bbb = HighlightArgs('aaa')
843+
844+
" try to redefine default link aaa --> ccc; check aaa --> bbb
845+
hi def link aaa ccc
846+
call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
847+
848+
" clear aaa; check aaa --> bbb
849+
hi clear aaa
850+
call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
851+
852+
" link aaa --> ccc; clear aaa; check aaa --> bbb
853+
hi link aaa ccc
854+
let id_ccc = hlID('ccc')
855+
call assert_equal(synIDtrans(id_aaa), id_ccc)
856+
hi clear aaa
857+
call assert_equal(HighlightArgs('aaa'), hl_aaa_bbb)
858+
859+
" forcibly set default link aaa --> ddd
860+
hi! def link aaa ddd
861+
let id_ddd = hlID('ddd')
862+
let hl_aaa_ddd = HighlightArgs('aaa')
863+
call assert_equal(synIDtrans(id_aaa), id_ddd)
864+
865+
" link aaa --> eee; clear aaa; check aaa --> ddd
866+
hi link aaa eee
867+
let eee_id = hlID('eee')
868+
call assert_equal(synIDtrans(id_aaa), eee_id)
869+
hi clear aaa
870+
call assert_equal(HighlightArgs('aaa'), hl_aaa_ddd)
871+
endfunc
872+
873+
func Test_highlight_default_colorscheme_restores_links()
874+
hi link TestLink Identifier
875+
hi TestHi ctermbg=red
839876

840877
let hlTestLinkPre = HighlightArgs('TestLink')
841878
let hlTestHiPre = HighlightArgs('TestHi')
@@ -846,19 +883,16 @@ func Test_highlight_restore_defaults()
846883
syntax reset
847884
endif
848885
let g:colors_name = 'test'
849-
hi! link TestLink ErrorMsg
850-
hi! TestHi ctermbg=green
886+
hi link TestLink ErrorMsg
887+
hi TestHi ctermbg=green
851888

852889
" Restore default highlighting
853890
colorscheme default
854-
syntax on
855891
" 'default' should work no matter if highlight group was cleared
856892
hi def link TestLink Identifier
857893
hi def TestHi ctermbg=red
858-
859894
let hlTestLinkPost = HighlightArgs('TestLink')
860895
let hlTestHiPost = HighlightArgs('TestHi')
861-
862896
call assert_equal(hlTestLinkPre, hlTestLinkPost)
863897
call assert_equal(hlTestHiPre, hlTestHiPost)
864898
hi clear

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
1703,
753755
/**/
754756
1702,
755757
/**/

0 commit comments

Comments
 (0)