summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDrew Vogel <dvogel@github>2021-10-24 20:35:07 +0100
committerBram Moolenaar <Bram@vim.org>2021-10-24 20:35:07 +0100
commite30d10253fa634c4f60daa798d029245f4eed393 (patch)
tree57aca74b65dc4c3924ef23185b8cb2b6933996c2 /src
parent3c5904d2a5d7861c227a4c3cd4ddcbc51014c838 (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/Makefile11
-rw-r--r--src/errors.h6
-rw-r--r--src/evalvars.c3
-rw-r--r--src/globals.h3
-rw-r--r--src/gui.c2
-rw-r--r--src/gui_haiku.cc159
-rw-r--r--src/highlight.c233
-rw-r--r--src/job.c2
-rw-r--r--src/proto/highlight.pro6
-rw-r--r--src/proto/term.pro2
-rw-r--r--src/term.c199
-rw-r--r--src/testdir/test_highlight.vim36
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h3
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"));
diff --git a/src/gui.c b/src/gui.c
index 1edf659dd1..68754b3bc0 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -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
/*
diff --git a/src/job.c b/src/job.c
index afa9972a76..fcb482c706 100644
--- a/src/job.c
+++ b/src/job.c
@@ -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,
diff --git a/src/vim.h b/src/vim.h
index 0ce0e964e2..31d4bdefe8 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -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