>From a8192dcb7ec91f1b593de723f722d6ba74ba171f Mon Sep 17 00:00:00 2001 From: Brand Huntsman Date: Mon, 29 Jan 2018 17:13:31 -0700 Subject: [PATCH 2/2] bold, italic, reverse and underline attributes Change bright prefix to only brighten colors. Use the following command to convert old syntax files. sed -i 's/color bright/color bold,/' *.nanorc Signed-off-by: Brand Huntsman --- src/color.c | 11 +++-- src/nano.h | 2 - src/proto.h | 2 +- src/rcfile.c | 126 ++++++++++++++++++++++++++++++++++++++++++--------- syntax/nanorc.nanorc | 4 +- 5 files changed, 114 insertions(+), 31 deletions(-) diff --git a/src/color.c b/src/color.c index 108af9f8..b4bcfa9d 100644 --- a/src/color.c +++ b/src/color.c @@ -66,8 +66,9 @@ void set_colorpairs(void) if (combo->bg == -1 && !using_defaults) combo->bg = COLOR_BLACK; init_pair(i + 1, combo->fg, combo->bg); - interface_color_pair[i] = COLOR_PAIR(i + 1) | A_BANDAID | - (combo->bright ? A_BOLD : A_NORMAL); + interface_color_pair[i] = COLOR_PAIR(i + 1) + | combo->attributes + | A_BANDAID; } else { if (i != FUNCTION_TAG) interface_color_pair[i] = hilite_attribute; @@ -89,7 +90,8 @@ void set_colorpairs(void) while (beforenow != ink && (beforenow->fg != ink->fg || beforenow->bg != ink->bg || - beforenow->bright != ink->bright)) + (beforenow->attributes & 0xFFFF0000) != + ink->attributes)) beforenow = beforenow->next; if (beforenow != ink) @@ -97,8 +99,7 @@ void set_colorpairs(void) else ink->pairnum = new_number++; - ink->attributes = COLOR_PAIR(ink->pairnum) | A_BANDAID | - (ink->bright ? A_BOLD : A_NORMAL); + ink->attributes |= COLOR_PAIR(ink->pairnum) | A_BANDAID; } } } diff --git a/src/nano.h b/src/nano.h index 92f8e296..b3a9b631 100644 --- a/src/nano.h +++ b/src/nano.h @@ -182,8 +182,6 @@ typedef struct colortype { /* This syntax's foreground color. */ short bg; /* This syntax's background color. */ - bool bright; - /* Is this color A_BOLD? */ int pairnum; /* The color pair number used for this foreground color and * background color. */ diff --git a/src/proto.h b/src/proto.h index c575a7a1..ab2fe0d3 100644 --- a/src/proto.h +++ b/src/proto.h @@ -473,7 +473,7 @@ int do_yesno_prompt(bool all, const char *msg); /* Most functions in rcfile.c. */ #ifdef ENABLE_NANORC #ifdef ENABLE_COLOR -bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright); +bool parse_color_names(char *combostr, short *fg, short *bg, int *attributes); void grab_and_store(const char *kind, char *ptr, regexlisttype **storage); #endif void parse_rcfile(FILE *rcstream, bool syntax_only); diff --git a/src/rcfile.c b/src/rcfile.c index ddfbd003..59942457 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -570,10 +570,12 @@ void parse_includes(char *ptr) } /* Return the short value corresponding to the color named in colorname, - * and set bright to TRUE if that color is bright. */ + * and set bright to TRUE if that color has bright prefix. */ short color_to_short(const char *colorname, bool *bright) { if (strncasecmp(colorname, "bright", 6) == 0) { + /* The bright foreground prefix makes the color bright without + * bolding it. It bolds on terminals with only 8 colors. */ *bright = TRUE; colorname += 6; } else @@ -606,7 +608,7 @@ short color_to_short(const char *colorname, bool *bright) void parse_colors(char *ptr, int rex_flags) { short fg, bg; - bool bright; + int attributes; char *item; if (!opensyntax) { @@ -622,7 +624,7 @@ void parse_colors(char *ptr, int rex_flags) item = ptr; ptr = parse_next_word(ptr); - if (!parse_color_names(item, &fg, &bg, &bright)) + if (!parse_color_names(item, &fg, &bg, &attributes)) return; if (*ptr == '\0') { @@ -669,7 +671,7 @@ void parse_colors(char *ptr, int rex_flags) newcolor->fg = fg; newcolor->bg = bg; - newcolor->bright = bright; + newcolor->attributes = attributes; newcolor->rex_flags = rex_flags; newcolor->start_regex = mallocstrcpy(NULL, item); @@ -727,29 +729,111 @@ void parse_colors(char *ptr, int rex_flags) } } -/* Parse the color name, or pair of color names, in combostr. */ -bool parse_color_names(char *combostr, short *fg, short *bg, bool *bright) +static char *find_next_comma_word(char *prev_word) { - char *comma = strchr(combostr, ','); + if (prev_word == NULL) + return NULL; + char *comma = strchr(prev_word, ','); if (comma != NULL) { - *bg = color_to_short(comma + 1, bright); - if (*bright) { - rcfile_error(N_("A background color cannot be bright")); - return FALSE; - } *comma = '\0'; - } else - *bg = -1; + return comma + 1; + } - if (comma != combostr) { - *fg = color_to_short(combostr, bright); + /* No comma was found. */ + return NULL; +} - /* If the specified foreground color is bad, ignore the regexes. */ - if (*fg == -1) - return FALSE; - } else +/* Parse the color name, or pair of color names, in combostr. */ +bool parse_color_names(char *combostr, short *fg, short *bg, int *attributes) +{ + char *word = combostr; + char *next_word = find_next_comma_word(combostr); + + *attributes = A_NORMAL; + + /* Get attributes. */ + while (word != NULL) { + if (strcasecmp(word, "bold") == 0) { + /* The bold attribute makes the color bold and bright, + * or only bright on terminals without bold support, + * or only bold for extended colors. */ + if (*attributes & A_BOLD) + rcfile_error(N_("A color should not use the same attribute more than once")); + *attributes |= A_BOLD; + } else if (strcasecmp(word, "italic") == 0) { + /* The italic attribute makes the color italic + * on terminals with italic support and an italic capable font. */ + #ifdef A_ITALIC + if (*attributes & A_ITALIC) + rcfile_error(N_("A color should not use the same attribute more than once")); + *attributes |= A_ITALIC; + #else + rcfile_error(N_("The italic color attribute requires ncurses >= 6.0")); + #endif + } else if (strcasecmp(word, "reverse") == 0) { + /* The reverse attribute swaps the foreground and background colors. + * Useful when default background color is needed. + * Example: color reverse,blue */ + if (*attributes & A_REVERSE) + rcfile_error(N_("A color should not use the same attribute more than once")); + *attributes |= A_REVERSE; + } else if (strcasecmp(word, "underline") == 0) { + /* The underline attribute makes the color underlined. */ + if (*attributes & A_UNDERLINE) + rcfile_error(N_("A color should not use the same attribute more than once")); + *attributes |= A_UNDERLINE; + } else + break; + + word = next_word; + next_word = find_next_comma_word(word); + } + + /* Get foreground color. */ + if (word != NULL) { + if (*word != '\0') { + bool fg_bright; + *fg = color_to_short(word, &fg_bright); + + /* If the specified foreground color is bad, ignore the regexes. */ + if (*fg == -1) + return FALSE; + + if (fg_bright) { + if (*attributes & A_BOLD) + rcfile_error(N_("A foreground color should not be bright with bold attribute")); + + /* A bright foreground on 8-color is A_BOLD to brighten it. */ + if (nr_term_colors > 8) + *fg += 8; + else + *attributes |= A_BOLD; + } + } else + *fg = -1; + + word = next_word; + next_word = find_next_comma_word(word); + + /* Get background color. */ + if (word != NULL && *word != '\0') { + bool bg_bright; + *bg = color_to_short(word, &bg_bright); + + if (bg_bright) { + rcfile_error(N_("A background color cannot be bright")); + return FALSE; + } + /* It is possible to have a bright background by adding 8 to it. + * But "red,brightred" becomes "red,red" on 8-color. + * Use "reverse,brightred,red" for a similar result. */ + } else + *bg = -1; + } else { *fg = -1; + *bg = -1; + } return TRUE; } @@ -759,7 +843,7 @@ colortype *parse_interface_color(char *combostr) { colortype *trio = nmalloc(sizeof(colortype)); - if (parse_color_names(combostr, &trio->fg, &trio->bg, &trio->bright)) { + if (parse_color_names(combostr, &trio->fg, &trio->bg, &trio->attributes)) { free(combostr); return trio; } else { diff --git a/syntax/nanorc.nanorc b/syntax/nanorc.nanorc index 9882d6b0..aa5020ba 100644 --- a/syntax/nanorc.nanorc +++ b/syntax/nanorc.nanorc @@ -8,7 +8,7 @@ icolor brightred "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comm # Keywords icolor brightgreen "^[[:space:]]*(set|unset)[[:space:]]+(allow_insecure_backup|atblanks|autoindent|backup|backwards|boldtext|casesensitive|constantshow|cutfromcursor|fill[[:space:]]+-?[[:digit:]]+|historylog|linenumbers|locking|morespace|mouse|multibuffer|noconvert|nohelp|nopauses|nonewlines|nowrap|positionlog|preserve|quickblank|quiet|rebinddelete|rebindkeypad|regexp|showcursor|smarthome|smooth|softwrap|suspend|tabsize[[:space:]]+[1-9][0-9]*|tabstospaces|tempfile|trimblanks|unix|view|wordbounds)\>" -icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|selected|status|title)color)[[:space:]]+(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>" +icolor yellow "^[[:space:]]*set[[:space:]]+((function|key|number|selected|status|title)color)[[:space:]]+((bold|italic|reverse|underline)(,(bold|italic|reverse|underline))*|((bold|italic|reverse|underline),)*((bright)?(white|black|red|blue|green|yellow|magenta|cyan))?(,(white|black|red|blue|green|yellow|magenta|cyan))?)\>" icolor brightgreen "^[[:space:]]*set[[:space:]]+(backupdir|brackets|functioncolor|keycolor|matchbrackets|numbercolor|operatingdir|punct|quotestr|selectedcolor|speller|statuscolor|titlecolor|whitespace|wordchars)[[:space:]]+" icolor brightgreen "^[[:space:]]*bind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>address@hidden|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+[[:alpha:]]+[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)" icolor brightgreen "^[[:space:]]*unbind[[:space:]]+((\^([[:alpha:]]|[]0-9\^_]|Space)|M-([[:alpha:]]|[]!"#$%&'()*+,./0-9:;<=>address@hidden|}~-]|Space))|F([1-9]|1[0-6])|Ins|Del)[[:space:]]+(all|main|search|replace(with)?|gotoline|writeout|insert|ext(ernal)?cmd|help|spell|linter|browser|whereisfile|gotodir)([[:space:]]+#|[[:space:]]*$)" @@ -20,7 +20,7 @@ icolor green "^[[:space:]]*((un)?(bind|set)|include|syntax|header|magic|comment| color brightmagenta "".+"([[:space:]]|$)" # Colors -icolor yellow "^[[:space:]]*i?color[[:space:]]*(bright)?(white|black|red|blue|green|yellow|magenta|cyan)?(,(white|black|red|blue|green|yellow|magenta|cyan))?\>" +icolor yellow "^[[:space:]]*i?color[[:space:]]+((bold|italic|reverse|underline)(,(bold|italic|reverse|underline))*|((bold|italic|reverse|underline),)*((bright)?(white|black|red|blue|green|yellow|magenta|cyan))?(,(white|black|red|blue|green|yellow|magenta|cyan))?)\>" icolor magenta "^[[:space:]]*i?color\>" "\<(start|end)=" # Comments -- 2.13.6