mirror of
https://github.com/neovim/neovim.git
synced 2025-09-05 19:08:15 +00:00
![github-actions[bot]](/assets/img/avatar_default.png)
Co-authored-by: Christian Clason <c.clason@uni-graz.at> Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: dundargoc <33953936+dundargoc@users.noreply.github.com>
3201 lines
114 KiB
C
3201 lines
114 KiB
C
// highlight_group.c: code for managing highlight groups
|
|
|
|
#include <ctype.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "klib/kvec.h"
|
|
#include "nvim/api/keysets_defs.h"
|
|
#include "nvim/api/private/defs.h"
|
|
#include "nvim/api/private/dispatch.h"
|
|
#include "nvim/api/private/helpers.h"
|
|
#include "nvim/api/private/validate.h"
|
|
#include "nvim/ascii_defs.h"
|
|
#include "nvim/autocmd.h"
|
|
#include "nvim/autocmd_defs.h"
|
|
#include "nvim/buffer_defs.h"
|
|
#include "nvim/charset.h"
|
|
#include "nvim/cmdexpand_defs.h"
|
|
#include "nvim/cursor_shape.h"
|
|
#include "nvim/decoration_provider.h"
|
|
#include "nvim/drawscreen.h"
|
|
#include "nvim/eval.h"
|
|
#include "nvim/eval/typval_defs.h"
|
|
#include "nvim/eval/vars.h"
|
|
#include "nvim/ex_docmd.h"
|
|
#include "nvim/garray.h"
|
|
#include "nvim/garray_defs.h"
|
|
#include "nvim/gettext_defs.h"
|
|
#include "nvim/globals.h"
|
|
#include "nvim/highlight.h"
|
|
#include "nvim/highlight_group.h"
|
|
#include "nvim/lua/executor.h"
|
|
#include "nvim/macros_defs.h"
|
|
#include "nvim/map_defs.h"
|
|
#include "nvim/memory.h"
|
|
#include "nvim/memory_defs.h"
|
|
#include "nvim/message.h"
|
|
#include "nvim/option.h"
|
|
#include "nvim/option_defs.h"
|
|
#include "nvim/option_vars.h"
|
|
#include "nvim/os/time.h"
|
|
#include "nvim/runtime.h"
|
|
#include "nvim/strings.h"
|
|
#include "nvim/types_defs.h"
|
|
#include "nvim/ui.h"
|
|
#include "nvim/ui_defs.h"
|
|
#include "nvim/vim_defs.h"
|
|
|
|
/// \addtogroup SG_SET
|
|
/// @{
|
|
enum {
|
|
SG_CTERM = 2, // cterm has been set
|
|
SG_GUI = 4, // gui has been set
|
|
SG_LINK = 8, // link has been set
|
|
};
|
|
/// @}
|
|
|
|
#define MAX_SYN_NAME 200
|
|
|
|
// builtin |highlight-groups|
|
|
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
|
|
|
|
// arena for object with same lifetime as highlight_ga (aka hl_table)
|
|
Arena highlight_arena = ARENA_EMPTY;
|
|
|
|
Map(cstr_t, int) highlight_unames = MAP_INIT;
|
|
|
|
/// The "term", "cterm" and "gui" arguments can be any combination of the
|
|
/// following names, separated by commas (but no spaces!).
|
|
static char *(hl_name_table[]) =
|
|
{ "bold", "standout", "underline",
|
|
"undercurl", "underdouble", "underdotted", "underdashed",
|
|
"italic", "reverse", "inverse", "strikethrough", "altfont",
|
|
"nocombine", "NONE" };
|
|
static int hl_attr_table[] =
|
|
{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE,
|
|
HL_UNDERCURL, HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED,
|
|
HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_ALTFONT,
|
|
HL_NOCOMBINE, 0 };
|
|
|
|
/// Structure that stores information about a highlight group.
|
|
/// The ID of a highlight group is also called group ID. It is the index in
|
|
/// the highlight_ga array PLUS ONE.
|
|
typedef struct {
|
|
char *sg_name; ///< highlight group name
|
|
char *sg_name_u; ///< uppercase of sg_name
|
|
bool sg_cleared; ///< "hi clear" was used
|
|
int sg_attr; ///< Screen attr @see ATTR_ENTRY
|
|
int sg_link; ///< link to this highlight group ID
|
|
int sg_deflink; ///< default link; restored in highlight_clear()
|
|
int sg_set; ///< combination of flags in \ref SG_SET
|
|
sctx_T sg_deflink_sctx; ///< script where the default link was set
|
|
sctx_T sg_script_ctx; ///< script in which the group was last set for terminal UIs
|
|
int sg_cterm; ///< "cterm=" highlighting attr
|
|
///< (combination of \ref HlAttrFlags)
|
|
int sg_cterm_fg; ///< terminal fg color number + 1
|
|
int sg_cterm_bg; ///< terminal bg color number + 1
|
|
bool sg_cterm_bold; ///< bold attr was set for light color for RGB UIs
|
|
int sg_gui; ///< "gui=" highlighting attributes
|
|
///< (combination of \ref HlAttrFlags)
|
|
RgbValue sg_rgb_fg; ///< RGB foreground color
|
|
RgbValue sg_rgb_bg; ///< RGB background color
|
|
RgbValue sg_rgb_sp; ///< RGB special color
|
|
int sg_rgb_fg_idx; ///< RGB foreground color index
|
|
int sg_rgb_bg_idx; ///< RGB background color index
|
|
int sg_rgb_sp_idx; ///< RGB special color index
|
|
|
|
int sg_blend; ///< blend level (0-100 inclusive), -1 if unset
|
|
|
|
int sg_parent; ///< parent of @nested.group
|
|
} HlGroup;
|
|
|
|
enum {
|
|
kColorIdxNone = -1,
|
|
kColorIdxHex = -2,
|
|
kColorIdxFg = -3,
|
|
kColorIdxBg = -4,
|
|
};
|
|
|
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
|
# include "highlight_group.c.generated.h"
|
|
#endif
|
|
|
|
static const char e_highlight_group_name_not_found_str[]
|
|
= N_("E411: Highlight group not found: %s");
|
|
static const char e_group_has_settings_highlight_link_ignored[]
|
|
= N_("E414: Group has settings, highlight link ignored");
|
|
static const char e_unexpected_equal_sign_str[]
|
|
= N_("E415: Unexpected equal sign: %s");
|
|
static const char e_missing_equal_sign_str_2[]
|
|
= N_("E416: Missing equal sign: %s");
|
|
static const char e_missing_argument_str[]
|
|
= N_("E417: Missing argument: %s");
|
|
|
|
#define hl_table ((HlGroup *)((highlight_ga.ga_data)))
|
|
|
|
// The default highlight groups. These are compiled-in for fast startup and
|
|
// they still work when the runtime files can't be found.
|
|
|
|
static const char *highlight_init_both[] = {
|
|
"Cursor guifg=bg guibg=fg",
|
|
"CursorLineNr gui=bold cterm=bold",
|
|
"RedrawDebugNormal gui=reverse cterm=reverse",
|
|
"TabLineSel gui=bold cterm=bold",
|
|
"TermCursor gui=reverse cterm=reverse",
|
|
"Underlined gui=underline cterm=underline",
|
|
"lCursor guifg=bg guibg=fg",
|
|
|
|
// UI
|
|
"default link CursorIM Cursor",
|
|
"default link CursorLineFold FoldColumn",
|
|
"default link CursorLineSign SignColumn",
|
|
"default link EndOfBuffer NonText",
|
|
"default link FloatBorder NormalFloat",
|
|
"default link FloatFooter FloatTitle",
|
|
"default link FloatTitle Title",
|
|
"default link FoldColumn SignColumn",
|
|
"default link IncSearch CurSearch",
|
|
"default link LineNrAbove LineNr",
|
|
"default link LineNrBelow LineNr",
|
|
"default link MsgSeparator StatusLine",
|
|
"default link MsgArea NONE",
|
|
"default link NormalNC NONE",
|
|
"default link PmenuExtra Pmenu",
|
|
"default link PmenuExtraSel PmenuSel",
|
|
"default link PmenuKind Pmenu",
|
|
"default link PmenuKindSel PmenuSel",
|
|
"default link PmenuSbar Pmenu",
|
|
"default link Substitute Search",
|
|
"default link TabLine StatusLineNC",
|
|
"default link TabLineFill TabLine",
|
|
"default link TermCursorNC NONE",
|
|
"default link VertSplit WinSeparator",
|
|
"default link VisualNOS Visual",
|
|
"default link Whitespace NonText",
|
|
"default link WildMenu PmenuSel",
|
|
"default link WinSeparator Normal",
|
|
|
|
// Syntax
|
|
"default link Character Constant",
|
|
"default link Number Constant",
|
|
"default link Boolean Constant",
|
|
"default link Float Number",
|
|
"default link Conditional Statement",
|
|
"default link Repeat Statement",
|
|
"default link Label Statement",
|
|
"default link Keyword Statement",
|
|
"default link Exception Statement",
|
|
"default link Include PreProc",
|
|
"default link Define PreProc",
|
|
"default link Macro PreProc",
|
|
"default link PreCondit PreProc",
|
|
"default link StorageClass Type",
|
|
"default link Structure Type",
|
|
"default link Typedef Type",
|
|
"default link Tag Special",
|
|
"default link SpecialChar Special",
|
|
"default link SpecialComment Special",
|
|
"default link Debug Special",
|
|
"default link Ignore Normal",
|
|
|
|
// Built-in LSP
|
|
"default link LspCodeLens NonText",
|
|
"default link LspCodeLensSeparator LspCodeLens",
|
|
"default link LspInlayHint NonText",
|
|
"default link LspReferenceRead LspReferenceText",
|
|
"default link LspReferenceText Visual",
|
|
"default link LspReferenceWrite LspReferenceText",
|
|
"default link LspSignatureActiveParameter Visual",
|
|
"default link SnippetTabstop Visual",
|
|
|
|
// Diagnostic
|
|
"default link DiagnosticFloatingError DiagnosticError",
|
|
"default link DiagnosticFloatingWarn DiagnosticWarn",
|
|
"default link DiagnosticFloatingInfo DiagnosticInfo",
|
|
"default link DiagnosticFloatingHint DiagnosticHint",
|
|
"default link DiagnosticFloatingOk DiagnosticOk",
|
|
"default link DiagnosticVirtualTextError DiagnosticError",
|
|
"default link DiagnosticVirtualTextWarn DiagnosticWarn",
|
|
"default link DiagnosticVirtualTextInfo DiagnosticInfo",
|
|
"default link DiagnosticVirtualTextHint DiagnosticHint",
|
|
"default link DiagnosticVirtualTextOk DiagnosticOk",
|
|
"default link DiagnosticSignError DiagnosticError",
|
|
"default link DiagnosticSignWarn DiagnosticWarn",
|
|
"default link DiagnosticSignInfo DiagnosticInfo",
|
|
"default link DiagnosticSignHint DiagnosticHint",
|
|
"default link DiagnosticSignOk DiagnosticOk",
|
|
"default link DiagnosticUnnecessary Comment",
|
|
|
|
// Treesitter standard groups
|
|
"default link @variable.builtin Special",
|
|
"default link @variable.parameter.builtin Special",
|
|
|
|
"default link @constant Constant",
|
|
"default link @constant.builtin Special",
|
|
|
|
"default link @module Structure",
|
|
"default link @module.builtin Special",
|
|
"default link @label Label",
|
|
|
|
"default link @string String",
|
|
"default link @string.regexp @string.special",
|
|
"default link @string.escape @string.special",
|
|
"default link @string.special SpecialChar",
|
|
"default link @string.special.url Underlined",
|
|
|
|
"default link @character Character",
|
|
"default link @character.special SpecialChar",
|
|
|
|
"default link @boolean Boolean",
|
|
"default link @number Number",
|
|
"default link @number.float Float",
|
|
|
|
"default link @type Type",
|
|
"default link @type.builtin Special",
|
|
|
|
"default link @attribute Macro",
|
|
"default link @attribute.builtin Special",
|
|
"default link @property Identifier",
|
|
|
|
"default link @function Function",
|
|
"default link @function.builtin Special",
|
|
|
|
"default link @constructor Special",
|
|
"default link @operator Operator",
|
|
|
|
"default link @keyword Keyword",
|
|
|
|
"default link @punctuation Delimiter", // fallback for subgroups; never used itself
|
|
"default link @punctuation.special Special",
|
|
|
|
"default link @comment Comment",
|
|
|
|
"default link @comment.error DiagnosticError",
|
|
"default link @comment.warning DiagnosticWarn",
|
|
"default link @comment.note DiagnosticInfo",
|
|
"default link @comment.todo Todo",
|
|
|
|
"@markup.strong gui=bold cterm=bold",
|
|
"@markup.italic gui=italic cterm=italic",
|
|
"@markup.strikethrough gui=strikethrough cterm=strikethrough",
|
|
"@markup.underline gui=underline cterm=underline",
|
|
|
|
"default link @markup Special", // fallback for subgroups; never used itself
|
|
"default link @markup.heading Title",
|
|
"default link @markup.link Underlined",
|
|
|
|
"default link @diff.plus Added",
|
|
"default link @diff.minus Removed",
|
|
"default link @diff.delta Changed",
|
|
|
|
"default link @tag Tag",
|
|
"default link @tag.builtin Special",
|
|
|
|
// LSP semantic tokens
|
|
"default link @lsp.type.class @type",
|
|
"default link @lsp.type.comment @comment",
|
|
"default link @lsp.type.decorator @attribute",
|
|
"default link @lsp.type.enum @type",
|
|
"default link @lsp.type.enumMember @constant",
|
|
"default link @lsp.type.event @type",
|
|
"default link @lsp.type.function @function",
|
|
"default link @lsp.type.interface @type",
|
|
"default link @lsp.type.keyword @keyword",
|
|
"default link @lsp.type.macro @constant.macro",
|
|
"default link @lsp.type.method @function.method",
|
|
"default link @lsp.type.modifier @type.qualifier",
|
|
"default link @lsp.type.namespace @module",
|
|
"default link @lsp.type.number @number",
|
|
"default link @lsp.type.operator @operator",
|
|
"default link @lsp.type.parameter @variable.parameter",
|
|
"default link @lsp.type.property @property",
|
|
"default link @lsp.type.regexp @string.regexp",
|
|
"default link @lsp.type.string @string",
|
|
"default link @lsp.type.struct @type",
|
|
"default link @lsp.type.type @type",
|
|
"default link @lsp.type.typeParameter @type.definition",
|
|
"default link @lsp.type.variable @variable",
|
|
|
|
"default link @lsp.mod.deprecated DiagnosticDeprecated",
|
|
|
|
NULL
|
|
};
|
|
|
|
// Default colors only used with a light background.
|
|
static const char *highlight_init_light[] = {
|
|
"Normal guifg=NvimDarkGrey2 guibg=NvimLightGrey2 ctermfg=NONE ctermbg=NONE",
|
|
|
|
// UI
|
|
"Added guifg=NvimDarkGreen ctermfg=2",
|
|
"Changed guifg=NvimDarkCyan ctermfg=6",
|
|
"ColorColumn guibg=NvimLightGrey4 cterm=reverse",
|
|
"Conceal guifg=NvimLightGrey4",
|
|
"CurSearch guifg=NvimLightGrey1 guibg=NvimDarkYellow ctermfg=15 ctermbg=3",
|
|
"CursorColumn guibg=NvimLightGrey3",
|
|
"CursorLine guibg=NvimLightGrey3",
|
|
"DiffAdd guifg=NvimDarkGrey1 guibg=NvimLightGreen ctermfg=15 ctermbg=2",
|
|
"DiffChange guifg=NvimDarkGrey1 guibg=NvimLightGrey4",
|
|
"DiffDelete guifg=NvimDarkRed gui=bold ctermfg=1 cterm=bold",
|
|
"DiffText guifg=NvimDarkGrey1 guibg=NvimLightCyan ctermfg=15 ctermbg=6",
|
|
"Directory guifg=NvimDarkCyan ctermfg=6",
|
|
"ErrorMsg guifg=NvimDarkRed ctermfg=1",
|
|
"FloatShadow guibg=NvimLightGrey4 ctermbg=0 blend=80",
|
|
"FloatShadowThrough guibg=NvimLightGrey4 ctermbg=0 blend=100",
|
|
"Folded guifg=NvimDarkGrey4 guibg=NvimLightGrey3",
|
|
"LineNr guifg=NvimLightGrey4",
|
|
"MatchParen guibg=NvimLightGrey4 gui=bold cterm=bold,underline",
|
|
"ModeMsg guifg=NvimDarkGreen ctermfg=2",
|
|
"MoreMsg guifg=NvimDarkCyan ctermfg=6",
|
|
"NonText guifg=NvimLightGrey4",
|
|
"NormalFloat guibg=NvimLightGrey1",
|
|
"Pmenu guibg=NvimLightGrey3 cterm=reverse",
|
|
"PmenuSel guifg=NvimLightGrey3 guibg=NvimDarkGrey2 cterm=reverse,underline blend=0",
|
|
"PmenuThumb guibg=NvimLightGrey4",
|
|
"Question guifg=NvimDarkCyan ctermfg=6",
|
|
"QuickFixLine guifg=NvimDarkCyan ctermfg=6",
|
|
"RedrawDebugClear guibg=NvimLightYellow ctermfg=15 ctermbg=3",
|
|
"RedrawDebugComposed guibg=NvimLightGreen ctermfg=15 ctermbg=2",
|
|
"RedrawDebugRecompose guibg=NvimLightRed ctermfg=15 ctermbg=1",
|
|
"Removed guifg=NvimDarkRed ctermfg=1",
|
|
"Search guifg=NvimDarkGrey1 guibg=NvimLightYellow ctermfg=15 ctermbg=3",
|
|
"SignColumn guifg=NvimLightGrey4",
|
|
"SpecialKey guifg=NvimLightGrey4",
|
|
"SpellBad guisp=NvimDarkRed gui=undercurl cterm=undercurl",
|
|
"SpellCap guisp=NvimDarkYellow gui=undercurl cterm=undercurl",
|
|
"SpellLocal guisp=NvimDarkGreen gui=undercurl cterm=undercurl",
|
|
"SpellRare guisp=NvimDarkCyan gui=undercurl cterm=undercurl",
|
|
"StatusLine guifg=NvimLightGrey3 guibg=NvimDarkGrey3 cterm=reverse",
|
|
"StatusLineNC guifg=NvimDarkGrey3 guibg=NvimLightGrey3 cterm=bold,underline",
|
|
"Title guifg=NvimDarkGrey2 gui=bold cterm=bold",
|
|
"Visual guibg=NvimLightGrey4 ctermfg=15 ctermbg=0",
|
|
"WarningMsg guifg=NvimDarkYellow ctermfg=3",
|
|
"WinBar guifg=NvimDarkGrey4 guibg=NvimLightGrey1 gui=bold cterm=bold",
|
|
"WinBarNC guifg=NvimDarkGrey4 guibg=NvimLightGrey1 cterm=bold",
|
|
|
|
// Syntax
|
|
"Constant guifg=NvimDarkGrey2", // Use only `Normal` foreground to be usable on different background
|
|
"Operator guifg=NvimDarkGrey2",
|
|
"PreProc guifg=NvimDarkGrey2",
|
|
"Type guifg=NvimDarkGrey2",
|
|
"Delimiter guifg=NvimDarkGrey2",
|
|
|
|
"Comment guifg=NvimDarkGrey4",
|
|
"String guifg=NvimDarkGreen ctermfg=2",
|
|
"Identifier guifg=NvimDarkBlue ctermfg=4",
|
|
"Function guifg=NvimDarkCyan ctermfg=6",
|
|
"Statement guifg=NvimDarkGrey2 gui=bold cterm=bold",
|
|
"Special guifg=NvimDarkCyan ctermfg=6",
|
|
"Error guifg=NvimDarkGrey1 guibg=NvimLightRed ctermfg=15 ctermbg=1",
|
|
"Todo guifg=NvimDarkGrey2 gui=bold cterm=bold",
|
|
|
|
// Diagnostic
|
|
"DiagnosticError guifg=NvimDarkRed ctermfg=1",
|
|
"DiagnosticWarn guifg=NvimDarkYellow ctermfg=3",
|
|
"DiagnosticInfo guifg=NvimDarkCyan ctermfg=6",
|
|
"DiagnosticHint guifg=NvimDarkBlue ctermfg=4",
|
|
"DiagnosticOk guifg=NvimDarkGreen ctermfg=2",
|
|
"DiagnosticUnderlineError guisp=NvimDarkRed gui=underline cterm=underline",
|
|
"DiagnosticUnderlineWarn guisp=NvimDarkYellow gui=underline cterm=underline",
|
|
"DiagnosticUnderlineInfo guisp=NvimDarkCyan gui=underline cterm=underline",
|
|
"DiagnosticUnderlineHint guisp=NvimDarkBlue gui=underline cterm=underline",
|
|
"DiagnosticUnderlineOk guisp=NvimDarkGreen gui=underline cterm=underline",
|
|
"DiagnosticDeprecated guisp=NvimDarkRed gui=strikethrough cterm=strikethrough",
|
|
|
|
// Treesitter standard groups
|
|
"@variable guifg=NvimDarkGrey2",
|
|
NULL
|
|
};
|
|
|
|
// Default colors only used with a dark background.
|
|
static const char *highlight_init_dark[] = {
|
|
"Normal guifg=NvimLightGrey2 guibg=NvimDarkGrey2 ctermfg=NONE ctermbg=NONE",
|
|
|
|
// UI
|
|
"Added guifg=NvimLightGreen ctermfg=10",
|
|
"Changed guifg=NvimLightCyan ctermfg=14",
|
|
"ColorColumn guibg=NvimDarkGrey4 cterm=reverse",
|
|
"Conceal guifg=NvimDarkGrey4",
|
|
"CurSearch guifg=NvimDarkGrey1 guibg=NvimLightYellow ctermfg=0 ctermbg=11",
|
|
"CursorColumn guibg=NvimDarkGrey3",
|
|
"CursorLine guibg=NvimDarkGrey3",
|
|
"DiffAdd guifg=NvimLightGrey1 guibg=NvimDarkGreen ctermfg=0 ctermbg=10",
|
|
"DiffChange guifg=NvimLightGrey1 guibg=NvimDarkGrey4",
|
|
"DiffDelete guifg=NvimLightRed gui=bold ctermfg=9 cterm=bold",
|
|
"DiffText guifg=NvimLightGrey1 guibg=NvimDarkCyan ctermfg=0 ctermbg=14",
|
|
"Directory guifg=NvimLightCyan ctermfg=14",
|
|
"ErrorMsg guifg=NvimLightRed ctermfg=9",
|
|
"FloatShadow guibg=NvimDarkGrey4 ctermbg=0 blend=80",
|
|
"FloatShadowThrough guibg=NvimDarkGrey4 ctermbg=0 blend=100",
|
|
"Folded guifg=NvimLightGrey4 guibg=NvimDarkGrey3",
|
|
"LineNr guifg=NvimDarkGrey4",
|
|
"MatchParen guibg=NvimDarkGrey4 gui=bold cterm=bold,underline",
|
|
"ModeMsg guifg=NvimLightGreen ctermfg=10",
|
|
"MoreMsg guifg=NvimLightCyan ctermfg=14",
|
|
"NonText guifg=NvimDarkGrey4",
|
|
"NormalFloat guibg=NvimDarkGrey1",
|
|
"Pmenu guibg=NvimDarkGrey3 cterm=reverse",
|
|
"PmenuSel guifg=NvimDarkGrey3 guibg=NvimLightGrey2 cterm=reverse,underline blend=0",
|
|
"PmenuThumb guibg=NvimDarkGrey4",
|
|
"Question guifg=NvimLightCyan ctermfg=14",
|
|
"QuickFixLine guifg=NvimLightCyan ctermfg=14",
|
|
"RedrawDebugClear guibg=NvimDarkYellow ctermfg=0 ctermbg=11",
|
|
"RedrawDebugComposed guibg=NvimDarkGreen ctermfg=0 ctermbg=10",
|
|
"RedrawDebugRecompose guibg=NvimDarkRed ctermfg=0 ctermbg=9",
|
|
"Removed guifg=NvimLightRed ctermfg=9",
|
|
"Search guifg=NvimLightGrey1 guibg=NvimDarkYellow ctermfg=0 ctermbg=11",
|
|
"SignColumn guifg=NvimDarkGrey4",
|
|
"SpecialKey guifg=NvimDarkGrey4",
|
|
"SpellBad guisp=NvimLightRed gui=undercurl cterm=undercurl",
|
|
"SpellCap guisp=NvimLightYellow gui=undercurl cterm=undercurl",
|
|
"SpellLocal guisp=NvimLightGreen gui=undercurl cterm=undercurl",
|
|
"SpellRare guisp=NvimLightCyan gui=undercurl cterm=undercurl",
|
|
"StatusLine guifg=NvimDarkGrey3 guibg=NvimLightGrey3 cterm=reverse",
|
|
"StatusLineNC guifg=NvimLightGrey3 guibg=NvimDarkGrey3 cterm=bold,underline",
|
|
"Title guifg=NvimLightGrey2 gui=bold cterm=bold",
|
|
"Visual guibg=NvimDarkGrey4 ctermfg=0 ctermbg=15",
|
|
"WarningMsg guifg=NvimLightYellow ctermfg=11",
|
|
"WinBar guifg=NvimLightGrey4 guibg=NvimDarkGrey1 gui=bold cterm=bold",
|
|
"WinBarNC guifg=NvimLightGrey4 guibg=NvimDarkGrey1 cterm=bold",
|
|
|
|
// Syntax
|
|
"Constant guifg=NvimLightGrey2", // Use only `Normal` foreground to be usable on different background
|
|
"Operator guifg=NvimLightGrey2",
|
|
"PreProc guifg=NvimLightGrey2",
|
|
"Type guifg=NvimLightGrey2",
|
|
"Delimiter guifg=NvimLightGrey2",
|
|
|
|
"Comment guifg=NvimLightGrey4",
|
|
"String guifg=NvimLightGreen ctermfg=10",
|
|
"Identifier guifg=NvimLightBlue ctermfg=12",
|
|
"Function guifg=NvimLightCyan ctermfg=14",
|
|
"Statement guifg=NvimLightGrey2 gui=bold cterm=bold",
|
|
"Special guifg=NvimLightCyan ctermfg=14",
|
|
"Error guifg=NvimLightGrey1 guibg=NvimDarkRed ctermfg=0 ctermbg=9",
|
|
"Todo guifg=NvimLightGrey2 gui=bold cterm=bold",
|
|
|
|
// Diagnostic
|
|
"DiagnosticError guifg=NvimLightRed ctermfg=9",
|
|
"DiagnosticWarn guifg=NvimLightYellow ctermfg=11",
|
|
"DiagnosticInfo guifg=NvimLightCyan ctermfg=14",
|
|
"DiagnosticHint guifg=NvimLightBlue ctermfg=12",
|
|
"DiagnosticOk guifg=NvimLightGreen ctermfg=10",
|
|
"DiagnosticUnderlineError guisp=NvimLightRed gui=underline cterm=underline",
|
|
"DiagnosticUnderlineWarn guisp=NvimLightYellow gui=underline cterm=underline",
|
|
"DiagnosticUnderlineInfo guisp=NvimLightCyan gui=underline cterm=underline",
|
|
"DiagnosticUnderlineHint guisp=NvimLightBlue gui=underline cterm=underline",
|
|
"DiagnosticUnderlineOk guisp=NvimLightGreen gui=underline cterm=underline",
|
|
"DiagnosticDeprecated guisp=NvimLightRed gui=strikethrough cterm=strikethrough",
|
|
|
|
// Treesitter standard groups
|
|
"@variable guifg=NvimLightGrey2",
|
|
NULL
|
|
};
|
|
|
|
const char *const highlight_init_cmdline[] = {
|
|
// XXX When modifying a list modify it in both valid and invalid halves.
|
|
// TODO(ZyX-I): merge valid and invalid groups via a macros.
|
|
|
|
// NvimInternalError should appear only when highlighter has a bug.
|
|
"NvimInternalError ctermfg=Red ctermbg=Red guifg=Red guibg=Red",
|
|
|
|
// Highlight groups (links) used by parser:
|
|
|
|
"default link NvimAssignment Operator",
|
|
"default link NvimPlainAssignment NvimAssignment",
|
|
"default link NvimAugmentedAssignment NvimAssignment",
|
|
"default link NvimAssignmentWithAddition NvimAugmentedAssignment",
|
|
"default link NvimAssignmentWithSubtraction NvimAugmentedAssignment",
|
|
"default link NvimAssignmentWithConcatenation NvimAugmentedAssignment",
|
|
|
|
"default link NvimOperator Operator",
|
|
|
|
"default link NvimUnaryOperator NvimOperator",
|
|
"default link NvimUnaryPlus NvimUnaryOperator",
|
|
"default link NvimUnaryMinus NvimUnaryOperator",
|
|
"default link NvimNot NvimUnaryOperator",
|
|
|
|
"default link NvimBinaryOperator NvimOperator",
|
|
"default link NvimComparison NvimBinaryOperator",
|
|
"default link NvimComparisonModifier NvimComparison",
|
|
"default link NvimBinaryPlus NvimBinaryOperator",
|
|
"default link NvimBinaryMinus NvimBinaryOperator",
|
|
"default link NvimConcat NvimBinaryOperator",
|
|
"default link NvimConcatOrSubscript NvimConcat",
|
|
"default link NvimOr NvimBinaryOperator",
|
|
"default link NvimAnd NvimBinaryOperator",
|
|
"default link NvimMultiplication NvimBinaryOperator",
|
|
"default link NvimDivision NvimBinaryOperator",
|
|
"default link NvimMod NvimBinaryOperator",
|
|
|
|
"default link NvimTernary NvimOperator",
|
|
"default link NvimTernaryColon NvimTernary",
|
|
|
|
"default link NvimParenthesis Delimiter",
|
|
"default link NvimLambda NvimParenthesis",
|
|
"default link NvimNestingParenthesis NvimParenthesis",
|
|
"default link NvimCallingParenthesis NvimParenthesis",
|
|
|
|
"default link NvimSubscript NvimParenthesis",
|
|
"default link NvimSubscriptBracket NvimSubscript",
|
|
"default link NvimSubscriptColon NvimSubscript",
|
|
"default link NvimCurly NvimSubscript",
|
|
|
|
"default link NvimContainer NvimParenthesis",
|
|
"default link NvimDict NvimContainer",
|
|
"default link NvimList NvimContainer",
|
|
|
|
"default link NvimIdentifier Identifier",
|
|
"default link NvimIdentifierScope NvimIdentifier",
|
|
"default link NvimIdentifierScopeDelimiter NvimIdentifier",
|
|
"default link NvimIdentifierName NvimIdentifier",
|
|
"default link NvimIdentifierKey NvimIdentifier",
|
|
|
|
"default link NvimColon Delimiter",
|
|
"default link NvimComma Delimiter",
|
|
"default link NvimArrow Delimiter",
|
|
|
|
"default link NvimRegister SpecialChar",
|
|
"default link NvimNumber Number",
|
|
"default link NvimFloat NvimNumber",
|
|
"default link NvimNumberPrefix Type",
|
|
|
|
"default link NvimOptionSigil Type",
|
|
"default link NvimOptionName NvimIdentifier",
|
|
"default link NvimOptionScope NvimIdentifierScope",
|
|
"default link NvimOptionScopeDelimiter NvimIdentifierScopeDelimiter",
|
|
|
|
"default link NvimEnvironmentSigil NvimOptionSigil",
|
|
"default link NvimEnvironmentName NvimIdentifier",
|
|
|
|
"default link NvimString String",
|
|
"default link NvimStringBody NvimString",
|
|
"default link NvimStringQuote NvimString",
|
|
"default link NvimStringSpecial SpecialChar",
|
|
|
|
"default link NvimSingleQuote NvimStringQuote",
|
|
"default link NvimSingleQuotedBody NvimStringBody",
|
|
"default link NvimSingleQuotedQuote NvimStringSpecial",
|
|
|
|
"default link NvimDoubleQuote NvimStringQuote",
|
|
"default link NvimDoubleQuotedBody NvimStringBody",
|
|
"default link NvimDoubleQuotedEscape NvimStringSpecial",
|
|
|
|
"default link NvimFigureBrace NvimInternalError",
|
|
"default link NvimSingleQuotedUnknownEscape NvimInternalError",
|
|
|
|
"default link NvimSpacing Normal",
|
|
|
|
// NvimInvalid groups:
|
|
|
|
"default link NvimInvalidSingleQuotedUnknownEscape NvimInternalError",
|
|
|
|
"default link NvimInvalid Error",
|
|
|
|
"default link NvimInvalidAssignment NvimInvalid",
|
|
"default link NvimInvalidPlainAssignment NvimInvalidAssignment",
|
|
"default link NvimInvalidAugmentedAssignment NvimInvalidAssignment",
|
|
"default link NvimInvalidAssignmentWithAddition NvimInvalidAugmentedAssignment",
|
|
"default link NvimInvalidAssignmentWithSubtraction NvimInvalidAugmentedAssignment",
|
|
"default link NvimInvalidAssignmentWithConcatenation NvimInvalidAugmentedAssignment",
|
|
|
|
"default link NvimInvalidOperator NvimInvalid",
|
|
|
|
"default link NvimInvalidUnaryOperator NvimInvalidOperator",
|
|
"default link NvimInvalidUnaryPlus NvimInvalidUnaryOperator",
|
|
"default link NvimInvalidUnaryMinus NvimInvalidUnaryOperator",
|
|
"default link NvimInvalidNot NvimInvalidUnaryOperator",
|
|
|
|
"default link NvimInvalidBinaryOperator NvimInvalidOperator",
|
|
"default link NvimInvalidComparison NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidComparisonModifier NvimInvalidComparison",
|
|
"default link NvimInvalidBinaryPlus NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidBinaryMinus NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidConcat NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidConcatOrSubscript NvimInvalidConcat",
|
|
"default link NvimInvalidOr NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidAnd NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidMultiplication NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidDivision NvimInvalidBinaryOperator",
|
|
"default link NvimInvalidMod NvimInvalidBinaryOperator",
|
|
|
|
"default link NvimInvalidTernary NvimInvalidOperator",
|
|
"default link NvimInvalidTernaryColon NvimInvalidTernary",
|
|
|
|
"default link NvimInvalidDelimiter NvimInvalid",
|
|
|
|
"default link NvimInvalidParenthesis NvimInvalidDelimiter",
|
|
"default link NvimInvalidLambda NvimInvalidParenthesis",
|
|
"default link NvimInvalidNestingParenthesis NvimInvalidParenthesis",
|
|
"default link NvimInvalidCallingParenthesis NvimInvalidParenthesis",
|
|
|
|
"default link NvimInvalidSubscript NvimInvalidParenthesis",
|
|
"default link NvimInvalidSubscriptBracket NvimInvalidSubscript",
|
|
"default link NvimInvalidSubscriptColon NvimInvalidSubscript",
|
|
"default link NvimInvalidCurly NvimInvalidSubscript",
|
|
|
|
"default link NvimInvalidContainer NvimInvalidParenthesis",
|
|
"default link NvimInvalidDict NvimInvalidContainer",
|
|
"default link NvimInvalidList NvimInvalidContainer",
|
|
|
|
"default link NvimInvalidValue NvimInvalid",
|
|
|
|
"default link NvimInvalidIdentifier NvimInvalidValue",
|
|
"default link NvimInvalidIdentifierScope NvimInvalidIdentifier",
|
|
"default link NvimInvalidIdentifierScopeDelimiter NvimInvalidIdentifier",
|
|
"default link NvimInvalidIdentifierName NvimInvalidIdentifier",
|
|
"default link NvimInvalidIdentifierKey NvimInvalidIdentifier",
|
|
|
|
"default link NvimInvalidColon NvimInvalidDelimiter",
|
|
"default link NvimInvalidComma NvimInvalidDelimiter",
|
|
"default link NvimInvalidArrow NvimInvalidDelimiter",
|
|
|
|
"default link NvimInvalidRegister NvimInvalidValue",
|
|
"default link NvimInvalidNumber NvimInvalidValue",
|
|
"default link NvimInvalidFloat NvimInvalidNumber",
|
|
"default link NvimInvalidNumberPrefix NvimInvalidNumber",
|
|
|
|
"default link NvimInvalidOptionSigil NvimInvalidIdentifier",
|
|
"default link NvimInvalidOptionName NvimInvalidIdentifier",
|
|
"default link NvimInvalidOptionScope NvimInvalidIdentifierScope",
|
|
"default link NvimInvalidOptionScopeDelimiter NvimInvalidIdentifierScopeDelimiter",
|
|
|
|
"default link NvimInvalidEnvironmentSigil NvimInvalidOptionSigil",
|
|
"default link NvimInvalidEnvironmentName NvimInvalidIdentifier",
|
|
|
|
// Invalid string bodies and specials are still highlighted as valid ones to
|
|
// minimize the red area.
|
|
"default link NvimInvalidString NvimInvalidValue",
|
|
"default link NvimInvalidStringBody NvimStringBody",
|
|
"default link NvimInvalidStringQuote NvimInvalidString",
|
|
"default link NvimInvalidStringSpecial NvimStringSpecial",
|
|
|
|
"default link NvimInvalidSingleQuote NvimInvalidStringQuote",
|
|
"default link NvimInvalidSingleQuotedBody NvimInvalidStringBody",
|
|
"default link NvimInvalidSingleQuotedQuote NvimInvalidStringSpecial",
|
|
|
|
"default link NvimInvalidDoubleQuote NvimInvalidStringQuote",
|
|
"default link NvimInvalidDoubleQuotedBody NvimInvalidStringBody",
|
|
"default link NvimInvalidDoubleQuotedEscape NvimInvalidStringSpecial",
|
|
"default link NvimInvalidDoubleQuotedUnknownEscape NvimInvalidValue",
|
|
|
|
"default link NvimInvalidFigureBrace NvimInvalidDelimiter",
|
|
|
|
"default link NvimInvalidSpacing ErrorMsg",
|
|
|
|
// Not actually invalid, but we show the user that they are doing something
|
|
// wrong.
|
|
"default link NvimDoubleQuotedUnknownEscape NvimInvalidValue",
|
|
NULL,
|
|
};
|
|
|
|
/// Returns the number of highlight groups.
|
|
int highlight_num_groups(void)
|
|
{
|
|
return highlight_ga.ga_len;
|
|
}
|
|
|
|
/// Returns the name of a highlight group.
|
|
char *highlight_group_name(int id)
|
|
{
|
|
return hl_table[id].sg_name;
|
|
}
|
|
|
|
/// Returns the ID of the link to a highlight group.
|
|
int highlight_link_id(int id)
|
|
{
|
|
return hl_table[id].sg_link;
|
|
}
|
|
|
|
/// Create default links for Nvim* highlight groups used for cmdline coloring
|
|
void syn_init_cmdline_highlight(bool reset, bool init)
|
|
{
|
|
for (size_t i = 0; highlight_init_cmdline[i] != NULL; i++) {
|
|
do_highlight(highlight_init_cmdline[i], reset, init);
|
|
}
|
|
}
|
|
|
|
/// Load colors from a file if "g:colors_name" is set, otherwise load builtin
|
|
/// colors
|
|
///
|
|
/// @param both include groups where 'bg' doesn't matter
|
|
/// @param reset clear groups first
|
|
void init_highlight(bool both, bool reset)
|
|
{
|
|
static bool had_both = false;
|
|
|
|
// Try finding the color scheme file. Used when a color file was loaded
|
|
// and 'background' or 't_Co' is changed.
|
|
char *p = get_var_value("g:colors_name");
|
|
if (p != NULL) {
|
|
// Value of g:colors_name could be freed in load_colors() and make
|
|
// p invalid, so copy it.
|
|
char *copy_p = xstrdup(p);
|
|
bool okay = load_colors(copy_p);
|
|
xfree(copy_p);
|
|
if (okay) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Didn't use a color file, use the compiled-in colors.
|
|
if (both) {
|
|
had_both = true;
|
|
const char *const *const pp = highlight_init_both;
|
|
for (size_t i = 0; pp[i] != NULL; i++) {
|
|
do_highlight(pp[i], reset, true);
|
|
}
|
|
} else if (!had_both) {
|
|
// Don't do anything before the call with both == true from main().
|
|
// Not everything has been setup then, and that call will overrule
|
|
// everything anyway.
|
|
return;
|
|
}
|
|
|
|
const char *const *const pp = ((*p_bg == 'l')
|
|
? highlight_init_light
|
|
: highlight_init_dark);
|
|
for (size_t i = 0; pp[i] != NULL; i++) {
|
|
do_highlight(pp[i], reset, true);
|
|
}
|
|
|
|
syn_init_cmdline_highlight(false, false);
|
|
}
|
|
|
|
/// Load color file "name".
|
|
///
|
|
/// @return OK for success, FAIL for failure.
|
|
int load_colors(char *name)
|
|
{
|
|
static bool recursive = false;
|
|
|
|
// When being called recursively, this is probably because setting
|
|
// 'background' caused the highlighting to be reloaded. This means it is
|
|
// working, thus we should return OK.
|
|
if (recursive) {
|
|
return OK;
|
|
}
|
|
|
|
recursive = true;
|
|
size_t buflen = strlen(name) + 12;
|
|
char *buf = xmalloc(buflen);
|
|
apply_autocmds(EVENT_COLORSCHEMEPRE, name, curbuf->b_fname, false, curbuf);
|
|
snprintf(buf, buflen, "colors/%s.*", name);
|
|
int retval = source_runtime_vim_lua(buf, DIP_START + DIP_OPT);
|
|
xfree(buf);
|
|
if (retval == OK) {
|
|
apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, false, curbuf);
|
|
}
|
|
|
|
recursive = false;
|
|
|
|
return retval;
|
|
}
|
|
|
|
static char *(color_names[28]) = {
|
|
"Black", "DarkBlue", "DarkGreen", "DarkCyan",
|
|
"DarkRed", "DarkMagenta", "Brown", "DarkYellow",
|
|
"Gray", "Grey", "LightGray", "LightGrey",
|
|
"DarkGray", "DarkGrey",
|
|
"Blue", "LightBlue", "Green", "LightGreen",
|
|
"Cyan", "LightCyan", "Red", "LightRed", "Magenta",
|
|
"LightMagenta", "Yellow", "LightYellow", "White", "NONE"
|
|
};
|
|
// indices:
|
|
// 0, 1, 2, 3,
|
|
// 4, 5, 6, 7,
|
|
// 8, 9, 10, 11,
|
|
// 12, 13,
|
|
// 14, 15, 16, 17,
|
|
// 18, 19, 20, 21, 22,
|
|
// 23, 24, 25, 26, 27
|
|
static int color_numbers_16[28] = { 0, 1, 2, 3,
|
|
4, 5, 6, 6,
|
|
7, 7, 7, 7,
|
|
8, 8,
|
|
9, 9, 10, 10,
|
|
11, 11, 12, 12, 13,
|
|
13, 14, 14, 15, -1 };
|
|
// for xterm with 88 colors...
|
|
static int color_numbers_88[28] = { 0, 4, 2, 6,
|
|
1, 5, 32, 72,
|
|
84, 84, 7, 7,
|
|
82, 82,
|
|
12, 43, 10, 61,
|
|
14, 63, 9, 74, 13,
|
|
75, 11, 78, 15, -1 };
|
|
// for xterm with 256 colors...
|
|
static int color_numbers_256[28] = { 0, 4, 2, 6,
|
|
1, 5, 130, 3,
|
|
248, 248, 7, 7,
|
|
242, 242,
|
|
12, 81, 10, 121,
|
|
14, 159, 9, 224, 13,
|
|
225, 11, 229, 15, -1 };
|
|
// for terminals with less than 16 colors...
|
|
static int color_numbers_8[28] = { 0, 4, 2, 6,
|
|
1, 5, 3, 3,
|
|
7, 7, 7, 7,
|
|
0 + 8, 0 + 8,
|
|
4 + 8, 4 + 8, 2 + 8, 2 + 8,
|
|
6 + 8, 6 + 8, 1 + 8, 1 + 8, 5 + 8,
|
|
5 + 8, 3 + 8, 3 + 8, 7 + 8, -1 };
|
|
|
|
// Lookup the "cterm" value to be used for color with index "idx" in
|
|
// color_names[].
|
|
// "boldp" will be set to kTrue or kFalse for a foreground color when using 8
|
|
// colors, otherwise it will be unchanged.
|
|
int lookup_color(const int idx, const bool foreground, TriState *const boldp)
|
|
{
|
|
int color = color_numbers_16[idx];
|
|
|
|
// Use the _16 table to check if it's a valid color name.
|
|
if (color < 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (t_colors == 8) {
|
|
// t_Co is 8: use the 8 colors table
|
|
color = color_numbers_8[idx];
|
|
if (foreground) {
|
|
// set/reset bold attribute to get light foreground
|
|
// colors (on some terminals, e.g. "linux")
|
|
if (color & 8) {
|
|
*boldp = kTrue;
|
|
} else {
|
|
*boldp = kFalse;
|
|
}
|
|
}
|
|
color &= 7; // truncate to 8 colors
|
|
} else if (t_colors == 16) {
|
|
color = color_numbers_8[idx];
|
|
} else if (t_colors == 88) {
|
|
color = color_numbers_88[idx];
|
|
} else if (t_colors >= 256) {
|
|
color = color_numbers_256[idx];
|
|
}
|
|
return color;
|
|
}
|
|
|
|
void set_hl_group(int id, HlAttrs attrs, Dict(highlight) *dict, int link_id)
|
|
{
|
|
int idx = id - 1; // Index is ID minus one.
|
|
bool is_default = attrs.rgb_ae_attr & HL_DEFAULT;
|
|
|
|
// Return if "default" was used and the group already has settings
|
|
if (is_default && hl_has_settings(idx, true) && !dict->force) {
|
|
return;
|
|
}
|
|
|
|
HlGroup *g = &hl_table[idx];
|
|
g->sg_cleared = false;
|
|
|
|
if (link_id > 0) {
|
|
g->sg_link = link_id;
|
|
g->sg_script_ctx = current_sctx;
|
|
g->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&g->sg_script_ctx);
|
|
g->sg_set |= SG_LINK;
|
|
if (is_default) {
|
|
g->sg_deflink = link_id;
|
|
g->sg_deflink_sctx = current_sctx;
|
|
g->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&g->sg_deflink_sctx);
|
|
}
|
|
} else {
|
|
g->sg_link = 0;
|
|
}
|
|
|
|
g->sg_gui = attrs.rgb_ae_attr &~HL_DEFAULT;
|
|
|
|
g->sg_rgb_fg = attrs.rgb_fg_color;
|
|
g->sg_rgb_bg = attrs.rgb_bg_color;
|
|
g->sg_rgb_sp = attrs.rgb_sp_color;
|
|
|
|
struct {
|
|
int *dest; RgbValue val; Object name;
|
|
} cattrs[] = {
|
|
{ &g->sg_rgb_fg_idx, g->sg_rgb_fg,
|
|
HAS_KEY(dict, highlight, fg) ? dict->fg : dict->foreground },
|
|
{ &g->sg_rgb_bg_idx, g->sg_rgb_bg,
|
|
HAS_KEY(dict, highlight, bg) ? dict->bg : dict->background },
|
|
{ &g->sg_rgb_sp_idx, g->sg_rgb_sp, HAS_KEY(dict, highlight, sp) ? dict->sp : dict->special },
|
|
{ NULL, -1, NIL },
|
|
};
|
|
|
|
for (int j = 0; cattrs[j].dest; j++) {
|
|
if (cattrs[j].val < 0) {
|
|
*cattrs[j].dest = kColorIdxNone;
|
|
} else if (cattrs[j].name.type == kObjectTypeString && cattrs[j].name.data.string.size) {
|
|
name_to_color(cattrs[j].name.data.string.data, cattrs[j].dest);
|
|
} else {
|
|
*cattrs[j].dest = kColorIdxHex;
|
|
}
|
|
}
|
|
|
|
g->sg_cterm = attrs.cterm_ae_attr &~HL_DEFAULT;
|
|
g->sg_cterm_bg = attrs.cterm_bg_color;
|
|
g->sg_cterm_fg = attrs.cterm_fg_color;
|
|
g->sg_cterm_bold = g->sg_cterm & HL_BOLD;
|
|
g->sg_blend = attrs.hl_blend;
|
|
|
|
g->sg_script_ctx = current_sctx;
|
|
g->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&g->sg_script_ctx);
|
|
|
|
g->sg_attr = hl_get_syn_attr(0, id, attrs);
|
|
|
|
// 'Normal' is special
|
|
if (strcmp(g->sg_name_u, "NORMAL") == 0) {
|
|
cterm_normal_fg_color = g->sg_cterm_fg;
|
|
cterm_normal_bg_color = g->sg_cterm_bg;
|
|
bool did_changed = false;
|
|
if (normal_bg != g->sg_rgb_bg || normal_fg != g->sg_rgb_fg || normal_sp != g->sg_rgb_sp) {
|
|
did_changed = true;
|
|
}
|
|
normal_fg = g->sg_rgb_fg;
|
|
normal_bg = g->sg_rgb_bg;
|
|
normal_sp = g->sg_rgb_sp;
|
|
|
|
if (did_changed) {
|
|
highlight_attr_set_all();
|
|
}
|
|
ui_default_colors_set();
|
|
} else {
|
|
// a cursor style uses this syn_id, make sure its attribute is updated.
|
|
if (cursor_mode_uses_syn_id(id)) {
|
|
ui_mode_info_set();
|
|
}
|
|
}
|
|
|
|
if (!updating_screen) {
|
|
redraw_all_later(UPD_NOT_VALID);
|
|
}
|
|
need_highlight_changed = true;
|
|
}
|
|
|
|
/// Handle ":highlight" command
|
|
///
|
|
/// When using ":highlight clear" this is called recursively for each group with
|
|
/// forceit and init being both true.
|
|
///
|
|
/// @param[in] line Command arguments.
|
|
/// @param[in] forceit True when bang is given, allows to link group even if
|
|
/// it has its own settings.
|
|
/// @param[in] init True when initializing.
|
|
void do_highlight(const char *line, const bool forceit, const bool init)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
// If no argument, list current highlighting.
|
|
if (!init && ends_excmd((uint8_t)(*line))) {
|
|
for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
|
|
// TODO(brammool): only call when the group has attributes set
|
|
highlight_list_one(i);
|
|
}
|
|
return;
|
|
}
|
|
|
|
bool dodefault = false;
|
|
|
|
// Isolate the name.
|
|
const char *name_end = skiptowhite(line);
|
|
const char *linep = skipwhite(name_end);
|
|
|
|
// Check for "default" argument.
|
|
if (strncmp(line, "default", (size_t)(name_end - line)) == 0) {
|
|
dodefault = true;
|
|
line = linep;
|
|
name_end = skiptowhite(line);
|
|
linep = skipwhite(name_end);
|
|
}
|
|
|
|
bool doclear = false;
|
|
bool dolink = false;
|
|
|
|
// Check for "clear" or "link" argument.
|
|
if (strncmp(line, "clear", (size_t)(name_end - line)) == 0) {
|
|
doclear = true;
|
|
} else if (strncmp(line, "link", (size_t)(name_end - line)) == 0) {
|
|
dolink = true;
|
|
}
|
|
|
|
// ":highlight {group-name}": list highlighting for one group.
|
|
if (!doclear && !dolink && ends_excmd((uint8_t)(*linep))) {
|
|
int id = syn_name2id_len(line, (size_t)(name_end - line));
|
|
if (id == 0) {
|
|
semsg(_(e_highlight_group_name_not_found_str), line);
|
|
} else {
|
|
highlight_list_one(id);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Handle ":highlight link {from} {to}" command.
|
|
if (dolink) {
|
|
const char *from_start = linep;
|
|
int to_id;
|
|
HlGroup *hlgroup = NULL;
|
|
|
|
const char *from_end = skiptowhite(from_start);
|
|
const char *to_start = skipwhite(from_end);
|
|
const char *to_end = skiptowhite(to_start);
|
|
|
|
if (ends_excmd((uint8_t)(*from_start))
|
|
|| ends_excmd((uint8_t)(*to_start))) {
|
|
semsg(_("E412: Not enough arguments: \":highlight link %s\""),
|
|
from_start);
|
|
return;
|
|
}
|
|
|
|
if (!ends_excmd(*skipwhite(to_end))) {
|
|
semsg(_("E413: Too many arguments: \":highlight link %s\""), from_start);
|
|
return;
|
|
}
|
|
|
|
int from_id = syn_check_group(from_start, (size_t)(from_end - from_start));
|
|
if (strncmp(to_start, "NONE", 4) == 0) {
|
|
to_id = 0;
|
|
} else {
|
|
to_id = syn_check_group(to_start, (size_t)(to_end - to_start));
|
|
}
|
|
|
|
if (from_id > 0) {
|
|
hlgroup = &hl_table[from_id - 1];
|
|
if (dodefault && (forceit || hlgroup->sg_deflink == 0)) {
|
|
hlgroup->sg_deflink = to_id;
|
|
hlgroup->sg_deflink_sctx = current_sctx;
|
|
hlgroup->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&hlgroup->sg_deflink_sctx);
|
|
}
|
|
}
|
|
|
|
if (from_id > 0 && (!init || hlgroup->sg_set == 0)) {
|
|
// Don't allow a link when there already is some highlighting
|
|
// for the group, unless '!' is used
|
|
if (to_id > 0 && !forceit && !init
|
|
&& hl_has_settings(from_id - 1, dodefault)) {
|
|
if (SOURCING_NAME == NULL && !dodefault) {
|
|
emsg(_(e_group_has_settings_highlight_link_ignored));
|
|
}
|
|
} else if (hlgroup->sg_link != to_id
|
|
|| hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
|
|
|| hlgroup->sg_cleared) {
|
|
if (!init) {
|
|
hlgroup->sg_set |= SG_LINK;
|
|
}
|
|
hlgroup->sg_link = to_id;
|
|
hlgroup->sg_script_ctx = current_sctx;
|
|
hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&hlgroup->sg_script_ctx);
|
|
hlgroup->sg_cleared = false;
|
|
redraw_all_later(UPD_SOME_VALID);
|
|
|
|
// Only call highlight changed() once after multiple changes
|
|
need_highlight_changed = true;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (doclear) {
|
|
// ":highlight clear [group]" command.
|
|
line = linep;
|
|
if (ends_excmd((uint8_t)(*line))) {
|
|
do_unlet(S_LEN("g:colors_name"), true);
|
|
restore_cterm_colors();
|
|
|
|
// Clear all default highlight groups and load the defaults.
|
|
for (int j = 0; j < highlight_ga.ga_len; j++) {
|
|
highlight_clear(j);
|
|
}
|
|
init_highlight(true, true);
|
|
highlight_changed();
|
|
redraw_all_later(UPD_NOT_VALID);
|
|
return;
|
|
}
|
|
name_end = skiptowhite(line);
|
|
linep = skipwhite(name_end);
|
|
}
|
|
|
|
// Find the group name in the table. If it does not exist yet, add it.
|
|
int id = syn_check_group(line, (size_t)(name_end - line));
|
|
if (id == 0) { // Failed (out of memory).
|
|
return;
|
|
}
|
|
int idx = id - 1; // Index is ID minus one.
|
|
|
|
// Return if "default" was used and the group already has settings
|
|
if (dodefault && hl_has_settings(idx, true)) {
|
|
return;
|
|
}
|
|
|
|
// Make a copy so we can check if any attribute actually changed
|
|
HlGroup item_before = hl_table[idx];
|
|
bool is_normal_group = (strcmp(hl_table[idx].sg_name_u, "NORMAL") == 0);
|
|
|
|
// Clear the highlighting for ":hi clear {group}" and ":hi clear".
|
|
if (doclear || (forceit && init)) {
|
|
highlight_clear(idx);
|
|
if (!doclear) {
|
|
hl_table[idx].sg_set = 0;
|
|
}
|
|
}
|
|
|
|
bool did_change = false;
|
|
bool error = false;
|
|
|
|
char key[64];
|
|
char arg[512];
|
|
if (!doclear) {
|
|
const char *arg_start;
|
|
|
|
while (!ends_excmd((uint8_t)(*linep))) {
|
|
const char *key_start = linep;
|
|
if (*linep == '=') {
|
|
semsg(_(e_unexpected_equal_sign_str), key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
|
|
// Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg",
|
|
// "guibg" or "guisp").
|
|
while (*linep && !ascii_iswhite(*linep) && *linep != '=') {
|
|
linep++;
|
|
}
|
|
size_t key_len = (size_t)(linep - key_start);
|
|
if (key_len > sizeof(key) - 1) {
|
|
emsg(_("E423: Illegal argument"));
|
|
error = true;
|
|
break;
|
|
}
|
|
vim_memcpy_up(key, key_start, key_len);
|
|
key[key_len] = '\0';
|
|
linep = skipwhite(linep);
|
|
|
|
if (strcmp(key, "NONE") == 0) {
|
|
if (!init || hl_table[idx].sg_set == 0) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_CTERM + SG_GUI;
|
|
}
|
|
highlight_clear(idx);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// Check for the equal sign.
|
|
if (*linep != '=') {
|
|
semsg(_(e_missing_equal_sign_str_2), key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
linep++;
|
|
|
|
// Isolate the argument.
|
|
linep = skipwhite(linep);
|
|
if (*linep == '\'') { // guifg='color name'
|
|
arg_start = ++linep;
|
|
linep = strchr(linep, '\'');
|
|
if (linep == NULL) {
|
|
semsg(_(e_invarg2), key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
} else {
|
|
arg_start = linep;
|
|
linep = skiptowhite(linep);
|
|
}
|
|
if (linep == arg_start) {
|
|
semsg(_(e_missing_argument_str), key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
size_t arg_len = (size_t)(linep - arg_start);
|
|
if (arg_len > sizeof(arg) - 1) {
|
|
emsg(_("E423: Illegal argument"));
|
|
error = true;
|
|
break;
|
|
}
|
|
memcpy(arg, arg_start, arg_len);
|
|
arg[arg_len] = NUL;
|
|
|
|
if (*linep == '\'') {
|
|
linep++;
|
|
}
|
|
|
|
// Store the argument.
|
|
if (strcmp(key, "TERM") == 0
|
|
|| strcmp(key, "CTERM") == 0
|
|
|| strcmp(key, "GUI") == 0) {
|
|
int attr = 0;
|
|
int off = 0;
|
|
int i;
|
|
while (arg[off] != NUL) {
|
|
for (i = ARRAY_SIZE(hl_attr_table); --i >= 0;) {
|
|
int len = (int)strlen(hl_name_table[i]);
|
|
if (STRNICMP(arg + off, hl_name_table[i], len) == 0) {
|
|
if (hl_attr_table[i] & HL_UNDERLINE_MASK) {
|
|
attr &= ~HL_UNDERLINE_MASK;
|
|
}
|
|
attr |= hl_attr_table[i];
|
|
off += len;
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
semsg(_("E418: Illegal value: %s"), arg);
|
|
error = true;
|
|
break;
|
|
}
|
|
if (arg[off] == ',') { // Another one follows.
|
|
off++;
|
|
}
|
|
}
|
|
if (error) {
|
|
break;
|
|
}
|
|
if (*key == 'C') {
|
|
if (!init || !(hl_table[idx].sg_set & SG_CTERM)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_CTERM;
|
|
}
|
|
hl_table[idx].sg_cterm = attr;
|
|
hl_table[idx].sg_cterm_bold = false;
|
|
}
|
|
} else if (*key == 'G') {
|
|
if (!init || !(hl_table[idx].sg_set & SG_GUI)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_GUI;
|
|
}
|
|
hl_table[idx].sg_gui = attr;
|
|
}
|
|
}
|
|
} else if (strcmp(key, "FONT") == 0) {
|
|
// in non-GUI fonts are simply ignored
|
|
} else if (strcmp(key, "CTERMFG") == 0 || strcmp(key, "CTERMBG") == 0) {
|
|
if (!init || !(hl_table[idx].sg_set & SG_CTERM)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_CTERM;
|
|
}
|
|
|
|
// When setting the foreground color, and previously the "bold"
|
|
// flag was set for a light color, reset it now
|
|
if (key[5] == 'F' && hl_table[idx].sg_cterm_bold) {
|
|
hl_table[idx].sg_cterm &= ~HL_BOLD;
|
|
hl_table[idx].sg_cterm_bold = false;
|
|
}
|
|
|
|
int color;
|
|
if (ascii_isdigit(*arg)) {
|
|
color = atoi(arg);
|
|
} else if (STRICMP(arg, "fg") == 0) {
|
|
if (cterm_normal_fg_color) {
|
|
color = cterm_normal_fg_color - 1;
|
|
} else {
|
|
emsg(_("E419: FG color unknown"));
|
|
error = true;
|
|
break;
|
|
}
|
|
} else if (STRICMP(arg, "bg") == 0) {
|
|
if (cterm_normal_bg_color > 0) {
|
|
color = cterm_normal_bg_color - 1;
|
|
} else {
|
|
emsg(_("E420: BG color unknown"));
|
|
error = true;
|
|
break;
|
|
}
|
|
} else {
|
|
// Reduce calls to STRICMP a bit, it can be slow.
|
|
int off = TOUPPER_ASC(*arg);
|
|
int i;
|
|
for (i = ARRAY_SIZE(color_names); --i >= 0;) {
|
|
if (off == color_names[i][0]
|
|
&& STRICMP(arg + 1, color_names[i] + 1) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
semsg(_("E421: Color name or number not recognized: %s"),
|
|
key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
|
|
TriState bold = kNone;
|
|
color = lookup_color(i, key[5] == 'F', &bold);
|
|
|
|
// set/reset bold attribute to get light foreground
|
|
// colors (on some terminals, e.g. "linux")
|
|
if (bold == kTrue) {
|
|
hl_table[idx].sg_cterm |= HL_BOLD;
|
|
hl_table[idx].sg_cterm_bold = true;
|
|
} else if (bold == kFalse) {
|
|
hl_table[idx].sg_cterm &= ~HL_BOLD;
|
|
}
|
|
}
|
|
// Add one to the argument, to avoid zero. Zero is used for
|
|
// "NONE", then "color" is -1.
|
|
if (key[5] == 'F') {
|
|
hl_table[idx].sg_cterm_fg = color + 1;
|
|
if (is_normal_group) {
|
|
cterm_normal_fg_color = color + 1;
|
|
}
|
|
} else {
|
|
hl_table[idx].sg_cterm_bg = color + 1;
|
|
if (is_normal_group) {
|
|
cterm_normal_bg_color = color + 1;
|
|
if (!ui_rgb_attached()) {
|
|
if (color >= 0) {
|
|
int dark = -1;
|
|
|
|
if (t_colors < 16) {
|
|
dark = (color == 0 || color == 4);
|
|
} else if (color < 16) {
|
|
// Limit the heuristic to the standard 16 colors
|
|
dark = (color < 7 || color == 8);
|
|
}
|
|
// Set the 'background' option if the value is
|
|
// wrong.
|
|
if (dark != -1
|
|
&& dark != (*p_bg == 'd')
|
|
&& !option_was_set(kOptBackground)) {
|
|
set_option_value_give_err(kOptBackground,
|
|
CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0);
|
|
reset_option_was_set(kOptBackground);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (strcmp(key, "GUIFG") == 0) {
|
|
int *indexp = &hl_table[idx].sg_rgb_fg_idx;
|
|
|
|
if (!init || !(hl_table[idx].sg_set & SG_GUI)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_GUI;
|
|
}
|
|
|
|
RgbValue old_color = hl_table[idx].sg_rgb_fg;
|
|
int old_idx = hl_table[idx].sg_rgb_fg_idx;
|
|
|
|
if (strcmp(arg, "NONE") != 0) {
|
|
hl_table[idx].sg_rgb_fg = name_to_color(arg, indexp);
|
|
} else {
|
|
hl_table[idx].sg_rgb_fg = -1;
|
|
hl_table[idx].sg_rgb_fg_idx = kColorIdxNone;
|
|
}
|
|
|
|
did_change = hl_table[idx].sg_rgb_fg != old_color || hl_table[idx].sg_rgb_fg != old_idx;
|
|
}
|
|
|
|
if (is_normal_group) {
|
|
normal_fg = hl_table[idx].sg_rgb_fg;
|
|
}
|
|
} else if (strcmp(key, "GUIBG") == 0) {
|
|
int *indexp = &hl_table[idx].sg_rgb_bg_idx;
|
|
|
|
if (!init || !(hl_table[idx].sg_set & SG_GUI)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_GUI;
|
|
}
|
|
|
|
RgbValue old_color = hl_table[idx].sg_rgb_bg;
|
|
int old_idx = hl_table[idx].sg_rgb_bg_idx;
|
|
|
|
if (strcmp(arg, "NONE") != 0) {
|
|
hl_table[idx].sg_rgb_bg = name_to_color(arg, indexp);
|
|
} else {
|
|
hl_table[idx].sg_rgb_bg = -1;
|
|
hl_table[idx].sg_rgb_bg_idx = kColorIdxNone;
|
|
}
|
|
|
|
did_change = hl_table[idx].sg_rgb_bg != old_color || hl_table[idx].sg_rgb_bg != old_idx;
|
|
}
|
|
|
|
if (is_normal_group) {
|
|
normal_bg = hl_table[idx].sg_rgb_bg;
|
|
}
|
|
} else if (strcmp(key, "GUISP") == 0) {
|
|
int *indexp = &hl_table[idx].sg_rgb_sp_idx;
|
|
|
|
if (!init || !(hl_table[idx].sg_set & SG_GUI)) {
|
|
if (!init) {
|
|
hl_table[idx].sg_set |= SG_GUI;
|
|
}
|
|
|
|
RgbValue old_color = hl_table[idx].sg_rgb_sp;
|
|
int old_idx = hl_table[idx].sg_rgb_sp_idx;
|
|
|
|
if (strcmp(arg, "NONE") != 0) {
|
|
hl_table[idx].sg_rgb_sp = name_to_color(arg, indexp);
|
|
} else {
|
|
hl_table[idx].sg_rgb_sp = -1;
|
|
}
|
|
|
|
did_change = hl_table[idx].sg_rgb_sp != old_color || hl_table[idx].sg_rgb_sp != old_idx;
|
|
}
|
|
|
|
if (is_normal_group) {
|
|
normal_sp = hl_table[idx].sg_rgb_sp;
|
|
}
|
|
} else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) {
|
|
// Ignored for now
|
|
} else if (strcmp(key, "BLEND") == 0) {
|
|
if (strcmp(arg, "NONE") != 0) {
|
|
hl_table[idx].sg_blend = (int)strtol(arg, NULL, 10);
|
|
} else {
|
|
hl_table[idx].sg_blend = -1;
|
|
}
|
|
} else {
|
|
semsg(_("E423: Illegal argument: %s"), key_start);
|
|
error = true;
|
|
break;
|
|
}
|
|
hl_table[idx].sg_cleared = false;
|
|
|
|
// When highlighting has been given for a group, don't link it.
|
|
if (!init || !(hl_table[idx].sg_set & SG_LINK)) {
|
|
hl_table[idx].sg_link = 0;
|
|
}
|
|
|
|
// Continue with next argument.
|
|
linep = skipwhite(linep);
|
|
}
|
|
}
|
|
|
|
bool did_highlight_changed = false;
|
|
|
|
if (!error && is_normal_group) {
|
|
// Need to update all groups, because they might be using "bg" and/or
|
|
// "fg", which have been changed now.
|
|
highlight_attr_set_all();
|
|
|
|
if (!ui_has(kUILinegrid) && starting == 0) {
|
|
// Older UIs assume that we clear the screen after normal group is
|
|
// changed
|
|
ui_refresh();
|
|
} else {
|
|
// TUI and newer UIs will repaint the screen themselves. UPD_NOT_VALID
|
|
// redraw below will still handle usages of guibg=fg etc.
|
|
ui_default_colors_set();
|
|
}
|
|
did_highlight_changed = true;
|
|
redraw_all_later(UPD_NOT_VALID);
|
|
} else {
|
|
set_hl_attr(idx);
|
|
}
|
|
hl_table[idx].sg_script_ctx = current_sctx;
|
|
hl_table[idx].sg_script_ctx.sc_lnum += SOURCING_LNUM;
|
|
nlua_set_sctx(&hl_table[idx].sg_script_ctx);
|
|
|
|
// Only call highlight_changed() once, after a sequence of highlight
|
|
// commands, and only if an attribute actually changed
|
|
if ((did_change
|
|
|| memcmp(&hl_table[idx], &item_before, sizeof(item_before)) != 0)
|
|
&& !did_highlight_changed) {
|
|
// Do not trigger a redraw when highlighting is changed while
|
|
// redrawing. This may happen when evaluating 'statusline' changes the
|
|
// StatusLine group.
|
|
if (!updating_screen) {
|
|
redraw_all_later(UPD_NOT_VALID);
|
|
}
|
|
need_highlight_changed = true;
|
|
}
|
|
}
|
|
|
|
#if defined(EXITFREE)
|
|
void free_highlight(void)
|
|
{
|
|
ga_clear(&highlight_ga);
|
|
map_destroy(cstr_t, &highlight_unames);
|
|
arena_mem_free(arena_finish(&highlight_arena));
|
|
}
|
|
|
|
#endif
|
|
|
|
/// Reset the cterm colors to what they were before Vim was started, if
|
|
/// possible. Otherwise reset them to zero.
|
|
void restore_cterm_colors(void)
|
|
{
|
|
normal_fg = -1;
|
|
normal_bg = -1;
|
|
normal_sp = -1;
|
|
cterm_normal_fg_color = 0;
|
|
cterm_normal_bg_color = 0;
|
|
}
|
|
|
|
/// @param check_link if true also check for an existing link.
|
|
///
|
|
/// @return true if highlight group "idx" has any settings.
|
|
static bool hl_has_settings(int idx, bool check_link)
|
|
{
|
|
return hl_table[idx].sg_cleared == 0
|
|
&& (hl_table[idx].sg_attr != 0
|
|
|| hl_table[idx].sg_cterm_fg != 0
|
|
|| hl_table[idx].sg_cterm_bg != 0
|
|
|| hl_table[idx].sg_rgb_fg_idx != kColorIdxNone
|
|
|| hl_table[idx].sg_rgb_bg_idx != kColorIdxNone
|
|
|| hl_table[idx].sg_rgb_sp_idx != kColorIdxNone
|
|
|| (check_link && (hl_table[idx].sg_set & SG_LINK)));
|
|
}
|
|
|
|
/// Clear highlighting for one group.
|
|
static void highlight_clear(int idx)
|
|
{
|
|
hl_table[idx].sg_cleared = true;
|
|
|
|
hl_table[idx].sg_attr = 0;
|
|
hl_table[idx].sg_cterm = 0;
|
|
hl_table[idx].sg_cterm_bold = false;
|
|
hl_table[idx].sg_cterm_fg = 0;
|
|
hl_table[idx].sg_cterm_bg = 0;
|
|
hl_table[idx].sg_gui = 0;
|
|
hl_table[idx].sg_rgb_fg = -1;
|
|
hl_table[idx].sg_rgb_bg = -1;
|
|
hl_table[idx].sg_rgb_sp = -1;
|
|
hl_table[idx].sg_rgb_fg_idx = kColorIdxNone;
|
|
hl_table[idx].sg_rgb_bg_idx = kColorIdxNone;
|
|
hl_table[idx].sg_rgb_sp_idx = kColorIdxNone;
|
|
hl_table[idx].sg_blend = -1;
|
|
// Restore default link and context if they exist. Otherwise clears.
|
|
hl_table[idx].sg_link = hl_table[idx].sg_deflink;
|
|
// Since we set the default link, set the location to where the default
|
|
// link was set.
|
|
hl_table[idx].sg_script_ctx = hl_table[idx].sg_deflink_sctx;
|
|
}
|
|
|
|
/// \addtogroup LIST_XXX
|
|
/// @{
|
|
#define LIST_ATTR 1
|
|
#define LIST_STRING 2
|
|
#define LIST_INT 3
|
|
/// @}
|
|
|
|
static void highlight_list_one(const int id)
|
|
{
|
|
const HlGroup *sgp = &hl_table[id - 1]; // index is ID minus one
|
|
bool didh = false;
|
|
|
|
if (message_filtered(sgp->sg_name)) {
|
|
return;
|
|
}
|
|
|
|
// don't list specialized groups if a parent is used instead
|
|
if (sgp->sg_parent && sgp->sg_cleared) {
|
|
return;
|
|
}
|
|
|
|
didh = highlight_list_arg(id, didh, LIST_ATTR,
|
|
sgp->sg_cterm, NULL, "cterm");
|
|
didh = highlight_list_arg(id, didh, LIST_INT,
|
|
sgp->sg_cterm_fg, NULL, "ctermfg");
|
|
didh = highlight_list_arg(id, didh, LIST_INT,
|
|
sgp->sg_cterm_bg, NULL, "ctermbg");
|
|
|
|
didh = highlight_list_arg(id, didh, LIST_ATTR,
|
|
sgp->sg_gui, NULL, "gui");
|
|
char hexbuf[8];
|
|
didh = highlight_list_arg(id, didh, LIST_STRING, 0,
|
|
coloridx_to_name(sgp->sg_rgb_fg_idx, sgp->sg_rgb_fg, hexbuf), "guifg");
|
|
didh = highlight_list_arg(id, didh, LIST_STRING, 0,
|
|
coloridx_to_name(sgp->sg_rgb_bg_idx, sgp->sg_rgb_bg, hexbuf), "guibg");
|
|
didh = highlight_list_arg(id, didh, LIST_STRING, 0,
|
|
coloridx_to_name(sgp->sg_rgb_sp_idx, sgp->sg_rgb_sp, hexbuf), "guisp");
|
|
|
|
didh = highlight_list_arg(id, didh, LIST_INT,
|
|
sgp->sg_blend + 1, NULL, "blend");
|
|
|
|
if (sgp->sg_link && !got_int) {
|
|
syn_list_header(didh, 0, id, true);
|
|
didh = true;
|
|
msg_puts_attr("links to", HL_ATTR(HLF_D));
|
|
msg_putchar(' ');
|
|
msg_outtrans(hl_table[hl_table[id - 1].sg_link - 1].sg_name, 0);
|
|
}
|
|
|
|
if (!didh) {
|
|
highlight_list_arg(id, didh, LIST_STRING, 0, "cleared", "");
|
|
}
|
|
if (p_verbose > 0) {
|
|
last_set_msg(sgp->sg_script_ctx);
|
|
}
|
|
}
|
|
|
|
static bool hlgroup2dict(Dictionary *hl, NS ns_id, int hl_id, Arena *arena)
|
|
{
|
|
HlGroup *sgp = &hl_table[hl_id - 1];
|
|
int link = ns_id == 0 ? sgp->sg_link : ns_get_hl(&ns_id, hl_id, true, sgp->sg_set);
|
|
if (link == -1) {
|
|
return false;
|
|
}
|
|
if (ns_id == 0 && sgp->sg_cleared && sgp->sg_set == 0) {
|
|
// table entry was created but not ever set
|
|
return false;
|
|
}
|
|
HlAttrs attr =
|
|
syn_attr2entry(ns_id == 0 ? sgp->sg_attr : ns_get_hl(&ns_id, hl_id, false, sgp->sg_set));
|
|
*hl = arena_dict(arena, HLATTRS_DICT_SIZE + 1);
|
|
if (attr.rgb_ae_attr & HL_DEFAULT) {
|
|
PUT_C(*hl, "default", BOOLEAN_OBJ(true));
|
|
}
|
|
if (link > 0) {
|
|
PUT_C(*hl, "link", CSTR_AS_OBJ(hl_table[link - 1].sg_name));
|
|
}
|
|
Dictionary hl_cterm = arena_dict(arena, HLATTRS_DICT_SIZE);
|
|
hlattrs2dict(hl, NULL, attr, true, true);
|
|
hlattrs2dict(hl, &hl_cterm, attr, false, true);
|
|
if (kv_size(hl_cterm)) {
|
|
PUT_C(*hl, "cterm", DICTIONARY_OBJ(hl_cterm));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Dictionary ns_get_hl_defs(NS ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err)
|
|
{
|
|
Boolean link = GET_BOOL_OR_TRUE(opts, get_highlight, link);
|
|
int id = -1;
|
|
if (HAS_KEY(opts, get_highlight, name)) {
|
|
Boolean create = GET_BOOL_OR_TRUE(opts, get_highlight, create);
|
|
id = create ? syn_check_group(opts->name.data, opts->name.size)
|
|
: syn_name2id_len(opts->name.data, opts->name.size);
|
|
if (id == 0 && !create) {
|
|
Dictionary attrs = ARRAY_DICT_INIT;
|
|
return attrs;
|
|
}
|
|
} else if (HAS_KEY(opts, get_highlight, id)) {
|
|
id = (int)opts->id;
|
|
}
|
|
|
|
if (id != -1) {
|
|
VALIDATE(1 <= id && id <= highlight_ga.ga_len, "%s", "Highlight id out of bounds", {
|
|
goto cleanup;
|
|
});
|
|
Dictionary attrs = ARRAY_DICT_INIT;
|
|
hlgroup2dict(&attrs, ns_id, link ? id : syn_get_final_id(id), arena);
|
|
return attrs;
|
|
}
|
|
if (ERROR_SET(err)) {
|
|
goto cleanup;
|
|
}
|
|
|
|
Dictionary rv = arena_dict(arena, (size_t)highlight_ga.ga_len);
|
|
for (int i = 1; i <= highlight_ga.ga_len; i++) {
|
|
Dictionary attrs = ARRAY_DICT_INIT;
|
|
if (!hlgroup2dict(&attrs, ns_id, i, arena)) {
|
|
continue;
|
|
}
|
|
PUT_C(rv, hl_table[(link ? i : syn_get_final_id(i)) - 1].sg_name, DICTIONARY_OBJ(attrs));
|
|
}
|
|
|
|
return rv;
|
|
|
|
cleanup:
|
|
return (Dictionary)ARRAY_DICT_INIT;
|
|
}
|
|
|
|
/// Outputs a highlight when doing ":hi MyHighlight"
|
|
///
|
|
/// @param type one of \ref LIST_XXX
|
|
/// @param iarg integer argument used if \p type == LIST_INT
|
|
/// @param sarg string used if \p type == LIST_STRING
|
|
static bool highlight_list_arg(const int id, bool didh, const int type, int iarg, const char *sarg,
|
|
const char *const name)
|
|
{
|
|
if (got_int) {
|
|
return false;
|
|
}
|
|
|
|
if (type == LIST_STRING ? (sarg == NULL) : (iarg == 0)) {
|
|
return didh;
|
|
}
|
|
|
|
char buf[100];
|
|
const char *ts = buf;
|
|
if (type == LIST_INT) {
|
|
snprintf(buf, sizeof(buf), "%d", iarg - 1);
|
|
} else if (type == LIST_STRING) {
|
|
ts = sarg;
|
|
} else { // type == LIST_ATTR
|
|
buf[0] = NUL;
|
|
for (int i = 0; hl_attr_table[i] != 0; i++) {
|
|
if (((hl_attr_table[i] & HL_UNDERLINE_MASK)
|
|
&& ((iarg & HL_UNDERLINE_MASK) == hl_attr_table[i]))
|
|
|| (!(hl_attr_table[i] & HL_UNDERLINE_MASK)
|
|
&& (iarg & hl_attr_table[i]))) {
|
|
if (buf[0] != NUL) {
|
|
xstrlcat(buf, ",", 100);
|
|
}
|
|
xstrlcat(buf, hl_name_table[i], 100);
|
|
if (!(hl_attr_table[i] & HL_UNDERLINE_MASK)) {
|
|
iarg &= ~hl_attr_table[i]; // don't want "inverse"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
syn_list_header(didh, vim_strsize(ts) + (int)strlen(name) + 1, id, false);
|
|
didh = true;
|
|
if (!got_int) {
|
|
if (*name != NUL) {
|
|
msg_puts_attr(name, HL_ATTR(HLF_D));
|
|
msg_puts_attr("=", HL_ATTR(HLF_D));
|
|
}
|
|
msg_outtrans(ts, 0);
|
|
}
|
|
return didh;
|
|
}
|
|
|
|
/// Check whether highlight group has attribute
|
|
///
|
|
/// @param[in] id Highlight group to check.
|
|
/// @param[in] flag Attribute to check.
|
|
/// @param[in] modec 'g' for GUI, 'c' for term.
|
|
///
|
|
/// @return "1" if highlight group has attribute, NULL otherwise.
|
|
const char *highlight_has_attr(const int id, const int flag, const int modec)
|
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE
|
|
{
|
|
if (id <= 0 || id > highlight_ga.ga_len) {
|
|
return NULL;
|
|
}
|
|
|
|
int attr;
|
|
|
|
if (modec == 'g') {
|
|
attr = hl_table[id - 1].sg_gui;
|
|
} else {
|
|
attr = hl_table[id - 1].sg_cterm;
|
|
}
|
|
|
|
if (flag & HL_UNDERLINE_MASK) {
|
|
int ul = attr & HL_UNDERLINE_MASK;
|
|
return ul == flag ? "1" : NULL;
|
|
} else {
|
|
return (attr & flag) ? "1" : NULL;
|
|
}
|
|
}
|
|
|
|
/// Return color name of the given highlight group
|
|
///
|
|
/// @param[in] id Highlight group to work with.
|
|
/// @param[in] what What to return: one of "font", "fg", "bg", "sp", "fg#",
|
|
/// "bg#" or "sp#".
|
|
/// @param[in] modec 'g' for GUI, 'c' for cterm and 't' for term.
|
|
///
|
|
/// @return color name, possibly in a static buffer. Buffer will be overwritten
|
|
/// on next highlight_color() call. May return NULL.
|
|
const char *highlight_color(const int id, const char *const what, const int modec)
|
|
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
static char name[20];
|
|
bool fg = false;
|
|
bool sp = false;
|
|
bool font = false;
|
|
|
|
if (id <= 0 || id > highlight_ga.ga_len) {
|
|
return NULL;
|
|
}
|
|
|
|
if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') {
|
|
fg = true;
|
|
} else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
|
|
&& TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') {
|
|
font = true;
|
|
} else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') {
|
|
sp = true;
|
|
} else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) {
|
|
return NULL;
|
|
}
|
|
|
|
int n;
|
|
|
|
if (modec == 'g') {
|
|
if (what[2] == '#' && ui_rgb_attached()) {
|
|
if (fg) {
|
|
n = hl_table[id - 1].sg_rgb_fg;
|
|
} else if (sp) {
|
|
n = hl_table[id - 1].sg_rgb_sp;
|
|
} else {
|
|
n = hl_table[id - 1].sg_rgb_bg;
|
|
}
|
|
if (n < 0 || n > 0xffffff) {
|
|
return NULL;
|
|
}
|
|
snprintf(name, sizeof(name), "#%06x", n);
|
|
return name;
|
|
}
|
|
if (fg) {
|
|
return coloridx_to_name(hl_table[id - 1].sg_rgb_fg_idx, hl_table[id - 1].sg_rgb_fg, name);
|
|
} else if (sp) {
|
|
return coloridx_to_name(hl_table[id - 1].sg_rgb_sp_idx, hl_table[id - 1].sg_rgb_sp, name);
|
|
} else {
|
|
return coloridx_to_name(hl_table[id - 1].sg_rgb_bg_idx, hl_table[id - 1].sg_rgb_bg, name);
|
|
}
|
|
}
|
|
if (font || sp) {
|
|
return NULL;
|
|
}
|
|
if (modec == 'c') {
|
|
if (fg) {
|
|
n = hl_table[id - 1].sg_cterm_fg - 1;
|
|
} else {
|
|
n = hl_table[id - 1].sg_cterm_bg - 1;
|
|
}
|
|
if (n < 0) {
|
|
return NULL;
|
|
}
|
|
snprintf(name, sizeof(name), "%d", n);
|
|
return name;
|
|
}
|
|
// term doesn't have color.
|
|
return NULL;
|
|
}
|
|
|
|
/// Output the syntax list header.
|
|
///
|
|
/// @param did_header did header already
|
|
/// @param outlen length of string that comes
|
|
/// @param id highlight group id
|
|
/// @param force_newline always start a new line
|
|
/// @return true when started a new line.
|
|
bool syn_list_header(const bool did_header, const int outlen, const int id, bool force_newline)
|
|
{
|
|
int endcol = 19;
|
|
bool newline = true;
|
|
int name_col = 0;
|
|
bool adjust = true;
|
|
|
|
if (!did_header) {
|
|
msg_putchar('\n');
|
|
if (got_int) {
|
|
return true;
|
|
}
|
|
msg_outtrans(hl_table[id - 1].sg_name, 0);
|
|
name_col = msg_col;
|
|
endcol = 15;
|
|
} else if ((ui_has(kUIMessages) || msg_silent) && !force_newline) {
|
|
msg_putchar(' ');
|
|
adjust = false;
|
|
} else if (msg_col + outlen + 1 >= Columns || force_newline) {
|
|
msg_putchar('\n');
|
|
if (got_int) {
|
|
return true;
|
|
}
|
|
} else {
|
|
if (msg_col >= endcol) { // wrap around is like starting a new line
|
|
newline = false;
|
|
}
|
|
}
|
|
|
|
if (adjust) {
|
|
if (msg_col >= endcol) {
|
|
// output at least one space
|
|
endcol = msg_col + 1;
|
|
}
|
|
|
|
msg_advance(endcol);
|
|
}
|
|
|
|
// Show "xxx" with the attributes.
|
|
if (!did_header) {
|
|
if (endcol == Columns - 1 && endcol <= name_col) {
|
|
msg_putchar(' ');
|
|
}
|
|
msg_puts_attr("xxx", syn_id2attr(id));
|
|
msg_putchar(' ');
|
|
}
|
|
|
|
return newline;
|
|
}
|
|
|
|
/// Set the attribute numbers for a highlight group.
|
|
/// Called after one of the attributes has changed.
|
|
/// @param idx corrected highlight index
|
|
static void set_hl_attr(int idx)
|
|
{
|
|
HlAttrs at_en = HLATTRS_INIT;
|
|
HlGroup *sgp = hl_table + idx;
|
|
|
|
at_en.cterm_ae_attr = (int16_t)sgp->sg_cterm;
|
|
at_en.cterm_fg_color = (int16_t)sgp->sg_cterm_fg;
|
|
at_en.cterm_bg_color = (int16_t)sgp->sg_cterm_bg;
|
|
at_en.rgb_ae_attr = (int16_t)sgp->sg_gui;
|
|
// FIXME(tarruda): The "unset value" for rgb is -1, but since hlgroup is
|
|
// initialized with 0 (by garray functions), check for sg_rgb_{f,b}g_name
|
|
// before setting attr_entry->{f,g}g_color to a other than -1
|
|
at_en.rgb_fg_color = sgp->sg_rgb_fg_idx != kColorIdxNone ? sgp->sg_rgb_fg : -1;
|
|
at_en.rgb_bg_color = sgp->sg_rgb_bg_idx != kColorIdxNone ? sgp->sg_rgb_bg : -1;
|
|
at_en.rgb_sp_color = sgp->sg_rgb_sp_idx != kColorIdxNone ? sgp->sg_rgb_sp : -1;
|
|
at_en.hl_blend = sgp->sg_blend;
|
|
|
|
sgp->sg_attr = hl_get_syn_attr(0, idx + 1, at_en);
|
|
|
|
// a cursor style uses this syn_id, make sure its attribute is updated.
|
|
if (cursor_mode_uses_syn_id(idx + 1)) {
|
|
ui_mode_info_set();
|
|
}
|
|
}
|
|
|
|
int syn_name2id(const char *name)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
if (name[0] == '@') {
|
|
// if we look up @aaa.bbb, we have to consider @aaa as well
|
|
return syn_check_group(name, strlen(name));
|
|
}
|
|
return syn_name2id_len(name, strlen(name));
|
|
}
|
|
|
|
/// Lookup a highlight group name and return its ID.
|
|
///
|
|
/// @param highlight name e.g. 'Cursor', 'Normal'
|
|
/// @return the highlight id, else 0 if \p name does not exist
|
|
int syn_name2id_len(const char *name, size_t len)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
char name_u[MAX_SYN_NAME + 1];
|
|
|
|
if (len == 0 || len > MAX_SYN_NAME) {
|
|
return 0;
|
|
}
|
|
|
|
// Avoid using stricmp() too much, it's slow on some systems
|
|
// Avoid alloc()/free(), these are slow too.
|
|
vim_memcpy_up(name_u, name, len);
|
|
name_u[len] = '\0';
|
|
|
|
// map_get(..., int) returns 0 when no key is present, which is
|
|
// the expected value for missing highlight group.
|
|
return map_get(cstr_t, int)(&highlight_unames, name_u);
|
|
}
|
|
|
|
/// Lookup a highlight group name and return its attributes.
|
|
/// Return zero if not found.
|
|
int syn_name2attr(const char *name)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
int id = syn_name2id(name);
|
|
|
|
if (id != 0) {
|
|
return syn_id2attr(id);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// Return true if highlight group "name" exists.
|
|
int highlight_exists(const char *name)
|
|
{
|
|
return syn_name2id(name) > 0;
|
|
}
|
|
|
|
/// Return the name of highlight group "id".
|
|
/// When not a valid ID return an empty string.
|
|
char *syn_id2name(int id)
|
|
{
|
|
if (id <= 0 || id > highlight_ga.ga_len) {
|
|
return "";
|
|
}
|
|
return hl_table[id - 1].sg_name;
|
|
}
|
|
|
|
/// Find highlight group name in the table and return its ID.
|
|
/// If it doesn't exist yet, a new entry is created.
|
|
///
|
|
/// @param pp Highlight group name
|
|
/// @param len length of \p pp
|
|
///
|
|
/// @return 0 for failure else the id of the group
|
|
int syn_check_group(const char *name, size_t len)
|
|
{
|
|
if (len > MAX_SYN_NAME) {
|
|
emsg(_(e_highlight_group_name_too_long));
|
|
return 0;
|
|
}
|
|
int id = syn_name2id_len(name, len);
|
|
if (id == 0) { // doesn't exist yet
|
|
return syn_add_group(name, len);
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/// Add new highlight group and return its ID.
|
|
///
|
|
/// @param name must be an allocated string, it will be consumed.
|
|
/// @return 0 for failure, else the allocated group id
|
|
/// @see syn_check_group
|
|
static int syn_add_group(const char *name, size_t len)
|
|
{
|
|
// Check that the name is valid (ASCII letters, digits, '_', '.', '@', '-').
|
|
for (size_t i = 0; i < len; i++) {
|
|
int c = (uint8_t)name[i];
|
|
if (!vim_isprintc(c)) {
|
|
emsg(_("E669: Unprintable character in group name"));
|
|
return 0;
|
|
} else if (!ASCII_ISALNUM(c) && c != '_' && c != '.' && c != '@' && c != '-') {
|
|
// '.' and '@' are allowed characters for use with treesitter capture names.
|
|
msg_source(HL_ATTR(HLF_W));
|
|
emsg(_(e_highlight_group_name_invalid_char));
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int scoped_parent = 0;
|
|
if (len > 1 && name[0] == '@') {
|
|
char *delim = xmemrchr(name, '.', len);
|
|
if (delim) {
|
|
scoped_parent = syn_check_group(name, (size_t)(delim - name));
|
|
}
|
|
}
|
|
|
|
// First call for this growarray: init growing array.
|
|
if (highlight_ga.ga_data == NULL) {
|
|
highlight_ga.ga_itemsize = sizeof(HlGroup);
|
|
ga_set_growsize(&highlight_ga, 10);
|
|
// 265 builtin groups, will always be used, plus some space
|
|
ga_grow(&highlight_ga, 300);
|
|
}
|
|
|
|
if (highlight_ga.ga_len >= MAX_HL_ID) {
|
|
emsg(_("E849: Too many highlight and syntax groups"));
|
|
return 0;
|
|
}
|
|
|
|
// Append another syntax_highlight entry.
|
|
HlGroup *hlgp = GA_APPEND_VIA_PTR(HlGroup, &highlight_ga);
|
|
CLEAR_POINTER(hlgp);
|
|
hlgp->sg_name = arena_memdupz(&highlight_arena, name, len);
|
|
hlgp->sg_rgb_bg = -1;
|
|
hlgp->sg_rgb_fg = -1;
|
|
hlgp->sg_rgb_sp = -1;
|
|
hlgp->sg_rgb_bg_idx = kColorIdxNone;
|
|
hlgp->sg_rgb_fg_idx = kColorIdxNone;
|
|
hlgp->sg_rgb_sp_idx = kColorIdxNone;
|
|
hlgp->sg_blend = -1;
|
|
hlgp->sg_name_u = arena_memdupz(&highlight_arena, name, len);
|
|
hlgp->sg_parent = scoped_parent;
|
|
// will get set to false by caller if settings are added
|
|
hlgp->sg_cleared = true;
|
|
vim_strup(hlgp->sg_name_u);
|
|
|
|
int id = highlight_ga.ga_len; // ID is index plus one
|
|
|
|
map_put(cstr_t, int)(&highlight_unames, hlgp->sg_name_u, id);
|
|
|
|
return id;
|
|
}
|
|
|
|
/// Translate a group ID to highlight attributes.
|
|
/// @see syn_attr2entry
|
|
int syn_id2attr(int hl_id)
|
|
{
|
|
bool optional = false;
|
|
return syn_ns_id2attr(-1, hl_id, &optional);
|
|
}
|
|
|
|
int syn_ns_id2attr(int ns_id, int hl_id, bool *optional)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
if (syn_ns_get_final_id(&ns_id, &hl_id)) {
|
|
// If the namespace explicitly defines a group to be empty, it is not optional
|
|
*optional = false;
|
|
}
|
|
HlGroup *sgp = &hl_table[hl_id - 1]; // index is ID minus one
|
|
|
|
int attr = ns_get_hl(&ns_id, hl_id, false, sgp->sg_set);
|
|
|
|
// if a highlight group is optional, don't use the global value
|
|
if (attr >= 0 || (*optional && ns_id > 0)) {
|
|
return attr;
|
|
}
|
|
return sgp->sg_attr;
|
|
}
|
|
|
|
/// Translate a group ID to the final group ID (following links).
|
|
int syn_get_final_id(int hl_id)
|
|
{
|
|
int ns_id = curwin->w_ns_hl_active;
|
|
syn_ns_get_final_id(&ns_id, &hl_id);
|
|
return hl_id;
|
|
}
|
|
|
|
bool syn_ns_get_final_id(int *ns_id, int *hl_idp)
|
|
{
|
|
int hl_id = *hl_idp;
|
|
bool used = false;
|
|
|
|
if (hl_id > highlight_ga.ga_len || hl_id < 1) {
|
|
*hl_idp = 0;
|
|
return false; // Can be called from eval!!
|
|
}
|
|
|
|
// Follow links until there is no more.
|
|
// Look out for loops! Break after 100 links.
|
|
for (int count = 100; --count >= 0;) {
|
|
HlGroup *sgp = &hl_table[hl_id - 1]; // index is ID minus one
|
|
|
|
// TODO(bfredl): when using "tmp" attribute (no link) the function might be
|
|
// called twice. it needs be smart enough to remember attr only to
|
|
// syn_id2attr time
|
|
int check = ns_get_hl(ns_id, hl_id, true, sgp->sg_set);
|
|
if (check == 0) {
|
|
*hl_idp = hl_id;
|
|
return true; // how dare! it broke the link!
|
|
} else if (check > 0) {
|
|
used = true;
|
|
hl_id = check;
|
|
continue;
|
|
}
|
|
|
|
if (sgp->sg_link > 0 && sgp->sg_link <= highlight_ga.ga_len) {
|
|
hl_id = sgp->sg_link;
|
|
} else if (sgp->sg_cleared && sgp->sg_parent > 0) {
|
|
hl_id = sgp->sg_parent;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
*hl_idp = hl_id;
|
|
return used;
|
|
}
|
|
|
|
/// Refresh the color attributes of all highlight groups.
|
|
void highlight_attr_set_all(void)
|
|
{
|
|
for (int idx = 0; idx < highlight_ga.ga_len; idx++) {
|
|
HlGroup *sgp = &hl_table[idx];
|
|
if (sgp->sg_rgb_bg_idx == kColorIdxFg) {
|
|
sgp->sg_rgb_bg = normal_fg;
|
|
} else if (sgp->sg_rgb_bg_idx == kColorIdxBg) {
|
|
sgp->sg_rgb_bg = normal_bg;
|
|
}
|
|
if (sgp->sg_rgb_fg_idx == kColorIdxFg) {
|
|
sgp->sg_rgb_fg = normal_fg;
|
|
} else if (sgp->sg_rgb_fg_idx == kColorIdxBg) {
|
|
sgp->sg_rgb_fg = normal_bg;
|
|
}
|
|
if (sgp->sg_rgb_sp_idx == kColorIdxFg) {
|
|
sgp->sg_rgb_sp = normal_fg;
|
|
} else if (sgp->sg_rgb_sp_idx == kColorIdxBg) {
|
|
sgp->sg_rgb_sp = normal_bg;
|
|
}
|
|
set_hl_attr(idx);
|
|
}
|
|
}
|
|
|
|
// Apply difference between User[1-9] and HLF_S to HLF_SNC.
|
|
static void combine_stl_hlt(int id, int id_S, int id_alt, int hlcnt, int i, int hlf, int *table)
|
|
FUNC_ATTR_NONNULL_ALL
|
|
{
|
|
HlGroup *const hlt = hl_table;
|
|
|
|
if (id_alt == 0) {
|
|
CLEAR_POINTER(&hlt[hlcnt + i]);
|
|
hlt[hlcnt + i].sg_cterm = highlight_attr[hlf];
|
|
hlt[hlcnt + i].sg_gui = highlight_attr[hlf];
|
|
} else {
|
|
memmove(&hlt[hlcnt + i], &hlt[id_alt - 1], sizeof(HlGroup));
|
|
}
|
|
hlt[hlcnt + i].sg_link = 0;
|
|
|
|
hlt[hlcnt + i].sg_cterm ^= hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
|
|
if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) {
|
|
hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg;
|
|
}
|
|
if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) {
|
|
hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg;
|
|
}
|
|
hlt[hlcnt + i].sg_gui ^= hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
|
|
if (hlt[id - 1].sg_rgb_fg != hlt[id_S - 1].sg_rgb_fg) {
|
|
hlt[hlcnt + i].sg_rgb_fg = hlt[id - 1].sg_rgb_fg;
|
|
}
|
|
if (hlt[id - 1].sg_rgb_bg != hlt[id_S - 1].sg_rgb_bg) {
|
|
hlt[hlcnt + i].sg_rgb_bg = hlt[id - 1].sg_rgb_bg;
|
|
}
|
|
if (hlt[id - 1].sg_rgb_sp != hlt[id_S - 1].sg_rgb_sp) {
|
|
hlt[hlcnt + i].sg_rgb_sp = hlt[id - 1].sg_rgb_sp;
|
|
}
|
|
highlight_ga.ga_len = hlcnt + i + 1;
|
|
set_hl_attr(hlcnt + i); // At long last we can apply
|
|
table[i] = syn_id2attr(hlcnt + i + 1);
|
|
}
|
|
|
|
/// Translate highlight groups into attributes in highlight_attr[] and set up
|
|
/// the user highlights User1..9. A set of corresponding highlights to use on
|
|
/// top of HLF_SNC is computed. Called only when nvim starts and upon first
|
|
/// screen redraw after any :highlight command.
|
|
void highlight_changed(void)
|
|
{
|
|
char userhl[30]; // use 30 to avoid compiler warning
|
|
int id_S = -1;
|
|
int id_SNC = 0;
|
|
|
|
need_highlight_changed = false;
|
|
|
|
/// Translate builtin highlight groups into attributes for quick lookup.
|
|
for (int hlf = 0; hlf < HLF_COUNT; hlf++) {
|
|
int id = syn_check_group(hlf_names[hlf], strlen(hlf_names[hlf]));
|
|
if (id == 0) {
|
|
abort();
|
|
}
|
|
int ns_id = -1;
|
|
int final_id = id;
|
|
syn_ns_get_final_id(&ns_id, &final_id);
|
|
if (hlf == HLF_SNC) {
|
|
id_SNC = final_id;
|
|
} else if (hlf == HLF_S) {
|
|
id_S = final_id;
|
|
}
|
|
|
|
highlight_attr[hlf] = hl_get_ui_attr(ns_id, hlf, final_id, hlf == HLF_INACTIVE);
|
|
|
|
if (highlight_attr[hlf] != highlight_attr_last[hlf]) {
|
|
if (hlf == HLF_MSG) {
|
|
clear_cmdline = true;
|
|
HlAttrs attrs = syn_attr2entry(highlight_attr[hlf]);
|
|
msg_grid.blending = attrs.hl_blend > -1;
|
|
}
|
|
ui_call_hl_group_set(cstr_as_string(hlf_names[hlf]),
|
|
highlight_attr[hlf]);
|
|
highlight_attr_last[hlf] = highlight_attr[hlf];
|
|
}
|
|
}
|
|
|
|
// sentinel value. used when no highlight namespace is active
|
|
highlight_attr[HLF_COUNT] = 0;
|
|
|
|
// Setup the user highlights
|
|
//
|
|
// Temporarily utilize 10 more hl entries:
|
|
// 9 for User1-User9 combined with StatusLineNC
|
|
// 1 for StatusLine default
|
|
// Must to be in there simultaneously in case of table overflows in
|
|
// get_attr_entry()
|
|
ga_grow(&highlight_ga, 10);
|
|
int hlcnt = highlight_ga.ga_len;
|
|
if (id_S == -1) {
|
|
// Make sure id_S is always valid to simplify code below. Use the last entry
|
|
CLEAR_POINTER(&hl_table[hlcnt + 9]);
|
|
id_S = hlcnt + 10;
|
|
}
|
|
for (int i = 0; i < 9; i++) {
|
|
snprintf(userhl, sizeof(userhl), "User%d", i + 1);
|
|
int id = syn_name2id(userhl);
|
|
if (id == 0) {
|
|
highlight_user[i] = 0;
|
|
highlight_stlnc[i] = 0;
|
|
} else {
|
|
highlight_user[i] = syn_id2attr(id);
|
|
combine_stl_hlt(id, id_S, id_SNC, hlcnt, i, HLF_SNC, highlight_stlnc);
|
|
}
|
|
}
|
|
highlight_ga.ga_len = hlcnt;
|
|
|
|
decor_provider_invalidate_hl();
|
|
}
|
|
|
|
/// Handle command line completion for :highlight command.
|
|
void set_context_in_highlight_cmd(expand_T *xp, const char *arg)
|
|
{
|
|
// Default: expand group names.
|
|
xp->xp_context = EXPAND_HIGHLIGHT;
|
|
xp->xp_pattern = (char *)arg;
|
|
include_link = 2;
|
|
include_default = 1;
|
|
|
|
if (*arg == NUL) {
|
|
return;
|
|
}
|
|
|
|
// (part of) subcommand already typed
|
|
const char *p = skiptowhite(arg);
|
|
if (*p == NUL) {
|
|
return;
|
|
}
|
|
|
|
// past "default" or group name
|
|
include_default = 0;
|
|
if (strncmp("default", arg, (unsigned)(p - arg)) == 0) {
|
|
arg = skipwhite(p);
|
|
xp->xp_pattern = (char *)arg;
|
|
p = skiptowhite(arg);
|
|
}
|
|
if (*p == NUL) {
|
|
return;
|
|
}
|
|
|
|
// past group name
|
|
include_link = 0;
|
|
if (arg[1] == 'i' && arg[0] == 'N') {
|
|
highlight_list();
|
|
}
|
|
if (strncmp("link", arg, (unsigned)(p - arg)) == 0
|
|
|| strncmp("clear", arg, (unsigned)(p - arg)) == 0) {
|
|
xp->xp_pattern = skipwhite(p);
|
|
p = skiptowhite(xp->xp_pattern);
|
|
if (*p != NUL) { // past first group name
|
|
xp->xp_pattern = skipwhite(p);
|
|
p = skiptowhite(xp->xp_pattern);
|
|
}
|
|
}
|
|
if (*p != NUL) { // past group name(s)
|
|
xp->xp_context = EXPAND_NOTHING;
|
|
}
|
|
}
|
|
|
|
/// List highlighting matches in a nice way.
|
|
static void highlight_list(void)
|
|
{
|
|
for (int i = 10; --i >= 0;) {
|
|
highlight_list_two(i, HL_ATTR(HLF_D));
|
|
}
|
|
for (int i = 40; --i >= 0;) {
|
|
highlight_list_two(99, 0);
|
|
}
|
|
}
|
|
|
|
static void highlight_list_two(int cnt, int attr)
|
|
{
|
|
msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr);
|
|
msg_clr_eos();
|
|
ui_flush();
|
|
os_delay(cnt == 99 ? 40 : (uint64_t)cnt * 50, false);
|
|
}
|
|
|
|
/// Function given to ExpandGeneric() to obtain the list of group names.
|
|
char *get_highlight_name(expand_T *const xp, int idx)
|
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
|
{
|
|
return (char *)get_highlight_name_ext(xp, idx, true);
|
|
}
|
|
|
|
/// Obtain a highlight group name.
|
|
///
|
|
/// @param skip_cleared if true don't return a cleared entry.
|
|
const char *get_highlight_name_ext(expand_T *xp, int idx, bool skip_cleared)
|
|
FUNC_ATTR_WARN_UNUSED_RESULT
|
|
{
|
|
if (idx < 0) {
|
|
return NULL;
|
|
}
|
|
|
|
// Items are never removed from the table, skip the ones that were cleared.
|
|
if (skip_cleared && idx < highlight_ga.ga_len && hl_table[idx].sg_cleared) {
|
|
return "";
|
|
}
|
|
|
|
if (idx == highlight_ga.ga_len && include_none != 0) {
|
|
return "none";
|
|
} else if (idx == highlight_ga.ga_len + include_none
|
|
&& include_default != 0) {
|
|
return "default";
|
|
} else if (idx == highlight_ga.ga_len + include_none + include_default
|
|
&& include_link != 0) {
|
|
return "link";
|
|
} else if (idx == highlight_ga.ga_len + include_none + include_default + 1
|
|
&& include_link != 0) {
|
|
return "clear";
|
|
} else if (idx >= highlight_ga.ga_len) {
|
|
return NULL;
|
|
}
|
|
return hl_table[idx].sg_name;
|
|
}
|
|
|
|
color_name_table_T color_name_table[] = {
|
|
// Colors from rgb.txt
|
|
{ "AliceBlue", RGB_(0xf0, 0xf8, 0xff) },
|
|
{ "AntiqueWhite", RGB_(0xfa, 0xeb, 0xd7) },
|
|
{ "AntiqueWhite1", RGB_(0xff, 0xef, 0xdb) },
|
|
{ "AntiqueWhite2", RGB_(0xee, 0xdf, 0xcc) },
|
|
{ "AntiqueWhite3", RGB_(0xcd, 0xc0, 0xb0) },
|
|
{ "AntiqueWhite4", RGB_(0x8b, 0x83, 0x78) },
|
|
{ "Aqua", RGB_(0x00, 0xff, 0xff) },
|
|
{ "Aquamarine", RGB_(0x7f, 0xff, 0xd4) },
|
|
{ "Aquamarine1", RGB_(0x7f, 0xff, 0xd4) },
|
|
{ "Aquamarine2", RGB_(0x76, 0xee, 0xc6) },
|
|
{ "Aquamarine3", RGB_(0x66, 0xcd, 0xaa) },
|
|
{ "Aquamarine4", RGB_(0x45, 0x8b, 0x74) },
|
|
{ "Azure", RGB_(0xf0, 0xff, 0xff) },
|
|
{ "Azure1", RGB_(0xf0, 0xff, 0xff) },
|
|
{ "Azure2", RGB_(0xe0, 0xee, 0xee) },
|
|
{ "Azure3", RGB_(0xc1, 0xcd, 0xcd) },
|
|
{ "Azure4", RGB_(0x83, 0x8b, 0x8b) },
|
|
{ "Beige", RGB_(0xf5, 0xf5, 0xdc) },
|
|
{ "Bisque", RGB_(0xff, 0xe4, 0xc4) },
|
|
{ "Bisque1", RGB_(0xff, 0xe4, 0xc4) },
|
|
{ "Bisque2", RGB_(0xee, 0xd5, 0xb7) },
|
|
{ "Bisque3", RGB_(0xcd, 0xb7, 0x9e) },
|
|
{ "Bisque4", RGB_(0x8b, 0x7d, 0x6b) },
|
|
{ "Black", RGB_(0x00, 0x00, 0x00) },
|
|
{ "BlanchedAlmond", RGB_(0xff, 0xeb, 0xcd) },
|
|
{ "Blue", RGB_(0x00, 0x00, 0xff) },
|
|
{ "Blue1", RGB_(0x0, 0x0, 0xff) },
|
|
{ "Blue2", RGB_(0x0, 0x0, 0xee) },
|
|
{ "Blue3", RGB_(0x0, 0x0, 0xcd) },
|
|
{ "Blue4", RGB_(0x0, 0x0, 0x8b) },
|
|
{ "BlueViolet", RGB_(0x8a, 0x2b, 0xe2) },
|
|
{ "Brown", RGB_(0xa5, 0x2a, 0x2a) },
|
|
{ "Brown1", RGB_(0xff, 0x40, 0x40) },
|
|
{ "Brown2", RGB_(0xee, 0x3b, 0x3b) },
|
|
{ "Brown3", RGB_(0xcd, 0x33, 0x33) },
|
|
{ "Brown4", RGB_(0x8b, 0x23, 0x23) },
|
|
{ "BurlyWood", RGB_(0xde, 0xb8, 0x87) },
|
|
{ "Burlywood1", RGB_(0xff, 0xd3, 0x9b) },
|
|
{ "Burlywood2", RGB_(0xee, 0xc5, 0x91) },
|
|
{ "Burlywood3", RGB_(0xcd, 0xaa, 0x7d) },
|
|
{ "Burlywood4", RGB_(0x8b, 0x73, 0x55) },
|
|
{ "CadetBlue", RGB_(0x5f, 0x9e, 0xa0) },
|
|
{ "CadetBlue1", RGB_(0x98, 0xf5, 0xff) },
|
|
{ "CadetBlue2", RGB_(0x8e, 0xe5, 0xee) },
|
|
{ "CadetBlue3", RGB_(0x7a, 0xc5, 0xcd) },
|
|
{ "CadetBlue4", RGB_(0x53, 0x86, 0x8b) },
|
|
{ "ChartReuse", RGB_(0x7f, 0xff, 0x00) },
|
|
{ "Chartreuse1", RGB_(0x7f, 0xff, 0x0) },
|
|
{ "Chartreuse2", RGB_(0x76, 0xee, 0x0) },
|
|
{ "Chartreuse3", RGB_(0x66, 0xcd, 0x0) },
|
|
{ "Chartreuse4", RGB_(0x45, 0x8b, 0x0) },
|
|
{ "Chocolate", RGB_(0xd2, 0x69, 0x1e) },
|
|
{ "Chocolate1", RGB_(0xff, 0x7f, 0x24) },
|
|
{ "Chocolate2", RGB_(0xee, 0x76, 0x21) },
|
|
{ "Chocolate3", RGB_(0xcd, 0x66, 0x1d) },
|
|
{ "Chocolate4", RGB_(0x8b, 0x45, 0x13) },
|
|
{ "Coral", RGB_(0xff, 0x7f, 0x50) },
|
|
{ "Coral1", RGB_(0xff, 0x72, 0x56) },
|
|
{ "Coral2", RGB_(0xee, 0x6a, 0x50) },
|
|
{ "Coral3", RGB_(0xcd, 0x5b, 0x45) },
|
|
{ "Coral4", RGB_(0x8b, 0x3e, 0x2f) },
|
|
{ "CornFlowerBlue", RGB_(0x64, 0x95, 0xed) },
|
|
{ "Cornsilk", RGB_(0xff, 0xf8, 0xdc) },
|
|
{ "Cornsilk1", RGB_(0xff, 0xf8, 0xdc) },
|
|
{ "Cornsilk2", RGB_(0xee, 0xe8, 0xcd) },
|
|
{ "Cornsilk3", RGB_(0xcd, 0xc8, 0xb1) },
|
|
{ "Cornsilk4", RGB_(0x8b, 0x88, 0x78) },
|
|
{ "Crimson", RGB_(0xdc, 0x14, 0x3c) },
|
|
{ "Cyan", RGB_(0x00, 0xff, 0xff) },
|
|
{ "Cyan1", RGB_(0x0, 0xff, 0xff) },
|
|
{ "Cyan2", RGB_(0x0, 0xee, 0xee) },
|
|
{ "Cyan3", RGB_(0x0, 0xcd, 0xcd) },
|
|
{ "Cyan4", RGB_(0x0, 0x8b, 0x8b) },
|
|
{ "DarkBlue", RGB_(0x00, 0x00, 0x8b) },
|
|
{ "DarkCyan", RGB_(0x00, 0x8b, 0x8b) },
|
|
{ "DarkGoldenrod", RGB_(0xb8, 0x86, 0x0b) },
|
|
{ "DarkGoldenrod1", RGB_(0xff, 0xb9, 0xf) },
|
|
{ "DarkGoldenrod2", RGB_(0xee, 0xad, 0xe) },
|
|
{ "DarkGoldenrod3", RGB_(0xcd, 0x95, 0xc) },
|
|
{ "DarkGoldenrod4", RGB_(0x8b, 0x65, 0x8) },
|
|
{ "DarkGray", RGB_(0xa9, 0xa9, 0xa9) },
|
|
{ "DarkGreen", RGB_(0x00, 0x64, 0x00) },
|
|
{ "DarkGrey", RGB_(0xa9, 0xa9, 0xa9) },
|
|
{ "DarkKhaki", RGB_(0xbd, 0xb7, 0x6b) },
|
|
{ "DarkMagenta", RGB_(0x8b, 0x00, 0x8b) },
|
|
{ "DarkOliveGreen", RGB_(0x55, 0x6b, 0x2f) },
|
|
{ "DarkOliveGreen1", RGB_(0xca, 0xff, 0x70) },
|
|
{ "DarkOliveGreen2", RGB_(0xbc, 0xee, 0x68) },
|
|
{ "DarkOliveGreen3", RGB_(0xa2, 0xcd, 0x5a) },
|
|
{ "DarkOliveGreen4", RGB_(0x6e, 0x8b, 0x3d) },
|
|
{ "DarkOrange", RGB_(0xff, 0x8c, 0x00) },
|
|
{ "DarkOrange1", RGB_(0xff, 0x7f, 0x0) },
|
|
{ "DarkOrange2", RGB_(0xee, 0x76, 0x0) },
|
|
{ "DarkOrange3", RGB_(0xcd, 0x66, 0x0) },
|
|
{ "DarkOrange4", RGB_(0x8b, 0x45, 0x0) },
|
|
{ "DarkOrchid", RGB_(0x99, 0x32, 0xcc) },
|
|
{ "DarkOrchid1", RGB_(0xbf, 0x3e, 0xff) },
|
|
{ "DarkOrchid2", RGB_(0xb2, 0x3a, 0xee) },
|
|
{ "DarkOrchid3", RGB_(0x9a, 0x32, 0xcd) },
|
|
{ "DarkOrchid4", RGB_(0x68, 0x22, 0x8b) },
|
|
{ "DarkRed", RGB_(0x8b, 0x00, 0x00) },
|
|
{ "DarkSalmon", RGB_(0xe9, 0x96, 0x7a) },
|
|
{ "DarkSeaGreen", RGB_(0x8f, 0xbc, 0x8f) },
|
|
{ "DarkSeaGreen1", RGB_(0xc1, 0xff, 0xc1) },
|
|
{ "DarkSeaGreen2", RGB_(0xb4, 0xee, 0xb4) },
|
|
{ "DarkSeaGreen3", RGB_(0x9b, 0xcd, 0x9b) },
|
|
{ "DarkSeaGreen4", RGB_(0x69, 0x8b, 0x69) },
|
|
{ "DarkSlateBlue", RGB_(0x48, 0x3d, 0x8b) },
|
|
{ "DarkSlateGray", RGB_(0x2f, 0x4f, 0x4f) },
|
|
{ "DarkSlateGray1", RGB_(0x97, 0xff, 0xff) },
|
|
{ "DarkSlateGray2", RGB_(0x8d, 0xee, 0xee) },
|
|
{ "DarkSlateGray3", RGB_(0x79, 0xcd, 0xcd) },
|
|
{ "DarkSlateGray4", RGB_(0x52, 0x8b, 0x8b) },
|
|
{ "DarkSlateGrey", RGB_(0x2f, 0x4f, 0x4f) },
|
|
{ "DarkTurquoise", RGB_(0x00, 0xce, 0xd1) },
|
|
{ "DarkViolet", RGB_(0x94, 0x00, 0xd3) },
|
|
{ "DarkYellow", RGB_(0xbb, 0xbb, 0x00) },
|
|
{ "DeepPink", RGB_(0xff, 0x14, 0x93) },
|
|
{ "DeepPink1", RGB_(0xff, 0x14, 0x93) },
|
|
{ "DeepPink2", RGB_(0xee, 0x12, 0x89) },
|
|
{ "DeepPink3", RGB_(0xcd, 0x10, 0x76) },
|
|
{ "DeepPink4", RGB_(0x8b, 0xa, 0x50) },
|
|
{ "DeepSkyBlue", RGB_(0x00, 0xbf, 0xff) },
|
|
{ "DeepSkyBlue1", RGB_(0x0, 0xbf, 0xff) },
|
|
{ "DeepSkyBlue2", RGB_(0x0, 0xb2, 0xee) },
|
|
{ "DeepSkyBlue3", RGB_(0x0, 0x9a, 0xcd) },
|
|
{ "DeepSkyBlue4", RGB_(0x0, 0x68, 0x8b) },
|
|
{ "DimGray", RGB_(0x69, 0x69, 0x69) },
|
|
{ "DimGrey", RGB_(0x69, 0x69, 0x69) },
|
|
{ "DodgerBlue", RGB_(0x1e, 0x90, 0xff) },
|
|
{ "DodgerBlue1", RGB_(0x1e, 0x90, 0xff) },
|
|
{ "DodgerBlue2", RGB_(0x1c, 0x86, 0xee) },
|
|
{ "DodgerBlue3", RGB_(0x18, 0x74, 0xcd) },
|
|
{ "DodgerBlue4", RGB_(0x10, 0x4e, 0x8b) },
|
|
{ "Firebrick", RGB_(0xb2, 0x22, 0x22) },
|
|
{ "Firebrick1", RGB_(0xff, 0x30, 0x30) },
|
|
{ "Firebrick2", RGB_(0xee, 0x2c, 0x2c) },
|
|
{ "Firebrick3", RGB_(0xcd, 0x26, 0x26) },
|
|
{ "Firebrick4", RGB_(0x8b, 0x1a, 0x1a) },
|
|
{ "FloralWhite", RGB_(0xff, 0xfa, 0xf0) },
|
|
{ "ForestGreen", RGB_(0x22, 0x8b, 0x22) },
|
|
{ "Fuchsia", RGB_(0xff, 0x00, 0xff) },
|
|
{ "Gainsboro", RGB_(0xdc, 0xdc, 0xdc) },
|
|
{ "GhostWhite", RGB_(0xf8, 0xf8, 0xff) },
|
|
{ "Gold", RGB_(0xff, 0xd7, 0x00) },
|
|
{ "Gold1", RGB_(0xff, 0xd7, 0x0) },
|
|
{ "Gold2", RGB_(0xee, 0xc9, 0x0) },
|
|
{ "Gold3", RGB_(0xcd, 0xad, 0x0) },
|
|
{ "Gold4", RGB_(0x8b, 0x75, 0x0) },
|
|
{ "Goldenrod", RGB_(0xda, 0xa5, 0x20) },
|
|
{ "Goldenrod1", RGB_(0xff, 0xc1, 0x25) },
|
|
{ "Goldenrod2", RGB_(0xee, 0xb4, 0x22) },
|
|
{ "Goldenrod3", RGB_(0xcd, 0x9b, 0x1d) },
|
|
{ "Goldenrod4", RGB_(0x8b, 0x69, 0x14) },
|
|
{ "Gray", RGB_(0x80, 0x80, 0x80) },
|
|
{ "Gray0", RGB_(0x0, 0x0, 0x0) },
|
|
{ "Gray1", RGB_(0x3, 0x3, 0x3) },
|
|
{ "Gray10", RGB_(0x1a, 0x1a, 0x1a) },
|
|
{ "Gray100", RGB_(0xff, 0xff, 0xff) },
|
|
{ "Gray11", RGB_(0x1c, 0x1c, 0x1c) },
|
|
{ "Gray12", RGB_(0x1f, 0x1f, 0x1f) },
|
|
{ "Gray13", RGB_(0x21, 0x21, 0x21) },
|
|
{ "Gray14", RGB_(0x24, 0x24, 0x24) },
|
|
{ "Gray15", RGB_(0x26, 0x26, 0x26) },
|
|
{ "Gray16", RGB_(0x29, 0x29, 0x29) },
|
|
{ "Gray17", RGB_(0x2b, 0x2b, 0x2b) },
|
|
{ "Gray18", RGB_(0x2e, 0x2e, 0x2e) },
|
|
{ "Gray19", RGB_(0x30, 0x30, 0x30) },
|
|
{ "Gray2", RGB_(0x5, 0x5, 0x5) },
|
|
{ "Gray20", RGB_(0x33, 0x33, 0x33) },
|
|
{ "Gray21", RGB_(0x36, 0x36, 0x36) },
|
|
{ "Gray22", RGB_(0x38, 0x38, 0x38) },
|
|
{ "Gray23", RGB_(0x3b, 0x3b, 0x3b) },
|
|
{ "Gray24", RGB_(0x3d, 0x3d, 0x3d) },
|
|
{ "Gray25", RGB_(0x40, 0x40, 0x40) },
|
|
{ "Gray26", RGB_(0x42, 0x42, 0x42) },
|
|
{ "Gray27", RGB_(0x45, 0x45, 0x45) },
|
|
{ "Gray28", RGB_(0x47, 0x47, 0x47) },
|
|
{ "Gray29", RGB_(0x4a, 0x4a, 0x4a) },
|
|
{ "Gray3", RGB_(0x8, 0x8, 0x8) },
|
|
{ "Gray30", RGB_(0x4d, 0x4d, 0x4d) },
|
|
{ "Gray31", RGB_(0x4f, 0x4f, 0x4f) },
|
|
{ "Gray32", RGB_(0x52, 0x52, 0x52) },
|
|
{ "Gray33", RGB_(0x54, 0x54, 0x54) },
|
|
{ "Gray34", RGB_(0x57, 0x57, 0x57) },
|
|
{ "Gray35", RGB_(0x59, 0x59, 0x59) },
|
|
{ "Gray36", RGB_(0x5c, 0x5c, 0x5c) },
|
|
{ "Gray37", RGB_(0x5e, 0x5e, 0x5e) },
|
|
{ "Gray38", RGB_(0x61, 0x61, 0x61) },
|
|
{ "Gray39", RGB_(0x63, 0x63, 0x63) },
|
|
{ "Gray4", RGB_(0xa, 0xa, 0xa) },
|
|
{ "Gray40", RGB_(0x66, 0x66, 0x66) },
|
|
{ "Gray41", RGB_(0x69, 0x69, 0x69) },
|
|
{ "Gray42", RGB_(0x6b, 0x6b, 0x6b) },
|
|
{ "Gray43", RGB_(0x6e, 0x6e, 0x6e) },
|
|
{ "Gray44", RGB_(0x70, 0x70, 0x70) },
|
|
{ "Gray45", RGB_(0x73, 0x73, 0x73) },
|
|
{ "Gray46", RGB_(0x75, 0x75, 0x75) },
|
|
{ "Gray47", RGB_(0x78, 0x78, 0x78) },
|
|
{ "Gray48", RGB_(0x7a, 0x7a, 0x7a) },
|
|
{ "Gray49", RGB_(0x7d, 0x7d, 0x7d) },
|
|
{ "Gray5", RGB_(0xd, 0xd, 0xd) },
|
|
{ "Gray50", RGB_(0x7f, 0x7f, 0x7f) },
|
|
{ "Gray51", RGB_(0x82, 0x82, 0x82) },
|
|
{ "Gray52", RGB_(0x85, 0x85, 0x85) },
|
|
{ "Gray53", RGB_(0x87, 0x87, 0x87) },
|
|
{ "Gray54", RGB_(0x8a, 0x8a, 0x8a) },
|
|
{ "Gray55", RGB_(0x8c, 0x8c, 0x8c) },
|
|
{ "Gray56", RGB_(0x8f, 0x8f, 0x8f) },
|
|
{ "Gray57", RGB_(0x91, 0x91, 0x91) },
|
|
{ "Gray58", RGB_(0x94, 0x94, 0x94) },
|
|
{ "Gray59", RGB_(0x96, 0x96, 0x96) },
|
|
{ "Gray6", RGB_(0xf, 0xf, 0xf) },
|
|
{ "Gray60", RGB_(0x99, 0x99, 0x99) },
|
|
{ "Gray61", RGB_(0x9c, 0x9c, 0x9c) },
|
|
{ "Gray62", RGB_(0x9e, 0x9e, 0x9e) },
|
|
{ "Gray63", RGB_(0xa1, 0xa1, 0xa1) },
|
|
{ "Gray64", RGB_(0xa3, 0xa3, 0xa3) },
|
|
{ "Gray65", RGB_(0xa6, 0xa6, 0xa6) },
|
|
{ "Gray66", RGB_(0xa8, 0xa8, 0xa8) },
|
|
{ "Gray67", RGB_(0xab, 0xab, 0xab) },
|
|
{ "Gray68", RGB_(0xad, 0xad, 0xad) },
|
|
{ "Gray69", RGB_(0xb0, 0xb0, 0xb0) },
|
|
{ "Gray7", RGB_(0x12, 0x12, 0x12) },
|
|
{ "Gray70", RGB_(0xb3, 0xb3, 0xb3) },
|
|
{ "Gray71", RGB_(0xb5, 0xb5, 0xb5) },
|
|
{ "Gray72", RGB_(0xb8, 0xb8, 0xb8) },
|
|
{ "Gray73", RGB_(0xba, 0xba, 0xba) },
|
|
{ "Gray74", RGB_(0xbd, 0xbd, 0xbd) },
|
|
{ "Gray75", RGB_(0xbf, 0xbf, 0xbf) },
|
|
{ "Gray76", RGB_(0xc2, 0xc2, 0xc2) },
|
|
{ "Gray77", RGB_(0xc4, 0xc4, 0xc4) },
|
|
{ "Gray78", RGB_(0xc7, 0xc7, 0xc7) },
|
|
{ "Gray79", RGB_(0xc9, 0xc9, 0xc9) },
|
|
{ "Gray8", RGB_(0x14, 0x14, 0x14) },
|
|
{ "Gray80", RGB_(0xcc, 0xcc, 0xcc) },
|
|
{ "Gray81", RGB_(0xcf, 0xcf, 0xcf) },
|
|
{ "Gray82", RGB_(0xd1, 0xd1, 0xd1) },
|
|
{ "Gray83", RGB_(0xd4, 0xd4, 0xd4) },
|
|
{ "Gray84", RGB_(0xd6, 0xd6, 0xd6) },
|
|
{ "Gray85", RGB_(0xd9, 0xd9, 0xd9) },
|
|
{ "Gray86", RGB_(0xdb, 0xdb, 0xdb) },
|
|
{ "Gray87", RGB_(0xde, 0xde, 0xde) },
|
|
{ "Gray88", RGB_(0xe0, 0xe0, 0xe0) },
|
|
{ "Gray89", RGB_(0xe3, 0xe3, 0xe3) },
|
|
{ "Gray9", RGB_(0x17, 0x17, 0x17) },
|
|
{ "Gray90", RGB_(0xe5, 0xe5, 0xe5) },
|
|
{ "Gray91", RGB_(0xe8, 0xe8, 0xe8) },
|
|
{ "Gray92", RGB_(0xeb, 0xeb, 0xeb) },
|
|
{ "Gray93", RGB_(0xed, 0xed, 0xed) },
|
|
{ "Gray94", RGB_(0xf0, 0xf0, 0xf0) },
|
|
{ "Gray95", RGB_(0xf2, 0xf2, 0xf2) },
|
|
{ "Gray96", RGB_(0xf5, 0xf5, 0xf5) },
|
|
{ "Gray97", RGB_(0xf7, 0xf7, 0xf7) },
|
|
{ "Gray98", RGB_(0xfa, 0xfa, 0xfa) },
|
|
{ "Gray99", RGB_(0xfc, 0xfc, 0xfc) },
|
|
{ "Green", RGB_(0x00, 0x80, 0x00) },
|
|
{ "Green1", RGB_(0x0, 0xff, 0x0) },
|
|
{ "Green2", RGB_(0x0, 0xee, 0x0) },
|
|
{ "Green3", RGB_(0x0, 0xcd, 0x0) },
|
|
{ "Green4", RGB_(0x0, 0x8b, 0x0) },
|
|
{ "GreenYellow", RGB_(0xad, 0xff, 0x2f) },
|
|
{ "Grey", RGB_(0x80, 0x80, 0x80) },
|
|
{ "Grey0", RGB_(0x0, 0x0, 0x0) },
|
|
{ "Grey1", RGB_(0x3, 0x3, 0x3) },
|
|
{ "Grey10", RGB_(0x1a, 0x1a, 0x1a) },
|
|
{ "Grey100", RGB_(0xff, 0xff, 0xff) },
|
|
{ "Grey11", RGB_(0x1c, 0x1c, 0x1c) },
|
|
{ "Grey12", RGB_(0x1f, 0x1f, 0x1f) },
|
|
{ "Grey13", RGB_(0x21, 0x21, 0x21) },
|
|
{ "Grey14", RGB_(0x24, 0x24, 0x24) },
|
|
{ "Grey15", RGB_(0x26, 0x26, 0x26) },
|
|
{ "Grey16", RGB_(0x29, 0x29, 0x29) },
|
|
{ "Grey17", RGB_(0x2b, 0x2b, 0x2b) },
|
|
{ "Grey18", RGB_(0x2e, 0x2e, 0x2e) },
|
|
{ "Grey19", RGB_(0x30, 0x30, 0x30) },
|
|
{ "Grey2", RGB_(0x5, 0x5, 0x5) },
|
|
{ "Grey20", RGB_(0x33, 0x33, 0x33) },
|
|
{ "Grey21", RGB_(0x36, 0x36, 0x36) },
|
|
{ "Grey22", RGB_(0x38, 0x38, 0x38) },
|
|
{ "Grey23", RGB_(0x3b, 0x3b, 0x3b) },
|
|
{ "Grey24", RGB_(0x3d, 0x3d, 0x3d) },
|
|
{ "Grey25", RGB_(0x40, 0x40, 0x40) },
|
|
{ "Grey26", RGB_(0x42, 0x42, 0x42) },
|
|
{ "Grey27", RGB_(0x45, 0x45, 0x45) },
|
|
{ "Grey28", RGB_(0x47, 0x47, 0x47) },
|
|
{ "Grey29", RGB_(0x4a, 0x4a, 0x4a) },
|
|
{ "Grey3", RGB_(0x8, 0x8, 0x8) },
|
|
{ "Grey30", RGB_(0x4d, 0x4d, 0x4d) },
|
|
{ "Grey31", RGB_(0x4f, 0x4f, 0x4f) },
|
|
{ "Grey32", RGB_(0x52, 0x52, 0x52) },
|
|
{ "Grey33", RGB_(0x54, 0x54, 0x54) },
|
|
{ "Grey34", RGB_(0x57, 0x57, 0x57) },
|
|
{ "Grey35", RGB_(0x59, 0x59, 0x59) },
|
|
{ "Grey36", RGB_(0x5c, 0x5c, 0x5c) },
|
|
{ "Grey37", RGB_(0x5e, 0x5e, 0x5e) },
|
|
{ "Grey38", RGB_(0x61, 0x61, 0x61) },
|
|
{ "Grey39", RGB_(0x63, 0x63, 0x63) },
|
|
{ "Grey4", RGB_(0xa, 0xa, 0xa) },
|
|
{ "Grey40", RGB_(0x66, 0x66, 0x66) },
|
|
{ "Grey41", RGB_(0x69, 0x69, 0x69) },
|
|
{ "Grey42", RGB_(0x6b, 0x6b, 0x6b) },
|
|
{ "Grey43", RGB_(0x6e, 0x6e, 0x6e) },
|
|
{ "Grey44", RGB_(0x70, 0x70, 0x70) },
|
|
{ "Grey45", RGB_(0x73, 0x73, 0x73) },
|
|
{ "Grey46", RGB_(0x75, 0x75, 0x75) },
|
|
{ "Grey47", RGB_(0x78, 0x78, 0x78) },
|
|
{ "Grey48", RGB_(0x7a, 0x7a, 0x7a) },
|
|
{ "Grey49", RGB_(0x7d, 0x7d, 0x7d) },
|
|
{ "Grey5", RGB_(0xd, 0xd, 0xd) },
|
|
{ "Grey50", RGB_(0x7f, 0x7f, 0x7f) },
|
|
{ "Grey51", RGB_(0x82, 0x82, 0x82) },
|
|
{ "Grey52", RGB_(0x85, 0x85, 0x85) },
|
|
{ "Grey53", RGB_(0x87, 0x87, 0x87) },
|
|
{ "Grey54", RGB_(0x8a, 0x8a, 0x8a) },
|
|
{ "Grey55", RGB_(0x8c, 0x8c, 0x8c) },
|
|
{ "Grey56", RGB_(0x8f, 0x8f, 0x8f) },
|
|
{ "Grey57", RGB_(0x91, 0x91, 0x91) },
|
|
{ "Grey58", RGB_(0x94, 0x94, 0x94) },
|
|
{ "Grey59", RGB_(0x96, 0x96, 0x96) },
|
|
{ "Grey6", RGB_(0xf, 0xf, 0xf) },
|
|
{ "Grey60", RGB_(0x99, 0x99, 0x99) },
|
|
{ "Grey61", RGB_(0x9c, 0x9c, 0x9c) },
|
|
{ "Grey62", RGB_(0x9e, 0x9e, 0x9e) },
|
|
{ "Grey63", RGB_(0xa1, 0xa1, 0xa1) },
|
|
{ "Grey64", RGB_(0xa3, 0xa3, 0xa3) },
|
|
{ "Grey65", RGB_(0xa6, 0xa6, 0xa6) },
|
|
{ "Grey66", RGB_(0xa8, 0xa8, 0xa8) },
|
|
{ "Grey67", RGB_(0xab, 0xab, 0xab) },
|
|
{ "Grey68", RGB_(0xad, 0xad, 0xad) },
|
|
{ "Grey69", RGB_(0xb0, 0xb0, 0xb0) },
|
|
{ "Grey7", RGB_(0x12, 0x12, 0x12) },
|
|
{ "Grey70", RGB_(0xb3, 0xb3, 0xb3) },
|
|
{ "Grey71", RGB_(0xb5, 0xb5, 0xb5) },
|
|
{ "Grey72", RGB_(0xb8, 0xb8, 0xb8) },
|
|
{ "Grey73", RGB_(0xba, 0xba, 0xba) },
|
|
{ "Grey74", RGB_(0xbd, 0xbd, 0xbd) },
|
|
{ "Grey75", RGB_(0xbf, 0xbf, 0xbf) },
|
|
{ "Grey76", RGB_(0xc2, 0xc2, 0xc2) },
|
|
{ "Grey77", RGB_(0xc4, 0xc4, 0xc4) },
|
|
{ "Grey78", RGB_(0xc7, 0xc7, 0xc7) },
|
|
{ "Grey79", RGB_(0xc9, 0xc9, 0xc9) },
|
|
{ "Grey8", RGB_(0x14, 0x14, 0x14) },
|
|
{ "Grey80", RGB_(0xcc, 0xcc, 0xcc) },
|
|
{ "Grey81", RGB_(0xcf, 0xcf, 0xcf) },
|
|
{ "Grey82", RGB_(0xd1, 0xd1, 0xd1) },
|
|
{ "Grey83", RGB_(0xd4, 0xd4, 0xd4) },
|
|
{ "Grey84", RGB_(0xd6, 0xd6, 0xd6) },
|
|
{ "Grey85", RGB_(0xd9, 0xd9, 0xd9) },
|
|
{ "Grey86", RGB_(0xdb, 0xdb, 0xdb) },
|
|
{ "Grey87", RGB_(0xde, 0xde, 0xde) },
|
|
{ "Grey88", RGB_(0xe0, 0xe0, 0xe0) },
|
|
{ "Grey89", RGB_(0xe3, 0xe3, 0xe3) },
|
|
{ "Grey9", RGB_(0x17, 0x17, 0x17) },
|
|
{ "Grey90", RGB_(0xe5, 0xe5, 0xe5) },
|
|
{ "Grey91", RGB_(0xe8, 0xe8, 0xe8) },
|
|
{ "Grey92", RGB_(0xeb, 0xeb, 0xeb) },
|
|
{ "Grey93", RGB_(0xed, 0xed, 0xed) },
|
|
{ "Grey94", RGB_(0xf0, 0xf0, 0xf0) },
|
|
{ "Grey95", RGB_(0xf2, 0xf2, 0xf2) },
|
|
{ "Grey96", RGB_(0xf5, 0xf5, 0xf5) },
|
|
{ "Grey97", RGB_(0xf7, 0xf7, 0xf7) },
|
|
{ "Grey98", RGB_(0xfa, 0xfa, 0xfa) },
|
|
{ "Grey99", RGB_(0xfc, 0xfc, 0xfc) },
|
|
{ "Honeydew", RGB_(0xf0, 0xff, 0xf0) },
|
|
{ "Honeydew1", RGB_(0xf0, 0xff, 0xf0) },
|
|
{ "Honeydew2", RGB_(0xe0, 0xee, 0xe0) },
|
|
{ "Honeydew3", RGB_(0xc1, 0xcd, 0xc1) },
|
|
{ "Honeydew4", RGB_(0x83, 0x8b, 0x83) },
|
|
{ "HotPink", RGB_(0xff, 0x69, 0xb4) },
|
|
{ "HotPink1", RGB_(0xff, 0x6e, 0xb4) },
|
|
{ "HotPink2", RGB_(0xee, 0x6a, 0xa7) },
|
|
{ "HotPink3", RGB_(0xcd, 0x60, 0x90) },
|
|
{ "HotPink4", RGB_(0x8b, 0x3a, 0x62) },
|
|
{ "IndianRed", RGB_(0xcd, 0x5c, 0x5c) },
|
|
{ "IndianRed1", RGB_(0xff, 0x6a, 0x6a) },
|
|
{ "IndianRed2", RGB_(0xee, 0x63, 0x63) },
|
|
{ "IndianRed3", RGB_(0xcd, 0x55, 0x55) },
|
|
{ "IndianRed4", RGB_(0x8b, 0x3a, 0x3a) },
|
|
{ "Indigo", RGB_(0x4b, 0x00, 0x82) },
|
|
{ "Ivory", RGB_(0xff, 0xff, 0xf0) },
|
|
{ "Ivory1", RGB_(0xff, 0xff, 0xf0) },
|
|
{ "Ivory2", RGB_(0xee, 0xee, 0xe0) },
|
|
{ "Ivory3", RGB_(0xcd, 0xcd, 0xc1) },
|
|
{ "Ivory4", RGB_(0x8b, 0x8b, 0x83) },
|
|
{ "Khaki", RGB_(0xf0, 0xe6, 0x8c) },
|
|
{ "Khaki1", RGB_(0xff, 0xf6, 0x8f) },
|
|
{ "Khaki2", RGB_(0xee, 0xe6, 0x85) },
|
|
{ "Khaki3", RGB_(0xcd, 0xc6, 0x73) },
|
|
{ "Khaki4", RGB_(0x8b, 0x86, 0x4e) },
|
|
{ "Lavender", RGB_(0xe6, 0xe6, 0xfa) },
|
|
{ "LavenderBlush", RGB_(0xff, 0xf0, 0xf5) },
|
|
{ "LavenderBlush1", RGB_(0xff, 0xf0, 0xf5) },
|
|
{ "LavenderBlush2", RGB_(0xee, 0xe0, 0xe5) },
|
|
{ "LavenderBlush3", RGB_(0xcd, 0xc1, 0xc5) },
|
|
{ "LavenderBlush4", RGB_(0x8b, 0x83, 0x86) },
|
|
{ "LawnGreen", RGB_(0x7c, 0xfc, 0x00) },
|
|
{ "LemonChiffon", RGB_(0xff, 0xfa, 0xcd) },
|
|
{ "LemonChiffon1", RGB_(0xff, 0xfa, 0xcd) },
|
|
{ "LemonChiffon2", RGB_(0xee, 0xe9, 0xbf) },
|
|
{ "LemonChiffon3", RGB_(0xcd, 0xc9, 0xa5) },
|
|
{ "LemonChiffon4", RGB_(0x8b, 0x89, 0x70) },
|
|
{ "LightBlue", RGB_(0xad, 0xd8, 0xe6) },
|
|
{ "LightBlue1", RGB_(0xbf, 0xef, 0xff) },
|
|
{ "LightBlue2", RGB_(0xb2, 0xdf, 0xee) },
|
|
{ "LightBlue3", RGB_(0x9a, 0xc0, 0xcd) },
|
|
{ "LightBlue4", RGB_(0x68, 0x83, 0x8b) },
|
|
{ "LightCoral", RGB_(0xf0, 0x80, 0x80) },
|
|
{ "LightCyan", RGB_(0xe0, 0xff, 0xff) },
|
|
{ "LightCyan1", RGB_(0xe0, 0xff, 0xff) },
|
|
{ "LightCyan2", RGB_(0xd1, 0xee, 0xee) },
|
|
{ "LightCyan3", RGB_(0xb4, 0xcd, 0xcd) },
|
|
{ "LightCyan4", RGB_(0x7a, 0x8b, 0x8b) },
|
|
{ "LightGoldenrod", RGB_(0xee, 0xdd, 0x82) },
|
|
{ "LightGoldenrod1", RGB_(0xff, 0xec, 0x8b) },
|
|
{ "LightGoldenrod2", RGB_(0xee, 0xdc, 0x82) },
|
|
{ "LightGoldenrod3", RGB_(0xcd, 0xbe, 0x70) },
|
|
{ "LightGoldenrod4", RGB_(0x8b, 0x81, 0x4c) },
|
|
{ "LightGoldenrodYellow", RGB_(0xfa, 0xfa, 0xd2) },
|
|
{ "LightGray", RGB_(0xd3, 0xd3, 0xd3) },
|
|
{ "LightGreen", RGB_(0x90, 0xee, 0x90) },
|
|
{ "LightGrey", RGB_(0xd3, 0xd3, 0xd3) },
|
|
{ "LightMagenta", RGB_(0xff, 0xbb, 0xff) },
|
|
{ "LightPink", RGB_(0xff, 0xb6, 0xc1) },
|
|
{ "LightPink1", RGB_(0xff, 0xae, 0xb9) },
|
|
{ "LightPink2", RGB_(0xee, 0xa2, 0xad) },
|
|
{ "LightPink3", RGB_(0xcd, 0x8c, 0x95) },
|
|
{ "LightPink4", RGB_(0x8b, 0x5f, 0x65) },
|
|
{ "LightRed", RGB_(0xff, 0xbb, 0xbb) },
|
|
{ "LightSalmon", RGB_(0xff, 0xa0, 0x7a) },
|
|
{ "LightSalmon1", RGB_(0xff, 0xa0, 0x7a) },
|
|
{ "LightSalmon2", RGB_(0xee, 0x95, 0x72) },
|
|
{ "LightSalmon3", RGB_(0xcd, 0x81, 0x62) },
|
|
{ "LightSalmon4", RGB_(0x8b, 0x57, 0x42) },
|
|
{ "LightSeaGreen", RGB_(0x20, 0xb2, 0xaa) },
|
|
{ "LightSkyBlue", RGB_(0x87, 0xce, 0xfa) },
|
|
{ "LightSkyBlue1", RGB_(0xb0, 0xe2, 0xff) },
|
|
{ "LightSkyBlue2", RGB_(0xa4, 0xd3, 0xee) },
|
|
{ "LightSkyBlue3", RGB_(0x8d, 0xb6, 0xcd) },
|
|
{ "LightSkyBlue4", RGB_(0x60, 0x7b, 0x8b) },
|
|
{ "LightSlateBlue", RGB_(0x84, 0x70, 0xff) },
|
|
{ "LightSlateGray", RGB_(0x77, 0x88, 0x99) },
|
|
{ "LightSlateGrey", RGB_(0x77, 0x88, 0x99) },
|
|
{ "LightSteelBlue", RGB_(0xb0, 0xc4, 0xde) },
|
|
{ "LightSteelBlue1", RGB_(0xca, 0xe1, 0xff) },
|
|
{ "LightSteelBlue2", RGB_(0xbc, 0xd2, 0xee) },
|
|
{ "LightSteelBlue3", RGB_(0xa2, 0xb5, 0xcd) },
|
|
{ "LightSteelBlue4", RGB_(0x6e, 0x7b, 0x8b) },
|
|
{ "LightYellow", RGB_(0xff, 0xff, 0xe0) },
|
|
{ "LightYellow1", RGB_(0xff, 0xff, 0xe0) },
|
|
{ "LightYellow2", RGB_(0xee, 0xee, 0xd1) },
|
|
{ "LightYellow3", RGB_(0xcd, 0xcd, 0xb4) },
|
|
{ "LightYellow4", RGB_(0x8b, 0x8b, 0x7a) },
|
|
{ "Lime", RGB_(0x00, 0xff, 0x00) },
|
|
{ "LimeGreen", RGB_(0x32, 0xcd, 0x32) },
|
|
{ "Linen", RGB_(0xfa, 0xf0, 0xe6) },
|
|
{ "Magenta", RGB_(0xff, 0x00, 0xff) },
|
|
{ "Magenta1", RGB_(0xff, 0x0, 0xff) },
|
|
{ "Magenta2", RGB_(0xee, 0x0, 0xee) },
|
|
{ "Magenta3", RGB_(0xcd, 0x0, 0xcd) },
|
|
{ "Magenta4", RGB_(0x8b, 0x0, 0x8b) },
|
|
{ "Maroon", RGB_(0x80, 0x00, 0x00) },
|
|
{ "Maroon1", RGB_(0xff, 0x34, 0xb3) },
|
|
{ "Maroon2", RGB_(0xee, 0x30, 0xa7) },
|
|
{ "Maroon3", RGB_(0xcd, 0x29, 0x90) },
|
|
{ "Maroon4", RGB_(0x8b, 0x1c, 0x62) },
|
|
{ "MediumAquamarine", RGB_(0x66, 0xcd, 0xaa) },
|
|
{ "MediumBlue", RGB_(0x00, 0x00, 0xcd) },
|
|
{ "MediumOrchid", RGB_(0xba, 0x55, 0xd3) },
|
|
{ "MediumOrchid1", RGB_(0xe0, 0x66, 0xff) },
|
|
{ "MediumOrchid2", RGB_(0xd1, 0x5f, 0xee) },
|
|
{ "MediumOrchid3", RGB_(0xb4, 0x52, 0xcd) },
|
|
{ "MediumOrchid4", RGB_(0x7a, 0x37, 0x8b) },
|
|
{ "MediumPurple", RGB_(0x93, 0x70, 0xdb) },
|
|
{ "MediumPurple1", RGB_(0xab, 0x82, 0xff) },
|
|
{ "MediumPurple2", RGB_(0x9f, 0x79, 0xee) },
|
|
{ "MediumPurple3", RGB_(0x89, 0x68, 0xcd) },
|
|
{ "MediumPurple4", RGB_(0x5d, 0x47, 0x8b) },
|
|
{ "MediumSeaGreen", RGB_(0x3c, 0xb3, 0x71) },
|
|
{ "MediumSlateBlue", RGB_(0x7b, 0x68, 0xee) },
|
|
{ "MediumSpringGreen", RGB_(0x00, 0xfa, 0x9a) },
|
|
{ "MediumTurquoise", RGB_(0x48, 0xd1, 0xcc) },
|
|
{ "MediumVioletRed", RGB_(0xc7, 0x15, 0x85) },
|
|
{ "MidnightBlue", RGB_(0x19, 0x19, 0x70) },
|
|
{ "MintCream", RGB_(0xf5, 0xff, 0xfa) },
|
|
{ "MistyRose", RGB_(0xff, 0xe4, 0xe1) },
|
|
{ "MistyRose1", RGB_(0xff, 0xe4, 0xe1) },
|
|
{ "MistyRose2", RGB_(0xee, 0xd5, 0xd2) },
|
|
{ "MistyRose3", RGB_(0xcd, 0xb7, 0xb5) },
|
|
{ "MistyRose4", RGB_(0x8b, 0x7d, 0x7b) },
|
|
{ "Moccasin", RGB_(0xff, 0xe4, 0xb5) },
|
|
{ "NavajoWhite", RGB_(0xff, 0xde, 0xad) },
|
|
{ "NavajoWhite1", RGB_(0xff, 0xde, 0xad) },
|
|
{ "NavajoWhite2", RGB_(0xee, 0xcf, 0xa1) },
|
|
{ "NavajoWhite3", RGB_(0xcd, 0xb3, 0x8b) },
|
|
{ "NavajoWhite4", RGB_(0x8b, 0x79, 0x5e) },
|
|
{ "Navy", RGB_(0x00, 0x00, 0x80) },
|
|
{ "NavyBlue", RGB_(0x0, 0x0, 0x80) },
|
|
// Default Neovim palettes.
|
|
// Dark/light palette is used for background in dark/light color scheme and
|
|
// for foreground in light/dark color scheme.
|
|
{ "NvimDarkBlue", RGB_(0x00, 0x4c, 0x73) },
|
|
{ "NvimDarkCyan", RGB_(0x00, 0x73, 0x73) },
|
|
{ "NvimDarkGray1", RGB_(0x07, 0x08, 0x0d) },
|
|
{ "NvimDarkGray2", RGB_(0x14, 0x16, 0x1b) },
|
|
{ "NvimDarkGray3", RGB_(0x2c, 0x2e, 0x33) },
|
|
{ "NvimDarkGray4", RGB_(0x4f, 0x52, 0x58) },
|
|
{ "NvimDarkGreen", RGB_(0x00, 0x55, 0x23) },
|
|
{ "NvimDarkGrey1", RGB_(0x07, 0x08, 0x0d) },
|
|
{ "NvimDarkGrey2", RGB_(0x14, 0x16, 0x1b) },
|
|
{ "NvimDarkGrey3", RGB_(0x2c, 0x2e, 0x33) },
|
|
{ "NvimDarkGrey4", RGB_(0x4f, 0x52, 0x58) },
|
|
{ "NvimDarkMagenta", RGB_(0x47, 0x00, 0x45) },
|
|
{ "NvimDarkRed", RGB_(0x59, 0x00, 0x08) },
|
|
{ "NvimDarkYellow", RGB_(0x6b, 0x53, 0x00) },
|
|
{ "NvimLightBlue", RGB_(0xa6, 0xdb, 0xff) },
|
|
{ "NvimLightCyan", RGB_(0x8c, 0xf8, 0xf7) },
|
|
{ "NvimLightGray1", RGB_(0xee, 0xf1, 0xf8) },
|
|
{ "NvimLightGray2", RGB_(0xe0, 0xe2, 0xea) },
|
|
{ "NvimLightGray3", RGB_(0xc4, 0xc6, 0xcd) },
|
|
{ "NvimLightGray4", RGB_(0x9b, 0x9e, 0xa4) },
|
|
{ "NvimLightGreen", RGB_(0xb3, 0xf6, 0xc0) },
|
|
{ "NvimLightGrey1", RGB_(0xee, 0xf1, 0xf8) },
|
|
{ "NvimLightGrey2", RGB_(0xe0, 0xe2, 0xea) },
|
|
{ "NvimLightGrey3", RGB_(0xc4, 0xc6, 0xcd) },
|
|
{ "NvimLightGrey4", RGB_(0x9b, 0x9e, 0xa4) },
|
|
{ "NvimLightMagenta", RGB_(0xff, 0xca, 0xff) },
|
|
{ "NvimLightRed", RGB_(0xff, 0xc0, 0xb9) },
|
|
{ "NvimLightYellow", RGB_(0xfc, 0xe0, 0x94) },
|
|
{ "OldLace", RGB_(0xfd, 0xf5, 0xe6) },
|
|
{ "Olive", RGB_(0x80, 0x80, 0x00) },
|
|
{ "OliveDrab", RGB_(0x6b, 0x8e, 0x23) },
|
|
{ "OliveDrab1", RGB_(0xc0, 0xff, 0x3e) },
|
|
{ "OliveDrab2", RGB_(0xb3, 0xee, 0x3a) },
|
|
{ "OliveDrab3", RGB_(0x9a, 0xcd, 0x32) },
|
|
{ "OliveDrab4", RGB_(0x69, 0x8b, 0x22) },
|
|
{ "Orange", RGB_(0xff, 0xa5, 0x00) },
|
|
{ "Orange1", RGB_(0xff, 0xa5, 0x0) },
|
|
{ "Orange2", RGB_(0xee, 0x9a, 0x0) },
|
|
{ "Orange3", RGB_(0xcd, 0x85, 0x0) },
|
|
{ "Orange4", RGB_(0x8b, 0x5a, 0x0) },
|
|
{ "OrangeRed", RGB_(0xff, 0x45, 0x00) },
|
|
{ "OrangeRed1", RGB_(0xff, 0x45, 0x0) },
|
|
{ "OrangeRed2", RGB_(0xee, 0x40, 0x0) },
|
|
{ "OrangeRed3", RGB_(0xcd, 0x37, 0x0) },
|
|
{ "OrangeRed4", RGB_(0x8b, 0x25, 0x0) },
|
|
{ "Orchid", RGB_(0xda, 0x70, 0xd6) },
|
|
{ "Orchid1", RGB_(0xff, 0x83, 0xfa) },
|
|
{ "Orchid2", RGB_(0xee, 0x7a, 0xe9) },
|
|
{ "Orchid3", RGB_(0xcd, 0x69, 0xc9) },
|
|
{ "Orchid4", RGB_(0x8b, 0x47, 0x89) },
|
|
{ "PaleGoldenrod", RGB_(0xee, 0xe8, 0xaa) },
|
|
{ "PaleGreen", RGB_(0x98, 0xfb, 0x98) },
|
|
{ "PaleGreen1", RGB_(0x9a, 0xff, 0x9a) },
|
|
{ "PaleGreen2", RGB_(0x90, 0xee, 0x90) },
|
|
{ "PaleGreen3", RGB_(0x7c, 0xcd, 0x7c) },
|
|
{ "PaleGreen4", RGB_(0x54, 0x8b, 0x54) },
|
|
{ "PaleTurquoise", RGB_(0xaf, 0xee, 0xee) },
|
|
{ "PaleTurquoise1", RGB_(0xbb, 0xff, 0xff) },
|
|
{ "PaleTurquoise2", RGB_(0xae, 0xee, 0xee) },
|
|
{ "PaleTurquoise3", RGB_(0x96, 0xcd, 0xcd) },
|
|
{ "PaleTurquoise4", RGB_(0x66, 0x8b, 0x8b) },
|
|
{ "PaleVioletRed", RGB_(0xdb, 0x70, 0x93) },
|
|
{ "PaleVioletRed1", RGB_(0xff, 0x82, 0xab) },
|
|
{ "PaleVioletRed2", RGB_(0xee, 0x79, 0x9f) },
|
|
{ "PaleVioletRed3", RGB_(0xcd, 0x68, 0x89) },
|
|
{ "PaleVioletRed4", RGB_(0x8b, 0x47, 0x5d) },
|
|
{ "PapayaWhip", RGB_(0xff, 0xef, 0xd5) },
|
|
{ "PeachPuff", RGB_(0xff, 0xda, 0xb9) },
|
|
{ "PeachPuff1", RGB_(0xff, 0xda, 0xb9) },
|
|
{ "PeachPuff2", RGB_(0xee, 0xcb, 0xad) },
|
|
{ "PeachPuff3", RGB_(0xcd, 0xaf, 0x95) },
|
|
{ "PeachPuff4", RGB_(0x8b, 0x77, 0x65) },
|
|
{ "Peru", RGB_(0xcd, 0x85, 0x3f) },
|
|
{ "Pink", RGB_(0xff, 0xc0, 0xcb) },
|
|
{ "Pink1", RGB_(0xff, 0xb5, 0xc5) },
|
|
{ "Pink2", RGB_(0xee, 0xa9, 0xb8) },
|
|
{ "Pink3", RGB_(0xcd, 0x91, 0x9e) },
|
|
{ "Pink4", RGB_(0x8b, 0x63, 0x6c) },
|
|
{ "Plum", RGB_(0xdd, 0xa0, 0xdd) },
|
|
{ "Plum1", RGB_(0xff, 0xbb, 0xff) },
|
|
{ "Plum2", RGB_(0xee, 0xae, 0xee) },
|
|
{ "Plum3", RGB_(0xcd, 0x96, 0xcd) },
|
|
{ "Plum4", RGB_(0x8b, 0x66, 0x8b) },
|
|
{ "PowderBlue", RGB_(0xb0, 0xe0, 0xe6) },
|
|
{ "Purple", RGB_(0x80, 0x00, 0x80) },
|
|
{ "Purple1", RGB_(0x9b, 0x30, 0xff) },
|
|
{ "Purple2", RGB_(0x91, 0x2c, 0xee) },
|
|
{ "Purple3", RGB_(0x7d, 0x26, 0xcd) },
|
|
{ "Purple4", RGB_(0x55, 0x1a, 0x8b) },
|
|
{ "RebeccaPurple", RGB_(0x66, 0x33, 0x99) },
|
|
{ "Red", RGB_(0xff, 0x00, 0x00) },
|
|
{ "Red1", RGB_(0xff, 0x0, 0x0) },
|
|
{ "Red2", RGB_(0xee, 0x0, 0x0) },
|
|
{ "Red3", RGB_(0xcd, 0x0, 0x0) },
|
|
{ "Red4", RGB_(0x8b, 0x0, 0x0) },
|
|
{ "RosyBrown", RGB_(0xbc, 0x8f, 0x8f) },
|
|
{ "RosyBrown1", RGB_(0xff, 0xc1, 0xc1) },
|
|
{ "RosyBrown2", RGB_(0xee, 0xb4, 0xb4) },
|
|
{ "RosyBrown3", RGB_(0xcd, 0x9b, 0x9b) },
|
|
{ "RosyBrown4", RGB_(0x8b, 0x69, 0x69) },
|
|
{ "RoyalBlue", RGB_(0x41, 0x69, 0xe1) },
|
|
{ "RoyalBlue1", RGB_(0x48, 0x76, 0xff) },
|
|
{ "RoyalBlue2", RGB_(0x43, 0x6e, 0xee) },
|
|
{ "RoyalBlue3", RGB_(0x3a, 0x5f, 0xcd) },
|
|
{ "RoyalBlue4", RGB_(0x27, 0x40, 0x8b) },
|
|
{ "SaddleBrown", RGB_(0x8b, 0x45, 0x13) },
|
|
{ "Salmon", RGB_(0xfa, 0x80, 0x72) },
|
|
{ "Salmon1", RGB_(0xff, 0x8c, 0x69) },
|
|
{ "Salmon2", RGB_(0xee, 0x82, 0x62) },
|
|
{ "Salmon3", RGB_(0xcd, 0x70, 0x54) },
|
|
{ "Salmon4", RGB_(0x8b, 0x4c, 0x39) },
|
|
{ "SandyBrown", RGB_(0xf4, 0xa4, 0x60) },
|
|
{ "SeaGreen", RGB_(0x2e, 0x8b, 0x57) },
|
|
{ "SeaGreen1", RGB_(0x54, 0xff, 0x9f) },
|
|
{ "SeaGreen2", RGB_(0x4e, 0xee, 0x94) },
|
|
{ "SeaGreen3", RGB_(0x43, 0xcd, 0x80) },
|
|
{ "SeaGreen4", RGB_(0x2e, 0x8b, 0x57) },
|
|
{ "SeaShell", RGB_(0xff, 0xf5, 0xee) },
|
|
{ "Seashell1", RGB_(0xff, 0xf5, 0xee) },
|
|
{ "Seashell2", RGB_(0xee, 0xe5, 0xde) },
|
|
{ "Seashell3", RGB_(0xcd, 0xc5, 0xbf) },
|
|
{ "Seashell4", RGB_(0x8b, 0x86, 0x82) },
|
|
{ "Sienna", RGB_(0xa0, 0x52, 0x2d) },
|
|
{ "Sienna1", RGB_(0xff, 0x82, 0x47) },
|
|
{ "Sienna2", RGB_(0xee, 0x79, 0x42) },
|
|
{ "Sienna3", RGB_(0xcd, 0x68, 0x39) },
|
|
{ "Sienna4", RGB_(0x8b, 0x47, 0x26) },
|
|
{ "Silver", RGB_(0xc0, 0xc0, 0xc0) },
|
|
{ "SkyBlue", RGB_(0x87, 0xce, 0xeb) },
|
|
{ "SkyBlue1", RGB_(0x87, 0xce, 0xff) },
|
|
{ "SkyBlue2", RGB_(0x7e, 0xc0, 0xee) },
|
|
{ "SkyBlue3", RGB_(0x6c, 0xa6, 0xcd) },
|
|
{ "SkyBlue4", RGB_(0x4a, 0x70, 0x8b) },
|
|
{ "SlateBlue", RGB_(0x6a, 0x5a, 0xcd) },
|
|
{ "SlateBlue1", RGB_(0x83, 0x6f, 0xff) },
|
|
{ "SlateBlue2", RGB_(0x7a, 0x67, 0xee) },
|
|
{ "SlateBlue3", RGB_(0x69, 0x59, 0xcd) },
|
|
{ "SlateBlue4", RGB_(0x47, 0x3c, 0x8b) },
|
|
{ "SlateGray", RGB_(0x70, 0x80, 0x90) },
|
|
{ "SlateGray1", RGB_(0xc6, 0xe2, 0xff) },
|
|
{ "SlateGray2", RGB_(0xb9, 0xd3, 0xee) },
|
|
{ "SlateGray3", RGB_(0x9f, 0xb6, 0xcd) },
|
|
{ "SlateGray4", RGB_(0x6c, 0x7b, 0x8b) },
|
|
{ "SlateGrey", RGB_(0x70, 0x80, 0x90) },
|
|
{ "Snow", RGB_(0xff, 0xfa, 0xfa) },
|
|
{ "Snow1", RGB_(0xff, 0xfa, 0xfa) },
|
|
{ "Snow2", RGB_(0xee, 0xe9, 0xe9) },
|
|
{ "Snow3", RGB_(0xcd, 0xc9, 0xc9) },
|
|
{ "Snow4", RGB_(0x8b, 0x89, 0x89) },
|
|
{ "SpringGreen", RGB_(0x00, 0xff, 0x7f) },
|
|
{ "SpringGreen1", RGB_(0x0, 0xff, 0x7f) },
|
|
{ "SpringGreen2", RGB_(0x0, 0xee, 0x76) },
|
|
{ "SpringGreen3", RGB_(0x0, 0xcd, 0x66) },
|
|
{ "SpringGreen4", RGB_(0x0, 0x8b, 0x45) },
|
|
{ "SteelBlue", RGB_(0x46, 0x82, 0xb4) },
|
|
{ "SteelBlue1", RGB_(0x63, 0xb8, 0xff) },
|
|
{ "SteelBlue2", RGB_(0x5c, 0xac, 0xee) },
|
|
{ "SteelBlue3", RGB_(0x4f, 0x94, 0xcd) },
|
|
{ "SteelBlue4", RGB_(0x36, 0x64, 0x8b) },
|
|
{ "Tan", RGB_(0xd2, 0xb4, 0x8c) },
|
|
{ "Tan1", RGB_(0xff, 0xa5, 0x4f) },
|
|
{ "Tan2", RGB_(0xee, 0x9a, 0x49) },
|
|
{ "Tan3", RGB_(0xcd, 0x85, 0x3f) },
|
|
{ "Tan4", RGB_(0x8b, 0x5a, 0x2b) },
|
|
{ "Teal", RGB_(0x00, 0x80, 0x80) },
|
|
{ "Thistle", RGB_(0xd8, 0xbf, 0xd8) },
|
|
{ "Thistle1", RGB_(0xff, 0xe1, 0xff) },
|
|
{ "Thistle2", RGB_(0xee, 0xd2, 0xee) },
|
|
{ "Thistle3", RGB_(0xcd, 0xb5, 0xcd) },
|
|
{ "Thistle4", RGB_(0x8b, 0x7b, 0x8b) },
|
|
{ "Tomato", RGB_(0xff, 0x63, 0x47) },
|
|
{ "Tomato1", RGB_(0xff, 0x63, 0x47) },
|
|
{ "Tomato2", RGB_(0xee, 0x5c, 0x42) },
|
|
{ "Tomato3", RGB_(0xcd, 0x4f, 0x39) },
|
|
{ "Tomato4", RGB_(0x8b, 0x36, 0x26) },
|
|
{ "Turquoise", RGB_(0x40, 0xe0, 0xd0) },
|
|
{ "Turquoise1", RGB_(0x0, 0xf5, 0xff) },
|
|
{ "Turquoise2", RGB_(0x0, 0xe5, 0xee) },
|
|
{ "Turquoise3", RGB_(0x0, 0xc5, 0xcd) },
|
|
{ "Turquoise4", RGB_(0x0, 0x86, 0x8b) },
|
|
{ "Violet", RGB_(0xee, 0x82, 0xee) },
|
|
{ "VioletRed", RGB_(0xd0, 0x20, 0x90) },
|
|
{ "VioletRed1", RGB_(0xff, 0x3e, 0x96) },
|
|
{ "VioletRed2", RGB_(0xee, 0x3a, 0x8c) },
|
|
{ "VioletRed3", RGB_(0xcd, 0x32, 0x78) },
|
|
{ "VioletRed4", RGB_(0x8b, 0x22, 0x52) },
|
|
{ "WebGray", RGB_(0x80, 0x80, 0x80) },
|
|
{ "WebGreen", RGB_(0x0, 0x80, 0x0) },
|
|
{ "WebGrey", RGB_(0x80, 0x80, 0x80) },
|
|
{ "WebMaroon", RGB_(0x80, 0x0, 0x0) },
|
|
{ "WebPurple", RGB_(0x80, 0x0, 0x80) },
|
|
{ "Wheat", RGB_(0xf5, 0xde, 0xb3) },
|
|
{ "Wheat1", RGB_(0xff, 0xe7, 0xba) },
|
|
{ "Wheat2", RGB_(0xee, 0xd8, 0xae) },
|
|
{ "Wheat3", RGB_(0xcd, 0xba, 0x96) },
|
|
{ "Wheat4", RGB_(0x8b, 0x7e, 0x66) },
|
|
{ "White", RGB_(0xff, 0xff, 0xff) },
|
|
{ "WhiteSmoke", RGB_(0xf5, 0xf5, 0xf5) },
|
|
{ "X11Gray", RGB_(0xbe, 0xbe, 0xbe) },
|
|
{ "X11Green", RGB_(0x0, 0xff, 0x0) },
|
|
{ "X11Grey", RGB_(0xbe, 0xbe, 0xbe) },
|
|
{ "X11Maroon", RGB_(0xb0, 0x30, 0x60) },
|
|
{ "X11Purple", RGB_(0xa0, 0x20, 0xf0) },
|
|
{ "Yellow", RGB_(0xff, 0xff, 0x00) },
|
|
{ "Yellow1", RGB_(0xff, 0xff, 0x0) },
|
|
{ "Yellow2", RGB_(0xee, 0xee, 0x0) },
|
|
{ "Yellow3", RGB_(0xcd, 0xcd, 0x0) },
|
|
{ "Yellow4", RGB_(0x8b, 0x8b, 0x0) },
|
|
{ "YellowGreen", RGB_(0x9a, 0xcd, 0x32) },
|
|
{ NULL, 0 },
|
|
};
|
|
|
|
/// Translate to RgbValue if \p name is an hex value (e.g. #XXXXXX),
|
|
/// else look into color_name_table to translate a color name to its
|
|
/// hex value
|
|
///
|
|
/// @param[in] name string value to convert to RGB
|
|
/// @param[out] idx index in color table or special value
|
|
/// return the hex value or -1 if could not find a correct value
|
|
RgbValue name_to_color(const char *name, int *idx)
|
|
{
|
|
if (name[0] == '#' && isxdigit((uint8_t)name[1]) && isxdigit((uint8_t)name[2])
|
|
&& isxdigit((uint8_t)name[3]) && isxdigit((uint8_t)name[4]) && isxdigit((uint8_t)name[5])
|
|
&& isxdigit((uint8_t)name[6]) && name[7] == NUL) {
|
|
// rgb hex string
|
|
*idx = kColorIdxHex;
|
|
return (RgbValue)strtol(name + 1, NULL, 16);
|
|
} else if (!STRICMP(name, "bg") || !STRICMP(name, "background")) {
|
|
*idx = kColorIdxBg;
|
|
return normal_bg;
|
|
} else if (!STRICMP(name, "fg") || !STRICMP(name, "foreground")) {
|
|
*idx = kColorIdxFg;
|
|
return normal_fg;
|
|
}
|
|
|
|
int lo = 0;
|
|
int hi = ARRAY_SIZE(color_name_table) - 1; // don't count NULL element
|
|
while (lo < hi) {
|
|
int m = (lo + hi) / 2;
|
|
int cmp = STRICMP(name, color_name_table[m].name);
|
|
if (cmp < 0) {
|
|
hi = m;
|
|
} else if (cmp > 0) {
|
|
lo = m + 1;
|
|
} else { // found match
|
|
*idx = m;
|
|
return color_name_table[m].color;
|
|
}
|
|
}
|
|
|
|
*idx = kColorIdxNone;
|
|
return -1;
|
|
}
|
|
|
|
const char *coloridx_to_name(int idx, int val, char hexbuf[8])
|
|
{
|
|
if (idx >= 0) {
|
|
return color_name_table[idx].name;
|
|
}
|
|
switch (idx) {
|
|
case kColorIdxNone:
|
|
return NULL;
|
|
case kColorIdxFg:
|
|
return "fg";
|
|
case kColorIdxBg:
|
|
return "bg";
|
|
case kColorIdxHex:
|
|
snprintf(hexbuf, 7 + 1, "#%06x", val);
|
|
return hexbuf;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
int name_to_ctermcolor(const char *name)
|
|
{
|
|
int i;
|
|
int off = TOUPPER_ASC(*name);
|
|
for (i = ARRAY_SIZE(color_names); --i >= 0;) {
|
|
if (off == color_names[i][0]
|
|
&& STRICMP(name + 1, color_names[i] + 1) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
if (i < 0) {
|
|
return -1;
|
|
}
|
|
TriState bold = kNone;
|
|
return lookup_color(i, false, &bold);
|
|
}
|