diff options
author | Drew Vogel <dvogel@github> | 2021-10-24 20:35:07 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-10-24 20:35:07 +0100 |
commit | e30d10253fa634c4f60daa798d029245f4eed393 (patch) | |
tree | 57aca74b65dc4c3924ef23185b8cb2b6933996c2 /src | |
parent | 3c5904d2a5d7861c227a4c3cd4ddcbc51014c838 (diff) |
patch 8.2.3562: cannot add color namesv8.2.3562
Problem: Cannot add color names.
Solution: Add the v:colornames dictionary. (Drew Vogel, closes #8761)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 11 | ||||
-rw-r--r-- | src/errors.h | 6 | ||||
-rw-r--r-- | src/evalvars.c | 3 | ||||
-rw-r--r-- | src/globals.h | 3 | ||||
-rw-r--r-- | src/gui.c | 2 | ||||
-rw-r--r-- | src/gui_haiku.cc | 159 | ||||
-rw-r--r-- | src/highlight.c | 233 | ||||
-rw-r--r-- | src/job.c | 2 | ||||
-rw-r--r-- | src/proto/highlight.pro | 6 | ||||
-rw-r--r-- | src/proto/term.pro | 2 | ||||
-rw-r--r-- | src/term.c | 199 | ||||
-rw-r--r-- | src/testdir/test_highlight.vim | 36 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 3 |
14 files changed, 292 insertions, 375 deletions
diff --git a/src/Makefile b/src/Makefile index 32411d0b88..e5953afdbd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1136,9 +1136,6 @@ SYS_DELMENU_FILE = $(DESTDIR)$(SCRIPTLOC)/delmenu.vim ### Name of the bugreport file target. SYS_BUGR_FILE = $(DESTDIR)$(SCRIPTLOC)/bugreport.vim -### Name of the rgb.txt file target. -SYS_RGB_FILE = $(DESTDIR)$(SCRIPTLOC)/rgb.txt - ### Name of the file type detection file target. SYS_FILETYPE_FILE = $(DESTDIR)$(SCRIPTLOC)/filetype.vim @@ -2449,9 +2446,6 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \ chmod $(VIMSCRIPTMOD) $(EVIM_FILE) $(INSTALL_DATA) $(SCRIPTSOURCE)/mswin.vim $(MSWIN_FILE) chmod $(VIMSCRIPTMOD) $(MSWIN_FILE) -# install the rgb.txt file - $(INSTALL_DATA) $(SCRIPTSOURCE)/rgb.txt $(SYS_RGB_FILE) - chmod $(VIMSCRIPTMOD) $(SYS_RGB_FILE) # install the bugreport file $(INSTALL_DATA) $(SCRIPTSOURCE)/bugreport.vim $(SYS_BUGR_FILE) chmod $(VIMSCRIPTMOD) $(SYS_BUGR_FILE) @@ -2481,7 +2475,7 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \ cd $(PRINTSOURCE); $(INSTALL_DATA) *.ps $(DEST_PRINT) cd $(DEST_PRINT); chmod $(FILEMOD) *.ps # install the colorscheme files - cd $(COLSOURCE); $(INSTALL_DATA_R) *.vim tools README.txt $(DEST_COL) + cd $(COLSOURCE); $(INSTALL_DATA_R) *.vim lists tools README.txt $(DEST_COL) cd $(DEST_COL); chmod $(DIRMOD) tools cd $(DEST_COL); chmod $(HELPMOD) *.vim README.txt tools/*.vim # install the syntax files @@ -2894,7 +2888,6 @@ uninstall_runtime: -rm -f $(DEST_MAN_RU)/xxd.1 $(DEST_MAN_RU_U)/xxd.1 -rm -f $(DEST_HELP)/*.txt $(DEST_HELP)/tags $(DEST_HELP)/*.pl -rm -f $(DEST_HELP)/*.??x $(DEST_HELP)/tags-?? - -rm -f $(SYS_RGB_FILE) -rm -f $(SYS_MENU_FILE) $(SYS_SYNMENU_FILE) $(SYS_DELMENU_FILE) -rm -f $(SYS_BUGR_FILE) $(VIM_DEFAULTS_FILE) $(EVIM_FILE) $(MSWIN_FILE) -rm -f $(DEST_SCRIPT)/gvimrc_example.vim $(DEST_SCRIPT)/vimrc_example.vim @@ -3666,12 +3659,10 @@ Makefile: # This rule: # - add resources to already installed vim binary to avoid # stripping them during install; -# - copy rgb.txt to runtime directory; # - update system MIME database with info about vim application. # install_haiku_extra: $(DEST_BIN)/$(VIMTARGET) objects/os_haiku.rsrc xres -o $(DEST_BIN)/$(VIMTARGET) objects/os_haiku.rsrc - $(INSTALL_DATA) $(SCRIPTSOURCE)/rgb.txt $(DEST_RT) mimeset $(DEST_BIN)/$(VIMTARGET) # List of g*-links that should be replaced with shell script equivalents. diff --git a/src/errors.h b/src/errors.h index 7778b39602..537072d7d5 100644 --- a/src/errors.h +++ b/src/errors.h @@ -147,6 +147,10 @@ EXTERN char e_no_such_user_defined_command_str[] EXTERN char e_no_digraphs_version[] INIT(= N_("E196: No digraphs in this version")); #endif +#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) +EXTERN char e_cannot_allocate_color_str[] + INIT(= N_("E254: Cannot allocate color %s")); +#endif EXTERN char e_ambiguous_use_of_user_defined_command[] INIT(= N_("E464: Ambiguous use of user-defined command")); EXTERN char e_invalid_command[] @@ -678,3 +682,5 @@ EXTERN char e_no_white_space_allowed_before_separator_str[] INIT(= N_("E1242: No white space allowed before separator: %s")); EXTERN char e_ascii_code_not_in_range[] INIT(= N_("E1243: ASCII code not in 32-127 range")); +EXTERN char e_bad_color_string_str[] + INIT(= N_("E1244: Bad color string: %s")); diff --git a/src/evalvars.c b/src/evalvars.c index fbf2d68d1b..08736dd8c7 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -149,6 +149,7 @@ static struct vimvar {VV_NAME("argv", VAR_LIST), VV_RO}, {VV_NAME("collate", VAR_STRING), VV_RO}, {VV_NAME("exiting", VAR_SPECIAL), VV_RO}, + {VV_NAME("colornames", VAR_DICT), VV_RO}, }; // shorthand @@ -248,6 +249,8 @@ evalvars_init(void) set_vim_var_nr(VV_ECHOSPACE, sc_col - 1); + set_vim_var_dict(VV_COLORNAMES, dict_alloc()); + // Default for v:register is not 0 but '"'. This is adjusted once the // clipboard has been setup by calling reset_reg_var(). set_reg_var(0); diff --git a/src/globals.h b/src/globals.h index 948c35f84f..5c54130ebd 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1774,9 +1774,6 @@ EXTERN char e_nowhitespace[] INIT(= N_("E274: No white space allowed before pare EXTERN char e_lock_unlock[] INIT(= N_("E940: Cannot lock or unlock variable %s")); #endif -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) -EXTERN char e_alloc_color[] INIT(= N_("E254: Cannot allocate color %s")); -#endif EXTERN char e_chan_or_job_req[] INIT(= N_("E706: Channel or Job required")); EXTERN char e_jobreq[] INIT(= N_("E693: Job required")); @@ -4785,7 +4785,7 @@ gui_get_color(char_u *name) && gui.in_use #endif ) - semsg(_(e_alloc_color), name); + semsg(_(e_cannot_allocate_color_str), name); return t; } diff --git a/src/gui_haiku.cc b/src/gui_haiku.cc index 644c2db665..6d973c5656 100644 --- a/src/gui_haiku.cc +++ b/src/gui_haiku.cc @@ -4054,164 +4054,7 @@ guicolor_T gui_mch_get_color( char_u *name) { - typedef struct GuiColourTable - { - const char *name; - guicolor_T colour; - } GuiColourTable; - -#define NSTATIC_COLOURS 50 // 32 -#define NDYNAMIC_COLOURS 33 -#define NCOLOURS (NSTATIC_COLOURS + NDYNAMIC_COLOURS) - - static GuiColourTable table[NCOLOURS] = - { - {"Black", RGB(0x00, 0x00, 0x00)}, - {"DarkGray", RGB(0x80, 0x80, 0x80)}, - {"DarkGrey", RGB(0x80, 0x80, 0x80)}, - {"Gray", RGB(0xC0, 0xC0, 0xC0)}, - {"Grey", RGB(0xC0, 0xC0, 0xC0)}, - {"LightGray", RGB(0xD3, 0xD3, 0xD3)}, - {"LightGrey", RGB(0xD3, 0xD3, 0xD3)}, - {"Gray10", RGB(0x1A, 0x1A, 0x1A)}, - {"Grey10", RGB(0x1A, 0x1A, 0x1A)}, - {"Gray20", RGB(0x33, 0x33, 0x33)}, - {"Grey20", RGB(0x33, 0x33, 0x33)}, - {"Gray30", RGB(0x4D, 0x4D, 0x4D)}, - {"Grey30", RGB(0x4D, 0x4D, 0x4D)}, - {"Gray40", RGB(0x66, 0x66, 0x66)}, - {"Grey40", RGB(0x66, 0x66, 0x66)}, - {"Gray50", RGB(0x7F, 0x7F, 0x7F)}, - {"Grey50", RGB(0x7F, 0x7F, 0x7F)}, - {"Gray60", RGB(0x99, 0x99, 0x99)}, - {"Grey60", RGB(0x99, 0x99, 0x99)}, - {"Gray70", RGB(0xB3, 0xB3, 0xB3)}, - {"Grey70", RGB(0xB3, 0xB3, 0xB3)}, - {"Gray80", RGB(0xCC, 0xCC, 0xCC)}, - {"Grey80", RGB(0xCC, 0xCC, 0xCC)}, - {"Gray90", RGB(0xE5, 0xE5, 0xE5)}, - {"Grey90", RGB(0xE5, 0xE5, 0xE5)}, - {"White", RGB(0xFF, 0xFF, 0xFF)}, - {"DarkRed", RGB(0x80, 0x00, 0x00)}, - {"Red", RGB(0xFF, 0x00, 0x00)}, - {"LightRed", RGB(0xFF, 0xA0, 0xA0)}, - {"DarkBlue", RGB(0x00, 0x00, 0x80)}, - {"Blue", RGB(0x00, 0x00, 0xFF)}, - {"LightBlue", RGB(0xA0, 0xA0, 0xFF)}, - {"DarkGreen", RGB(0x00, 0x80, 0x00)}, - {"Green", RGB(0x00, 0xFF, 0x00)}, - {"LightGreen", RGB(0xA0, 0xFF, 0xA0)}, - {"DarkCyan", RGB(0x00, 0x80, 0x80)}, - {"Cyan", RGB(0x00, 0xFF, 0xFF)}, - {"LightCyan", RGB(0xA0, 0xFF, 0xFF)}, - {"DarkMagenta", RGB(0x80, 0x00, 0x80)}, - {"Magenta", RGB(0xFF, 0x00, 0xFF)}, - {"LightMagenta", RGB(0xFF, 0xA0, 0xFF)}, - {"Brown", RGB(0x80, 0x40, 0x40)}, - {"Yellow", RGB(0xFF, 0xFF, 0x00)}, - {"LightYellow", RGB(0xFF, 0xFF, 0xA0)}, - {"DarkYellow", RGB(0xBB, 0xBB, 0x00)}, - {"SeaGreen", RGB(0x2E, 0x8B, 0x57)}, - {"Orange", RGB(0xFF, 0xA5, 0x00)}, - {"Purple", RGB(0xA0, 0x20, 0xF0)}, - {"SlateBlue", RGB(0x6A, 0x5A, 0xCD)}, - {"Violet", RGB(0xEE, 0x82, 0xEE)}, - // NOTE: some entries are zero-allocated for NDDYNAMIC_COLORS - // in this table! - }; - - static int endColour = NSTATIC_COLOURS; - static int newColour = NSTATIC_COLOURS; - - int r, g, b; - int i; - - if (name[0] == '#' && STRLEN(name) == 7) - { - // Name is in "#rrggbb" format - r = hex_digit(name[1]) * 16 + hex_digit(name[2]); - g = hex_digit(name[3]) * 16 + hex_digit(name[4]); - b = hex_digit(name[5]) * 16 + hex_digit(name[6]); - if (r < 0 || g < 0 || b < 0) - return INVALCOLOR; - return RGB(r, g, b); - } - else - { - // Check if the name is one of the colours we know - for (i = 0; i < endColour; i++) - if (STRICMP(name, table[i].name) == 0) - return table[i].colour; - } - - /* - * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". - */ - { -#define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - return INVALCOLOR; - - while (!feof(fd)) - { - int len; - int pos; - char *colour; - - fgets(line, LINE_LEN, fd); - len = strlen(line); - - if (len <= 1 || line[len-1] != '\n') - continue; - - line[len-1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - colour = line + pos; - - if (STRICMP(colour, name) == 0) - { - fclose(fd); - /* - * Now remember this colour in the table. - * A LRU scheme might be better but this is simpler. - * Or could use a growing array. - */ - guicolor_T gcolour = RGB(r,g,b); - - // NOTE: see note above in table allocation! We are working here with - // dynamically allocated names, not constant ones! - vim_free((char*)table[newColour].name); - table[newColour].name = (char *)vim_strsave((char_u *)colour); - table[newColour].colour = gcolour; - - newColour++; - if (newColour >= NCOLOURS) - newColour = NSTATIC_COLOURS; - if (endColour < NCOLOURS) - endColour = newColour; - - return gcolour; - } - } - - fclose(fd); - } - - return INVALCOLOR; + return gui_get_color_cmn(name); } /* diff --git a/src/highlight.c b/src/highlight.c index 76d9a7e82e..5dde08b8f3 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -475,6 +475,9 @@ load_colors(char_u *name) buf = alloc(STRLEN(name) + 12); if (buf != NULL) { +#ifdef FEAT_EVAL + load_default_colors_lists(); +#endif apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, FALSE, curbuf); sprintf((char *)buf, "colors/%s.vim", name); @@ -1190,7 +1193,7 @@ highlight_set_guibg( HL_TABLE()[idx].sg_set |= SG_GUI; # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) - // In GUI guifg colors are only used when recognized + // In GUI guibg colors are only used when recognized i = color_name2handle(arg); if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) { @@ -2231,6 +2234,234 @@ color_name2handle(char_u *name) return GUI_GET_COLOR(name); } + +// On MS-Windows an RGB macro is available and it produces 0x00bbggrr color +// values as used by the MS-Windows GDI api. It should be used only for +// MS-Windows GDI builds. +# if defined(RGB) && defined(MSWIN) && !defined(FEAT_GUI) +# undef RGB +# endif +# ifndef RGB +# define RGB(r, g, b) ((r<<16) | (g<<8) | (b)) +# endif + +# ifdef VIMDLL + static guicolor_T +gui_adjust_rgb(guicolor_T c) +{ + if (gui.in_use) + return c; + else + return ((c & 0xff) << 16) | (c & 0x00ff00) | ((c >> 16) & 0xff); +} +# else +# define gui_adjust_rgb(c) (c) +# endif + + static int +hex_digit(int c) +{ + if (isdigit(c)) + return c - '0'; + c = TOLOWER_ASC(c); + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0x1ffffff; +} + + guicolor_T +decode_hex_color(char_u *hex) +{ + guicolor_T color; + + if (hex[0] != '#' || STRLEN(hex) != 7) + return INVALCOLOR; + + // Name is in "#rrggbb" format + color = RGB(((hex_digit(hex[1]) << 4) + hex_digit(hex[2])), + ((hex_digit(hex[3]) << 4) + hex_digit(hex[4])), + ((hex_digit(hex[5]) << 4) + hex_digit(hex[6]))); + if (color > 0xffffff) + return INVALCOLOR; + return gui_adjust_rgb(color); +} + +#if defined(FEAT_EVAL) +// Returns the color currently mapped to the given name or INVALCOLOR if no +// such name exists in the color table. The convention is to use lowercase for +// all keys in the v:colornames dictionary. The value can be either a string in +// the form #rrggbb or a number, either of which is converted to a guicolor_T. + guicolor_T +colorname2rgb(char_u *name) +{ + dict_T *colornames_table = get_vim_var_dict(VV_COLORNAMES); + char_u *lc_name; + dictitem_T *colentry; + char_u *colstr; + varnumber_T colnum; + + lc_name = strlow_save(name); + if (lc_name == NULL) + return INVALCOLOR; + + colentry = dict_find(colornames_table, lc_name, -1); + vim_free(lc_name); + if (colentry == NULL) + return INVALCOLOR; + + if (colentry->di_tv.v_type == VAR_STRING) + { + colstr = tv_get_string_strict(&colentry->di_tv); + if ((STRLEN(colstr) == 7) && (*colstr == '#')) + { + return decode_hex_color(colstr); + } + else + { + semsg(_(e_bad_color_string_str), colstr); + return INVALCOLOR; + } + } + + if (colentry->di_tv.v_type == VAR_NUMBER) + { + colnum = tv_get_number(&colentry->di_tv); + return (guicolor_T)colnum; + } + + return INVALCOLOR; +} + +// Maps the given name to the given color value, overwriting any current +// mapping. If allocation fails the named color will no longer exist in the +// table and the user will receive an error message. + void +save_colorname_hexstr(int r, int g, int b, char_u *name) +{ + int result; + dict_T *colornames_table; + dictitem_T *existing; + char_u hexstr[8]; + + if (vim_snprintf((char *)hexstr, sizeof(hexstr), + "#%02x%02x%02x", r, g, b) < 0) + { + semsg(_(e_cannot_allocate_color_str), name); + return; + } + + colornames_table = get_vim_var_dict(VV_COLORNAMES); + // The colornames_table dict is safe to use here because it is allocated at + // startup in evalvars.c + existing = dict_find(colornames_table, name, -1); + if (existing != NULL) + { + dictitem_remove(colornames_table, existing); + existing = NULL; // dictitem_remove freed the item + } + + result = dict_add_string(colornames_table, (char *)name, hexstr); + if (result == FAIL) + semsg(_(e_cannot_allocate_color_str), name); +} + +/* + * Load a default color list. Intended to support legacy color names but allows + * the user to override the color values. Only loaded once. + */ + void +load_default_colors_lists() +{ + // Lacking a default color list isn't the end of the world but it is likely + // an inconvenience so users should know when it is missing. + if (source_runtime((char_u *)"colors/lists/default.vim", DIP_ALL) != OK) + msg("failed to load colors/lists/default.vim"); +} +#endif + + guicolor_T +gui_get_color_cmn(char_u *name) +{ + int i; + guicolor_T color; + + struct rgbcolor_table_S { + char_u *color_name; + guicolor_T color; + }; + + // Only non X11 colors (not present in rgb.txt) and colors in + // color_names[], useful when $VIMRUNTIME is not found,. + static struct rgbcolor_table_S rgb_table[] = { + {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, + {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)}, + {(char_u *)"brown", RGB(0xA5, 0x2A, 0x2A)}, + {(char_u *)"cyan", RGB(0x00, 0xFF, 0xFF)}, + {(char_u *)"darkblue", RGB(0x00, 0x00, 0x8B)}, + {(char_u *)"darkcyan", RGB(0x00, 0x8B, 0x8B)}, + {(char_u *)"darkgray", RGB(0xA9, 0xA9, 0xA9)}, + {(char_u *)"darkgreen", RGB(0x00, 0x64, 0x00)}, + {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)}, + {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)}, + {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)}, + {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, // No X11 + {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)}, + {(char_u *)"green", RGB(0x00, 0xFF, 0x00)}, + {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)}, + {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)}, + {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)}, + {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)}, + {(char_u *)"lightblue", RGB(0xAD, 0xD8, 0xE6)}, + {(char_u *)"lightcyan", RGB(0xE0, 0xFF, 0xFF)}, + {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)}, + {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)}, + {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)}, + {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, // No X11 + {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, // No X11 + {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)}, + {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)}, + {(char_u *)"red", RGB(0xFF, 0x00, 0x00)}, + {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)}, + {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)}, + {(char_u *)"yellow", RGB(0xFF, 0xFF, 0x00)}, + }; + + color = decode_hex_color(name); + if (color != INVALCOLOR) + return color; + + // Check if the name is one of the colors we know + for (i = 0; i < (int)ARRAY_LENGTH(rgb_table); i++) + if (STRICMP(name, rgb_table[i].color_name) == 0) + return gui_adjust_rgb(rgb_table[i].color); + +#if defined(FEAT_EVAL) + /* + * Not a traditional color. Load additional color aliases and then consult the alias table. + */ + + color = colorname2rgb(name); + if (color == INVALCOLOR) + { + load_default_colors_lists(); + color = colorname2rgb(name); + } + + return color; +#else + return INVALCOLOR; +#endif +} + + guicolor_T +gui_get_rgb_color_cmn(int r, int g, int b) +{ + guicolor_T color = RGB(r, g, b); + + if (color > 0xffffff) + return INVALCOLOR; + return gui_adjust_rgb(color); +} #endif /* @@ -559,7 +559,7 @@ get_job_options(typval_T *tv, jobopt_T *opt, int supported, int supported2) { if (called_emsg_before == called_emsg) // may not get the error if the GUI didn't start - semsg(_(e_alloc_color), color_name); + semsg(_(e_cannot_allocate_color_str), color_name); return FAIL; } diff --git a/src/proto/highlight.pro b/src/proto/highlight.pro index ca4498140c..4c6b2f75c0 100644 --- a/src/proto/highlight.pro +++ b/src/proto/highlight.pro @@ -14,6 +14,12 @@ void hl_set_font_name(char_u *font_name); void hl_set_bg_color_name(char_u *name); void hl_set_fg_color_name(char_u *name); guicolor_T color_name2handle(char_u *name); +guicolor_T decode_hex_color(char_u *hex); +guicolor_T colorname2rgb(char_u *name); +void save_colorname_hexstr(int r, int g, int b, char_u *name); +void load_default_colors_lists(void); +guicolor_T gui_get_color_cmn(char_u *name); +guicolor_T gui_get_rgb_color_cmn(int r, int g, int b); int get_cterm_attr_idx(int attr, int fg, int bg); int get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg); int get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg); diff --git a/src/proto/term.pro b/src/proto/term.pro index efb2555343..572a41db7a 100644 --- a/src/proto/term.pro +++ b/src/proto/term.pro @@ -83,8 +83,6 @@ void show_termcodes(void); int show_one_termcode(char_u *name, char_u *code, int printit); void update_tcap(int attr); void swap_tcap(void); -guicolor_T gui_get_color_cmn(char_u *name); -guicolor_T gui_get_rgb_color_cmn(int r, int g, int b); void cterm_color2rgb(int nr, char_u *r, char_u *g, char_u *b, char_u *ansi_idx); void term_replace_bs_del_keycode(char_u *ta_buf, int ta_len, int len); /* vim: set ft=c : */ diff --git a/src/term.c b/src/term.c index b61667de8c..cb38b93387 100644 --- a/src/term.c +++ b/src/term.c @@ -1353,7 +1353,7 @@ termgui_get_color(char_u *name) t = termgui_mch_get_color(name); if (t == INVALCOLOR) - semsg(_(e_alloc_color), name); + semsg(_(e_cannot_allocate_color_str), name); return t; } @@ -6630,203 +6630,6 @@ swap_tcap(void) #endif -#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) - static int -hex_digit(int c) -{ - if (isdigit(c)) - return c - '0'; - c = TOLOWER_ASC(c); - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - return 0x1ffffff; -} - -# ifdef VIMDLL - static guicolor_T -gui_adjust_rgb(guicolor_T c) -{ - if (gui.in_use) - return c; - else - return ((c & 0xff) << 16) | (c & 0x00ff00) | ((c >> 16) & 0xff); -} -# else -# define gui_adjust_rgb(c) (c) -# endif - - guicolor_T -gui_get_color_cmn(char_u *name) -{ - // On MS-Windows an RGB macro is available and it produces 0x00bbggrr color - // values as used by the MS-Windows GDI api. It should be used only for - // MS-Windows GDI builds. -# if defined(RGB) && defined(MSWIN) && !defined(FEAT_GUI) -# undef RGB -# endif -# ifndef RGB -# define RGB(r, g, b) ((r<<16) | (g<<8) | (b)) -# endif -# define LINE_LEN 100 - FILE *fd; - char line[LINE_LEN]; - char_u *fname; - int r, g, b, i; - guicolor_T color; - - struct rgbcolor_table_S { - char_u *color_name; - guicolor_T color; - }; - - // Only non X11 colors (not present in rgb.txt) and colors in - // color_names[], useful when $VIMRUNTIME is not found,. - static struct rgbcolor_table_S rgb_table[] = { - {(char_u *)"black", RGB(0x00, 0x00, 0x00)}, - {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)}, - {(char_u *)"brown", RGB(0xA5, 0x2A, 0x2A)}, - {(char_u *)"cyan", RGB(0x00, 0xFF, 0xFF)}, - {(char_u *)"darkblue", RGB(0x00, 0x00, 0x8B)}, - {(char_u *)"darkcyan", RGB(0x00, 0x8B, 0x8B)}, - {(char_u *)"darkgray", RGB(0xA9, 0xA9, 0xA9)}, - {(char_u *)"darkgreen", RGB(0x00, 0x64, 0x00)}, - {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)}, - {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)}, - {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)}, - {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, // No X11 - {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)}, - {(char_u *)"green", RGB(0x00, 0xFF, 0x00)}, - {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)}, - {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)}, - {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)}, - {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)}, - {(char_u *)"lightblue", RGB(0xAD, 0xD8, 0xE6)}, - {(char_u *)"lightcyan", RGB(0xE0, 0xFF, 0xFF)}, - {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)}, - {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)}, - {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)}, - {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, // No X11 - {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, // No X11 - {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)}, - {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)}, - {(char_u *)"red", RGB(0xFF, 0x00, 0x00)}, - {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)}, - {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)}, - {(char_u *)"yellow", RGB(0xFF, 0xFF, 0x00)}, - }; - - static struct rgbcolor_table_S *colornames_table; - static int size = 0; - - if (name[0] == '#' && STRLEN(name) == 7) - { - // Name is in "#rrggbb" format - color = RGB(((hex_digit(name[1]) << 4) + hex_digit(name[2])), - ((hex_digit(name[3]) << 4) + hex_digit(name[4])), - ((hex_digit(name[5]) << 4) + hex_digit(name[6]))); - if (color > 0xffffff) - return INVALCOLOR; - return gui_adjust_rgb(color); - } - - // Check if the name is one of the colors we know - for (i = 0; i < (int)ARRAY_LENGTH(rgb_table); i++) - if (STRICMP(name, rgb_table[i].color_name) == 0) - return gui_adjust_rgb(rgb_table[i].color); - - /* - * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". - */ - if (size == 0) - { - int counting; - - // colornames_table not yet initialized - fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt"); - if (fname == NULL) - return INVALCOLOR; - - fd = fopen((char *)fname, "rt"); - vim_free(fname); - if (fd == NULL) - { - if (p_verbose > 1) - verb_msg(_("Cannot open $VIMRUNTIME/rgb.txt")); - size = -1; // don't try again - return INVALCOLOR; - } - - for (counting = 1; counting >= 0; --counting) - { - if (!counting) - { - colornames_table = ALLOC_MULT(struct rgbcolor_table_S, size); - if (colornames_table == NULL) - { - fclose(fd); - return INVALCOLOR; - } - rewind(fd); - } - size = 0; - - while (!feof(fd)) - { - size_t len; - int pos; - - vim_ignoredp = fgets(line, LINE_LEN, fd); - len = strlen(line); - - if (len <= 1 || line[len - 1] != '\n') - continue; - - line[len - 1] = '\0'; - - i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos); - if (i != 3) - continue; - - if (!counting) - { - char_u *s = vim_strsave((char_u *)line + pos); - - if (s == NULL) - { - fclose(fd); - return INVALCOLOR; - } - colornames_table[size].color_name = s; - colornames_table[size].color = (guicolor_T)RGB(r, g, b); - } - size++; - - // The distributed rgb.txt has less than 1000 entries. Limit to - // 10000, just in case the file was messed up. - if (size == 10000) - break; - } - } - fclose(fd); - } - - for (i = 0; i < size; i++) - if (STRICMP(name, colornames_table[i].color_name) == 0) - return gui_adjust_rgb(colornames_table[i].color); - - return INVALCOLOR; -} - - guicolor_T -gui_get_rgb_color_cmn(int r, int g, int b) -{ - guicolor_T color = RGB(r, g, b); - - if (color > 0xffffff) - return INVALCOLOR; - return gui_adjust_rgb(color); -} -#endif #if (defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))) || defined(FEAT_TERMINAL) \ || defined(PROTO) diff --git a/src/testdir/test_highlight.vim b/src/testdir/test_highlight.vim index a4c7a72591..d3734b31f2 100644 --- a/src/testdir/test_highlight.vim +++ b/src/testdir/test_highlight.vim @@ -934,4 +934,40 @@ func Test_highlight_default_colorscheme_restores_links() hi clear endfunc +func Test_colornames_assignment_and_lookup() + " Ensure highlight command can find custom color. + let v:colornames['a redish white'] = '#ffeedd' + highlight Normal guifg='a redish white' + highlight clear +endfunc + +func Test_colornames_default_list() + " Ensure default lists are loaded automatically and can be used for all gui fields. + highlight Normal guifg='rebecca purple' guibg='rebecca purple' guisp='rebecca purple' + highlight clear +endfunc + +func Test_colornames_overwrite_default() + " Ensure entries in v:colornames can be overwritten. + " Load default color scheme to trigger default color list loading. + colorscheme default + let old_rebecca_purple = v:colornames['rebecca purple'] + highlight Normal guifg='rebecca purple' guibg='rebecca purple' + let v:colornames['rebecca purple'] = '#550099' + highlight Normal guifg='rebecca purple' guibg='rebecca purple' + let v:colornames['rebecca purple'] = old_rebecca_purple + highlight clear +endfunc + +func Test_colornames_assignment_and_unassignment() + " Ensure we cannot overwrite the v:colornames dict. + call assert_fails("let v:colornames = {}", 'E46:') + + " Ensure we can delete entries from the v:colornames dict. + let v:colornames['x1'] = '#111111' + call assert_equal(v:colornames['x1'], '#111111') + unlet v:colornames['x1'] + call assert_fails("echo v:colornames['x1']") +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 7dc55ac95a..3bba9728a4 100644 --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3562, +/**/ 3561, /**/ 3560, @@ -2044,7 +2044,8 @@ typedef int sock_T; #define VV_ARGV 96 #define VV_COLLATE 97 #define VV_EXITING 98 -#define VV_LEN 99 // number of v: vars +#define VV_COLORNAMES 99 +#define VV_LEN 100 // number of v: vars // used for v_number in VAR_BOOL and VAR_SPECIAL #define VVAL_FALSE 0L // VAR_BOOL |