]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0007: no support for double, dotted and dashed underlines v9.0.0007
authorBram Moolenaar <Bram@vim.org>
Wed, 29 Jun 2022 17:39:11 +0000 (18:39 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 29 Jun 2022 17:39:11 +0000 (18:39 +0100)
Problem:    No support for double, dotted and dashed underlines.
Solution:   Add the termcap entries and highlight modes. (closes #9553)

16 files changed:
runtime/doc/options.txt
runtime/doc/syntax.txt
runtime/doc/term.txt
src/evalfunc.c
src/gui.c
src/hardcopy.c
src/highlight.c
src/optiondefs.h
src/screen.c
src/term.c
src/termdefs.h
src/testdir/test_highlight.vim
src/testdir/test_options.vim
src/testdir/test_syn_attr.vim
src/version.c
src/vim.h

index 84ab1fb8b95274ad1aa24949b791e19d737f89f9..1d14c44333746b4a11b30027a05383fb98cc6334 100644 (file)
@@ -4211,7 +4211,10 @@ A jump table for the options with a short description can be found at |Q_op|.
                b       bold            (termcap entry "md" and "me")
                s       standout        (termcap entry "so" and "se")
                u       underline       (termcap entry "us" and "ue")
-               c       undercurl       (termcap entry "Cs" and "Ce")
+               c       undercurl       (termcap entry "Us" and "Ce")
+               2       double underline (termcap entry "Ds" and "Ce")
+               d       dotted underline (termcap entry "ds" and "Ce")
+               =       dashed underline (termcap entry "Ds" and "Ce")
                t       strikethrough   (termcap entry "Ts" and "Te")
                n       no highlighting
                -       no highlighting
index c3d677769dd3e36bb8da0b9d5bfca9b90bef2b01..1229b19084b7600cd94a9540f4187cfd25cf54a4 100644 (file)
@@ -5002,14 +5002,18 @@ the same syntax file on all terminals, and use the optimal highlighting.
 1. highlight arguments for normal terminals
 
                                        *bold* *underline* *undercurl*
-                                       *inverse* *italic* *standout*
-                                       *nocombine* *strikethrough*
+                                       *underdouble* *underdotted*
+                                       *underdashed* *inverse* *italic*
+                                       *standout* *nocombine* *strikethrough*
 term={attr-list}                       *attr-list* *highlight-term* *E418*
        attr-list is a comma-separated list (without spaces) of the
        following items (in any order):
                bold
                underline
                undercurl       not always available
+               underdouble     not always available
+               underdotted     not always available
+               underdashed     not always available
                strikethrough   not always available
                reverse
                inverse         same as reverse
@@ -5020,6 +5024,7 @@ term={attr-list}                  *attr-list* *highlight-term* *E418*
 
        Note that "bold" can be used here and by using a bold font.  They
        have the same effect.
+                                                       *underline-codes*
        "undercurl" is a curly underline.  When "undercurl" is not possible
        then "underline" is used.  In general "undercurl" and "strikethrough"
        are only available in the GUI and some terminals.  The color is set
@@ -5028,6 +5033,17 @@ term={attr-list}                 *attr-list* *highlight-term* *E418*
            let &t_Cs = "\e[4:3m"
            let &t_Ce = "\e[4:0m"
 
+<      "underdouble" is a double underline, "underdotted" is a dotted
+       underline and "underdashed" is a dashed underline.  These are only
+       supported by some terminals.  If your terminal supports them you may
+       have to specify the codes like this: >
+           let &t_Us = "\e[4:2m"
+           let &t_ds = "\e[4:4m"
+           let &t_Ds = "\e[4:5m"
+<      They are reset with |t_Ce|, the same as curly underline (undercurl).
+       When t_Us, t_ds or t_Ds is not set then underline will be used as a
+       fallback.
+
 
 start={term-list}                              *highlight-start* *E422*
 stop={term-list}                               *term-list* *highlight-stop*
index f1034057282e566cfcd28f2631aee1290844042b..c4199c2db97ad63f5ba1c46c05413fdac04a51d4 100644 (file)
@@ -372,8 +372,11 @@ OUTPUT CODES                                               *terminal-output-codes*
 
 Added by Vim (there are no standard codes for these):
        t_AU    set underline color (ANSI)                      *t_AU* *'t_AU'*
-       t_Ce    undercurl end                                   *t_Ce* *'t_Ce'*
-       t_Cs    undercurl mode                                  *t_Cs* *'t_Cs'*
+       t_Ce    undercurl and underline end                     *t_Ce* *'t_Ce'*
+       t_Cs    undercurl (curly underline) mode                *t_Cs* *'t_Cs'*
+       t_Us    double underline mode                           *t_Us* *'t_Us'*
+       t_ds    dotted underline mode                           *t_ds* *'t_ds'*
+       t_Ds    dashed underline mode                           *t_Ds* *'t_Ds'*
        t_Te    strikethrough end                               *t_Te* *'t_Te'*
        t_Ts    strikethrough mode                              *t_Ts* *'t_Ts'*
        t_IS    set icon text start                             *t_IS* *'t_IS'*
index 0b8fd43966dab23ecd9feb84156a5da430a47982..f51aade495d017dea9fda54479fa544f925bc9b9 100644 (file)
@@ -10104,14 +10104,27 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
                break;
 
        case 'u':
-               if (TOLOWER_ASC(what[1]) == 'l')        // ul
-                   p = highlight_color(id, what, modec);
-               else if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
+               if (STRLEN(what) >= 9)
+               {
+                   if (TOLOWER_ASC(what[5]) == 'l')
                                                        // underline
-                   p = highlight_has_attr(id, HL_UNDERLINE, modec);
-               else
+                       p = highlight_has_attr(id, HL_UNDERLINE, modec);
+                   else if (TOLOWER_ASC(what[5]) != 'd')
                                                        // undercurl
-                   p = highlight_has_attr(id, HL_UNDERCURL, modec);
+                       p = highlight_has_attr(id, HL_UNDERCURL, modec);
+                   else if (TOLOWER_ASC(what[6]) != 'o')
+                                                       // underdashed
+                       p = highlight_has_attr(id, HL_UNDERDASHED, modec);
+                   else if (TOLOWER_ASC(what[7]) == 'u')
+                                                       // underdouble
+                       p = highlight_has_attr(id, HL_UNDERDOUBLE, modec);
+                   else
+                                                       // underdotted
+                       p = highlight_has_attr(id, HL_UNDERDOTTED, modec);
+               }
+               else
+                                                       // ul
+                   p = highlight_color(id, what, modec);
                break;
     }
 
index e708a27763265d15104b06f216332e7043d38ced..d7e768f31919d091e4e76aefe703ab661bba4c1c 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -2501,6 +2501,8 @@ gui_outstr_nowrap(
     if (hl_mask_todo & HL_UNDERCURL)
        draw_flags |= DRAW_UNDERC;
 
+    // TODO: HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED
+
     // Do we strikethrough the text?
     if (hl_mask_todo & HL_STRIKETHROUGH)
        draw_flags |= DRAW_STRIKE;
index e2e52116248217b80d76a036fde8269c1503af69..dd1f2e071e14b130b6a322bcfd09a344a1a82de4 100644 (file)
@@ -293,6 +293,7 @@ prt_get_attr(
     pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
     pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
     pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
+    // TODO: HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED
 
 # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
     if (USE_24BIT)
index bf876d16f117ce53a56fbadc5024c603c5d9d072..575451e7053a837fb4dcf32c39cd701d55814b10 100644 (file)
  * following names, separated by commas (but no spaces!).
  */
 static char *(hl_name_table[]) =
-    {"bold", "standout", "underline", "undercurl",
-      "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
+    {"bold", "standout", "underline",
+       "undercurl", "underdouble", "underdotted", "underdashed",
+       "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
 static int hl_attr_table[] =
-    {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
+    {HL_BOLD, HL_STANDOUT, HL_UNDERLINE,
+       HL_UNDERCURL, HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED,
+       HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
+// length of all attribute names, plus commas, together (and a bit more)
+#define MAX_ATTR_LEN 120
+
 #define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? (attr_b) : (attr_a)) | (attr_b))
 
 /*
@@ -2963,7 +2969,7 @@ highlight_list_arg(
     char_u     *sarg,
     char       *name)
 {
-    char_u     buf[100];
+    char_u     buf[MAX_ATTR_LEN];
     char_u     *ts;
     int                i;
 
@@ -2984,8 +2990,8 @@ highlight_list_arg(
                if (iarg & hl_attr_table[i])
                {
                    if (buf[0] != NUL)
-                       vim_strcat(buf, (char_u *)",", 100);
-                   vim_strcat(buf, (char_u *)hl_name_table[i], 100);
+                       vim_strcat(buf, (char_u *)",", MAX_ATTR_LEN);
+                   vim_strcat(buf, (char_u *)hl_name_table[i], MAX_ATTR_LEN);
                    iarg &= ~hl_attr_table[i];      // don't want "inverse"
                }
            }
@@ -3287,7 +3293,8 @@ set_hl_attr(
        at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg);
        // Only use the underline/undercurl color when used, it may clear the
        // background color if not supported.
-       if (sgp->sg_cterm & (HL_UNDERLINE | HL_UNDERCURL))
+       if (sgp->sg_cterm & (HL_UNDERLINE | HL_UNDERCURL
+                          | HL_UNDERDOUBLE | HL_UNDERDOTTED | HL_UNDERDASHED))
            at_en.ae_u.cterm.ul_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_sp);
        else
            at_en.ae_u.cterm.ul_rgb = INVALCOLOR;
@@ -3801,6 +3808,12 @@ highlight_changed(void)
                                break;
                    case 'c':   attr |= HL_UNDERCURL;
                                break;
+                   case '2':   attr |= HL_UNDERDOUBLE;
+                               break;
+                   case 'd':   attr |= HL_UNDERDOTTED;
+                               break;
+                   case '=':   attr |= HL_UNDERDASHED;
+                               break;
                    case 't':   attr |= HL_STRIKETHROUGH;
                                break;
                    case ':':   ++p;                // highlight group name
@@ -4362,9 +4375,9 @@ hlg_add_or_update(dict_T *dict)
 {
     char_u     *name;
     int                error;
-    char_u     term_attr[80];
-    char_u     cterm_attr[80];
-    char_u     gui_attr[80];
+    char_u     term_attr[MAX_ATTR_LEN];
+    char_u     cterm_attr[MAX_ATTR_LEN];
+    char_u     gui_attr[MAX_ATTR_LEN];
     char_u     *start;
     char_u     *stop;
     char_u     *ctermfg;
index aca373755015fffc67bed1a86386d5fd8f145a1b..03e472ff9e312d011bca1649b19d41ac19efb9e3 100644 (file)
@@ -2893,9 +2893,9 @@ static struct vimoption options[] =
     p_term("t_BD", T_BD)
     p_term("t_cd", T_CD)
     p_term("t_ce", T_CE)
+    p_term("t_Ce", T_UCE)
     p_term("t_cl", T_CL)
     p_term("t_cm", T_CM)
-    p_term("t_Ce", T_UCE)
     p_term("t_Co", T_CCO)
     p_term("t_CS", T_CCS)
     p_term("t_Cs", T_UCS)
@@ -2905,6 +2905,8 @@ static struct vimoption options[] =
     p_term("t_db", T_DB)
     p_term("t_DL", T_CDL)
     p_term("t_dl", T_DL)
+    p_term("t_ds", T_DS)
+    p_term("t_Ds", T_CDS)
     p_term("t_EC", T_CEC)
     p_term("t_EI", T_CEI)
     p_term("t_fs", T_FS)
@@ -2952,6 +2954,7 @@ static struct vimoption options[] =
     p_term("t_u7", T_U7)
     p_term("t_ue", T_UE)
     p_term("t_us", T_US)
+    p_term("t_Us", T_USS)
     p_term("t_ut", T_UT)
     p_term("t_vb", T_VB)
     p_term("t_ve", T_VE)
index 82a0e91ddca958d9e48a8963c880784ab2a1ddaa..01518882f29b45b62b3589d4b28289e11b84a55f 100644 (file)
@@ -1855,8 +1855,17 @@ screen_start_highlight(int attr)
                out_str(T_SO);
            if ((attr & HL_UNDERCURL) && *T_UCS != NUL) // undercurl
                out_str(T_UCS);
-           if (((attr & HL_UNDERLINE)      // underline or undercurl
-                       || ((attr & HL_UNDERCURL) && *T_UCS == NUL))
+           if ((attr & HL_UNDERDOUBLE) && *T_USS != NUL) // double underline
+               out_str(T_USS);
+           if ((attr & HL_UNDERDOTTED) && *T_DS != NUL) // dotted underline
+               out_str(T_DS);
+           if ((attr & HL_UNDERDASHED) && *T_CDS != NUL) // dashed underline
+               out_str(T_CDS);
+           if (((attr & HL_UNDERLINE)      // underline or undercurl, etc.
+                       || ((attr & HL_UNDERCURL) && *T_UCS == NUL)
+                       || ((attr & HL_UNDERDOUBLE) && *T_USS == NUL)
+                       || ((attr & HL_UNDERDOTTED) && *T_DS == NUL)
+                       || ((attr & HL_UNDERDASHED) && *T_CDS == NUL))
                    && *T_US != NUL)
                out_str(T_US);
            if ((attr & HL_ITALIC) && *T_CZH != NUL)    // italic
@@ -1951,6 +1960,8 @@ screen_stop_highlight(void)
        else
 #endif
        {
+           int is_under;
+
            if (screen_attr > HL_ALL)                   // special HL attr.
            {
                attrentry_T *aep;
@@ -2030,15 +2041,16 @@ screen_stop_highlight(void)
                else
                    out_str(T_SE);
            }
-           if ((screen_attr & HL_UNDERCURL) && *T_UCE != NUL)
+           is_under = (screen_attr & (HL_UNDERCURL
+                         | HL_UNDERDOUBLE | HL_UNDERDOTTED | HL_UNDERDASHED));
+           if (is_under && *T_UCE != NUL)
            {
                if (STRCMP(T_UCE, T_ME) == 0)
                    do_ME = TRUE;
                else
                    out_str(T_UCE);
            }
-           if ((screen_attr & HL_UNDERLINE)
-                           || ((screen_attr & HL_UNDERCURL) && *T_UCE == NUL))
+           if ((screen_attr & HL_UNDERLINE) || (is_under && *T_UCE == NUL))
            {
                if (STRCMP(T_UE, T_ME) == 0)
                    do_ME = TRUE;
index b365831146d1749613d8503f6cee68ac9b8f9354..754ef822d8e8283f8b03039e72e6a44abcb7000d 100644 (file)
@@ -1187,6 +1187,9 @@ static struct builtin_term builtin_termcaps[] =
     {(int)KS_US,       "[US]"},
     {(int)KS_UCE,      "[UCE]"},
     {(int)KS_UCS,      "[UCS]"},
+    {(int)KS_USS,      "[USS]"},
+    {(int)KS_DS,       "[DS]"},
+    {(int)KS_CDS,      "[CDS]"},
     {(int)KS_STE,      "[STE]"},
     {(int)KS_STS,      "[STS]"},
     {(int)KS_MS,       "[MS]"},
@@ -1669,6 +1672,7 @@ get_term_entries(int *height, int *width)
                        {KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
                        {KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
                        {KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
+                       {KS_USS, "Us"}, {KS_DS, "ds"}, {KS_CDS, "Ds"},
                        {KS_STE,"Te"}, {KS_STS,"Ts"},
                        {KS_CM, "cm"}, {KS_SR, "sr"},
                        {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
index a3d8299990b4c28752fb78a1231e626539787140..133641b5c0033fd59cca28bae418cf053439ec5c 100644 (file)
@@ -55,6 +55,9 @@ enum SpecialKey
     KS_US,     // underscore (underline) mode
     KS_UCE,    // exit undercurl mode
     KS_UCS,    // undercurl mode
+    KS_USS,    // double underline mode
+    KS_DS,     // dotted underline mode
+    KS_CDS,    // dashed underline mode
     KS_STE,    // exit strikethrough mode
     KS_STS,    // strikethrough mode
     KS_MS,     // save to move cur in reverse mode
@@ -160,6 +163,9 @@ extern char_u *(term_strings[]);    // current terminal strings
 #define T_US   (TERM_STR(KS_US))       // underscore (underline) mode
 #define T_UCE  (TERM_STR(KS_UCE))      // exit undercurl mode
 #define T_UCS  (TERM_STR(KS_UCS))      // undercurl mode
+#define T_USS  (TERM_STR(KS_USS))      // double underline mode
+#define T_DS   (TERM_STR(KS_DS))       // dotted underline mode
+#define T_CDS  (TERM_STR(KS_CDS))      // dashed underline mode
 #define T_STE  (TERM_STR(KS_STE))      // exit strikethrough mode
 #define T_STS  (TERM_STR(KS_STS))      // strikethrough mode
 #define T_MS   (TERM_STR(KS_MS))       // save to move cur in reverse mode
index 3400052a7cd0bbc72fb6fe1d9d7ca2fa04a7dc4e..ef9c70e7e93e9c51fb00af4a55c507eb8bba3950 100644 (file)
@@ -888,8 +888,8 @@ endfunc
 
 " Test for setting various 'term' attributes
 func Test_highlight_term_attr()
-  hi HlGrp3 term=bold,underline,undercurl,strikethrough,reverse,italic,standout
-  call assert_equal('hi HlGrp3          term=bold,standout,underline,undercurl,italic,reverse,strikethrough', HighlightArgs('HlGrp3'))
+  hi HlGrp3 term=bold,underline,undercurl,underdouble,underdotted,underdashed,strikethrough,reverse,italic,standout
+  call assert_equal('hi HlGrp3          term=bold,standout,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,strikethrough', HighlightArgs('HlGrp3'))
   hi HlGrp3 term=NONE
   call assert_equal('hi HlGrp3          cleared', HighlightArgs('HlGrp3'))
   hi clear
@@ -1174,12 +1174,14 @@ func Test_hlset()
   " Test for setting all the 'term', 'cterm' and 'gui' attributes of a
   " highlight group
   let lines =<< trim END
-    VAR attr = {'bold': v:true, 'underline': v:true, 'undercurl': v:true,
+    VAR attr = {'bold': v:true, 'underline': v:true,
+                \ 'undercurl': v:true, 'underdouble': v:true,
+                \ 'underdotted': v:true, 'underdashed': v:true,
                 \ 'strikethrough': v:true, 'reverse': v:true, 'italic': v:true,
                 \ 'standout': v:true, 'nocombine': v:true}
     call hlset([{'name': 'myhlg2', 'term': attr, 'cterm': attr, 'gui': attr}])
     VAR id2 = hlID('myhlg2')
-    VAR expected = "myhlg2 xxx term=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough cterm=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough gui=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough"
+    VAR expected = "myhlg2 xxx term=bold,standout,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,nocombine,strikethrough cterm=bold,standout,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,nocombine,strikethrough gui=bold,standout,underline,undercurl,underdouble,underdotted,underdashed,italic,reverse,nocombine,strikethrough"
     VAR output = execute('highlight myhlg2')
     LET output = output->split("\n")->join()->substitute('\s\+', ' ', 'g')
     call assert_equal(expected, output)
index 0a533152b9cde36e672f53e8a67fa25f3f10da31..fbe592d16519f52c7373553611bff161d2ad10c3 100644 (file)
@@ -955,6 +955,18 @@ func Test_opt_set_keycode()
   set <F9>=xyz
   call assert_equal('xyz', &t_k9)
   set <t_k9>&
+
+  " should we test all of them?
+  set t_Ce=testCe
+  set t_Cs=testCs
+  set t_Us=testUs
+  set t_ds=testds
+  set t_Ds=testDs
+  call assert_equal('testCe', &t_Ce)
+  call assert_equal('testCs', &t_Cs)
+  call assert_equal('testUs', &t_Us)
+  call assert_equal('testds', &t_ds)
+  call assert_equal('testDs', &t_Ds)
 endfunc
 
 " Test for changing options in a sandbox
index db9c9e93af1b72966ed8832db0e020c4da301eee..366f39f46885386989bacd4d6e7c3cd9e7692dad 100644 (file)
@@ -11,10 +11,17 @@ func Test_missing_attr()
   hi Mine term=reverse cterm=inverse
   call assert_equal('1', synIDattr(hlID("Mine"), "reverse", 'term'))
   call assert_equal('1', synIDattr(hlID("Mine"), "inverse", 'cterm'))
+
   hi Mine term=underline cterm=standout gui=undercurl
   call assert_equal('1', synIDattr(hlID("Mine"), "underline", 'term'))
   call assert_equal('1', synIDattr(hlID("Mine"), "standout", 'cterm'))
   call assert_equal('1', synIDattr("Mine"->hlID(), "undercurl", 'gui'))
+
+  hi Mine term=underdouble cterm=underdotted gui=underdashed
+  call assert_equal('1', synIDattr(hlID("Mine"), "underdouble", 'term'))
+  call assert_equal('1', synIDattr(hlID("Mine"), "underdotted", 'cterm'))
+  call assert_equal('1', synIDattr("Mine"->hlID(), "underdashed", 'gui'))
+
   hi Mine gui=strikethrough
   call assert_equal('1', synIDattr(hlID("Mine"), "strikethrough", 'gui'))
   hi Mine term=NONE cterm=NONE gui=NONE
index 98227fa445c4594d6642a0ba86174bd5e00a3792..e6255059d661627922e32cf974b82f1c18e7e6b2 100644 (file)
@@ -735,6 +735,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    7,
 /**/
     6,
 /**/
index 97ce6390ebb400ec9784582da103644b066e4d21..a4da18505ccd8cbcb4fffb12e223d1d17019689c 100644 (file)
--- a/src/vim.h
+++ b/src/vim.h
@@ -659,10 +659,13 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
 #define HL_ITALIC              0x04
 #define HL_UNDERLINE           0x08
 #define HL_UNDERCURL           0x10
-#define HL_STANDOUT            0x20
-#define HL_NOCOMBINE           0x40
-#define HL_STRIKETHROUGH       0x80
-#define HL_ALL                 0xff
+#define HL_UNDERDOUBLE         0x20
+#define HL_UNDERDOTTED         0x40
+#define HL_UNDERDASHED         0x80
+#define HL_STANDOUT            0x100
+#define HL_NOCOMBINE           0x200
+#define HL_STRIKETHROUGH       0x400
+#define HL_ALL                 0x7ff
 
 // special attribute addition: Put message in history
 #define MSG_HIST               0x1000