]> granicus.if.org Git - vim/commitdiff
patch 8.2.1703: ":highlight clear" does not restore default link v8.2.1703
authorBram Moolenaar <Bram@vim.org>
Thu, 17 Sep 2020 17:59:26 +0000 (19:59 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 17 Sep 2020 17:59:26 +0000 (19:59 +0200)
Problem:    ":highlight clear" does not restore default link.
Solution:   Remember the default link and restore it. (Antony Scriven,
            closes #6970, closes #4405)

runtime/doc/syntax.txt
src/highlight.c
src/testdir/test_highlight.vim
src/version.c

index 9c565671912161d6905060df9fe3ad915f301ad0..1d4dd1fec2b6bf0dd784e1ace2553b30f273a124 100644 (file)
@@ -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
index 0175079245aa2af9e7da200161414ea3f2752bce..85745024cc9b712556ae48ac2fb5e4b68a38adca 100644 (file)
@@ -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)
index 5db2c57cb8b5aed89f363f08d673410f91fad9f1..5ad0c941494ac2a184838638a7e5026cb8800b24 100644 (file)
@@ -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
index 9d87cdb7d049f9224c82c28b3c1d7d8855f379f7..f7e172051fc80ace337243001e86ab05e2402c58 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1703,
 /**/
     1702,
 /**/