Merge #6973 from teto/normal_hl

This commit is contained in:
Justin M. Keyes 2017-08-22 20:01:50 +02:00 committed by GitHub
commit 7f7698649f
4 changed files with 146 additions and 114 deletions

View File

@ -81,7 +81,10 @@ struct hl_group {
// highlight groups for 'highlight' option // highlight groups for 'highlight' option
static garray_T highlight_ga = GA_EMPTY_INIT_VALUE; static garray_T highlight_ga = GA_EMPTY_INIT_VALUE;
#define HL_TABLE() ((struct hl_group *)((highlight_ga.ga_data))) static inline struct hl_group * HL_TABLE(void)
{
return ((struct hl_group *)((highlight_ga.ga_data)));
}
#define MAX_HL_ID 20000 /* maximum value for a highlight ID. */ #define MAX_HL_ID 20000 /* maximum value for a highlight ID. */
@ -100,10 +103,8 @@ static int include_none = 0; /* when 1 include "nvim/None" */
static int include_default = 0; /* when 1 include "nvim/default" */ static int include_default = 0; /* when 1 include "nvim/default" */
static int include_link = 0; /* when 2 include "nvim/link" and "clear" */ static int include_link = 0; /* when 2 include "nvim/link" and "clear" */
/* /// The "term", "cterm" and "gui" arguments can be any combination of the
* The "term", "cterm" and "gui" arguments can be any combination of the /// following names, separated by commas (but no spaces!).
* following names, separated by commas (but no spaces!).
*/
static char *(hl_name_table[]) = static char *(hl_name_table[]) =
{"bold", "standout", "underline", "undercurl", {"bold", "standout", "underline", "undercurl",
"italic", "reverse", "inverse", "NONE"}; "italic", "reverse", "inverse", "NONE"};
@ -1775,8 +1776,9 @@ syn_current_attr (
cur_si->si_trans_id = CUR_STATE( cur_si->si_trans_id = CUR_STATE(
current_state.ga_len - 2).si_trans_id; current_state.ga_len - 2).si_trans_id;
} }
} else } else {
cur_si->si_attr = syn_id2attr(syn_id); cur_si->si_attr = syn_id2attr(syn_id);
}
cur_si->si_cont_list = NULL; cur_si->si_cont_list = NULL;
cur_si->si_next_list = next_list; cur_si->si_next_list = next_list;
check_keepend(); check_keepend();
@ -5252,12 +5254,10 @@ get_id_list (
/* /*
* Handle full group name. * Handle full group name.
*/ */
if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) if (vim_strpbrk(name + 1, (char_u *)"\\.*^$~[") == NULL) {
id = syn_check_group(name + 1, (int)(end - p)); id = syn_check_group(name + 1, (int)(end - p));
else { } else {
/* // Handle match of regexp with group names.
* Handle match of regexp with group names.
*/
*name = '^'; *name = '^';
STRCAT(name, "$"); STRCAT(name, "$");
regmatch.regprog = vim_regcomp(name, RE_MAGIC); regmatch.regprog = vim_regcomp(name, RE_MAGIC);
@ -5958,6 +5958,7 @@ static char *highlight_init_light[] =
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta", "Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
"Visual guibg=LightGrey", "Visual guibg=LightGrey",
"WarningMsg ctermfg=DarkRed guifg=Red", "WarningMsg ctermfg=DarkRed guifg=Red",
"Normal gui=NONE",
NULL NULL
}; };
@ -5991,23 +5992,25 @@ static char *highlight_init_dark[] =
"Title ctermfg=LightMagenta gui=bold guifg=Magenta", "Title ctermfg=LightMagenta gui=bold guifg=Magenta",
"Visual guibg=DarkGrey", "Visual guibg=DarkGrey",
"WarningMsg ctermfg=LightRed guifg=Red", "WarningMsg ctermfg=LightRed guifg=Red",
"Normal gui=NONE",
NULL NULL
}; };
/// 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 void
init_highlight ( init_highlight(int both, int reset)
int both, /* include groups where 'bg' doesn't matter */
int reset /* clear group first */
)
{ {
int i; int i;
char **pp; char **pp;
static int had_both = FALSE; static int had_both = FALSE;
/* // Try finding the color scheme file. Used when a color file was loaded
* Try finding the color scheme file. Used when a color file was loaded // and 'background' or 't_Co' is changed.
* and 'background' or 't_Co' is changed.
*/
char_u *p = get_var_value("g:colors_name"); char_u *p = get_var_value("g:colors_name");
if (p != NULL) { if (p != NULL) {
// Value of g:colors_name could be freed in load_colors() and make // Value of g:colors_name could be freed in load_colors() and make
@ -6026,33 +6029,34 @@ init_highlight (
if (both) { if (both) {
had_both = TRUE; had_both = TRUE;
pp = highlight_init_both; pp = highlight_init_both;
for (i = 0; pp[i] != NULL; ++i) for (i = 0; pp[i] != NULL; i++) {
do_highlight((char_u *)pp[i], reset, TRUE); do_highlight((char_u *)pp[i], reset, true);
} else if (!had_both) }
/* Don't do anything before the call with both == TRUE from main(). } else if (!had_both) {
* Not everything has been setup then, and that call will overrule // Don't do anything before the call with both == TRUE from main().
* everything anyway. */ // Not everything has been setup then, and that call will overrule
// everything anyway.
return; return;
}
if (*p_bg == 'l') pp = (*p_bg == 'l') ? highlight_init_light : highlight_init_dark;
pp = highlight_init_light;
else for (i = 0; pp[i] != NULL; i++) {
pp = highlight_init_dark; do_highlight((char_u *)pp[i], reset, true);
for (i = 0; pp[i] != NULL; ++i) }
do_highlight((char_u *)pp[i], reset, TRUE);
/* Reverse looks ugly, but grey may not work for 8 colors. Thus let it /* Reverse looks ugly, but grey may not work for 8 colors. Thus let it
* depend on the number of colors available. * depend on the number of colors available.
* With 8 colors brown is equal to yellow, need to use black for Search fg * With 8 colors brown is equal to yellow, need to use black for Search fg
* to avoid Statement highlighted text disappears. * to avoid Statement highlighted text disappears.
* Clear the attributes, needed when changing the t_Co value. */ * Clear the attributes, needed when changing the t_Co value. */
if (t_colors > 8) if (t_colors > 8) {
do_highlight( do_highlight(
(char_u *)(*p_bg == 'l' (char_u *)(*p_bg == 'l'
? "Visual cterm=NONE ctermbg=LightGrey" ? "Visual cterm=NONE ctermbg=LightGrey"
: "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, : "Visual cterm=NONE ctermbg=DarkGrey"), false,
TRUE); true);
else { } else {
do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
FALSE, TRUE); FALSE, TRUE);
if (*p_bg == 'l') if (*p_bg == 'l')
@ -6112,12 +6116,7 @@ int load_colors(char_u *name)
/// "forceit" and "init" both TRUE. /// "forceit" and "init" both TRUE.
/// @param init TRUE when called for initializing /// @param init TRUE when called for initializing
void void
do_highlight( do_highlight(char_u *line, int forceit, int init) {
char_u *line,
int forceit,
int init
)
{
char_u *name_end; char_u *name_end;
char_u *linep; char_u *linep;
char_u *key_start; char_u *key_start;
@ -6134,15 +6133,16 @@ do_highlight(
int dolink = FALSE; int dolink = FALSE;
int error = FALSE; int error = FALSE;
int color; int color;
int is_normal_group = FALSE; /* "Normal" group */ bool is_normal_group = false; // "Normal" group
/* /*
* If no argument, list current highlighting. * If no argument, list current highlighting.
*/ */
if (ends_excmd(*line)) { if (ends_excmd(*line)) {
for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i) for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
/* TODO: only call when the group has attributes set */ // todo(vim): only call when the group has attributes set
highlight_list_one(i); highlight_list_one(i);
}
return; return;
} }
@ -6270,12 +6270,12 @@ do_highlight(
return; return;
idx = id - 1; /* index is ID minus one */ idx = id - 1; /* index is ID minus one */
/* Return if "default" was used and the group already has settings. */ // Return if "default" was used and the group already has settings
if (dodefault && hl_has_settings(idx, TRUE)) if (dodefault && hl_has_settings(idx, true)) {
return; return;
}
if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0);
is_normal_group = TRUE;
/* Clear the highlighting for ":hi clear {group}" and ":hi clear". */ /* Clear the highlighting for ":hi clear {group}" and ":hi clear". */
if (doclear || (forceit && init)) { if (doclear || (forceit && init)) {
@ -6284,7 +6284,7 @@ do_highlight(
HL_TABLE()[idx].sg_set = 0; HL_TABLE()[idx].sg_set = 0;
} }
if (!doclear) if (!doclear) {
while (!ends_excmd(*linep)) { while (!ends_excmd(*linep)) {
key_start = linep; key_start = linep;
if (*linep == '=') { if (*linep == '=') {
@ -6390,12 +6390,12 @@ do_highlight(
} }
} }
} else if (STRCMP(key, "FONT") == 0) { } else if (STRCMP(key, "FONT") == 0) {
/* in non-GUI fonts are simply ignored */ // in non-GUI fonts are simply ignored
} else if (STRCMP(key, } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
"CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) {
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) { if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) {
if (!init) if (!init) {
HL_TABLE()[idx].sg_set |= SG_CTERM; HL_TABLE()[idx].sg_set |= SG_CTERM;
}
/* When setting the foreground color, and previously the "bold" /* When setting the foreground color, and previously the "bold"
* flag was set for a light color, reset it now */ * flag was set for a light color, reset it now */
@ -6489,9 +6489,10 @@ do_highlight(
* colors (on some terminals, e.g. "linux") */ * colors (on some terminals, e.g. "linux") */
if (color & 8) { if (color & 8) {
HL_TABLE()[idx].sg_cterm |= HL_BOLD; HL_TABLE()[idx].sg_cterm |= HL_BOLD;
HL_TABLE()[idx].sg_cterm_bold = TRUE; HL_TABLE()[idx].sg_cterm_bold = true;
} else } else {
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
}
} }
color &= 7; // truncate to 8 colors color &= 7; // truncate to 8 colors
} else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) { } else if (t_colors == 16 || t_colors == 88 || t_colors >= 256) {
@ -6603,21 +6604,23 @@ do_highlight(
/* /*
* When highlighting has been given for a group, don't link it. * When highlighting has been given for a group, don't link it.
*/ */
if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) {
HL_TABLE()[idx].sg_link = 0; HL_TABLE()[idx].sg_link = 0;
}
/* /*
* Continue with next argument. * Continue with next argument.
*/ */
linep = skipwhite(linep); linep = skipwhite(linep);
} }
}
/* /*
* If there is an error, and it's a new entry, remove it from the table. * If there is an error, and it's a new entry, remove it from the table.
*/ */
if (error && idx == highlight_ga.ga_len) if (error && idx == highlight_ga.ga_len) {
syn_unadd_group(); syn_unadd_group();
else { } else {
if (is_normal_group) { if (is_normal_group) {
HL_TABLE()[idx].sg_attr = 0; HL_TABLE()[idx].sg_attr = 0;
// Need to update all groups, because they might be using "bg" and/or // Need to update all groups, because they might be using "bg" and/or
@ -6625,16 +6628,17 @@ do_highlight(
highlight_attr_set_all(); highlight_attr_set_all();
// If the normal group has changed, it is simpler to refresh every UI // If the normal group has changed, it is simpler to refresh every UI
ui_refresh(); ui_refresh();
} else } else {
set_hl_attr(idx); set_hl_attr(idx);
}
HL_TABLE()[idx].sg_scriptID = current_SID; HL_TABLE()[idx].sg_scriptID = current_SID;
redraw_all_later(NOT_VALID); redraw_all_later(NOT_VALID);
} }
xfree(key); xfree(key);
xfree(arg); xfree(arg);
/* Only call highlight_changed() once, after sourcing a syntax file */ // Only call highlight_changed() once, after sourcing a syntax file
need_highlight_changed = TRUE; need_highlight_changed = true;
} }
#if defined(EXITFREE) #if defined(EXITFREE)
@ -6707,14 +6711,15 @@ static void highlight_clear(int idx)
} }
/* /// Table with the specifications for an attribute number.
* Table with the specifications for an attribute number. /// Note that this table is used by ALL buffers. This is required because the
* Note that this table is used by ALL buffers. This is required because the /// GUI can redraw at any time for any buffer.
* GUI can redraw at any time for any buffer.
*/
static garray_T attr_table = GA_EMPTY_INIT_VALUE; static garray_T attr_table = GA_EMPTY_INIT_VALUE;
#define ATTR_ENTRY(idx) ((attrentry_T *)attr_table.ga_data)[idx] static inline attrentry_T * ATTR_ENTRY(int idx)
{
return &((attrentry_T *)attr_table.ga_data)[idx];
}
/// Return the attr number for a set of colors and font. /// Return the attr number for a set of colors and font.
@ -6804,7 +6809,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
{ {
attrentry_T *char_aep = NULL; attrentry_T *char_aep = NULL;
attrentry_T *spell_aep; attrentry_T *spell_aep;
attrentry_T new_en; attrentry_T new_en = ATTRENTRY_INIT;
if (char_attr == 0) { if (char_attr == 0) {
return prim_attr; return prim_attr;
@ -6852,17 +6857,24 @@ int hl_combine_attr(int char_attr, int prim_attr)
return get_attr_entry(&new_en); return get_attr_entry(&new_en);
} }
/// \note this function does not apply exclusively to cterm attr contrary
/// to what its name implies
attrentry_T *syn_cterm_attr2entry(int attr) attrentry_T *syn_cterm_attr2entry(int attr)
{ {
attr -= ATTR_OFF; attr -= ATTR_OFF;
if (attr >= attr_table.ga_len) /* did ":syntax clear" */ if (attr >= attr_table.ga_len) {
// did ":syntax clear"
return NULL; return NULL;
return &(ATTR_ENTRY(attr)); }
return ATTR_ENTRY(attr);
} }
/// \addtogroup LIST_XXX
/// @{
#define LIST_ATTR 1 #define LIST_ATTR 1
#define LIST_STRING 2 #define LIST_STRING 2
#define LIST_INT 3 #define LIST_INT 3
/// @}
static void highlight_list_one(int id) static void highlight_list_one(int id)
{ {
@ -6901,7 +6913,13 @@ static void highlight_list_one(int id)
last_set_msg(sgp->sg_scriptID); last_set_msg(sgp->sg_scriptID);
} }
static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name) /// 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 int highlight_list_arg(int id, int didh, int type, int iarg,
char_u *sarg, const char *name)
{ {
char_u buf[100]; char_u buf[100];
char_u *ts; char_u *ts;
@ -7041,24 +7059,23 @@ const char *highlight_color(const int id, const char *const what,
return NULL; return NULL;
} }
/* /// Output the syntax list header.
* Output the syntax list header. ///
* Return TRUE when started a new line. /// @param did_header did header already
*/ /// @param outlen length of string that comes
/// @param id highlight group id
/// @return true when started a new line.
static int static int
syn_list_header ( syn_list_header(int did_header, int outlen, int id)
int did_header, /* did header already */
int outlen, /* length of string that comes */
int id /* highlight group id */
)
{ {
int endcol = 19; int endcol = 19;
int newline = TRUE; int newline = TRUE;
if (!did_header) { if (!did_header) {
msg_putchar('\n'); msg_putchar('\n');
if (got_int) if (got_int) {
return TRUE; return true;
}
msg_outtrans(HL_TABLE()[id - 1].sg_name); msg_outtrans(HL_TABLE()[id - 1].sg_name);
endcol = 15; endcol = 15;
} else if (msg_col + outlen + 1 >= Columns) { } else if (msg_col + outlen + 1 >= Columns) {
@ -7095,12 +7112,13 @@ set_hl_attr (
int idx /* index in array */ int idx /* index in array */
) )
{ {
attrentry_T at_en; attrentry_T at_en = ATTRENTRY_INIT;
struct hl_group *sgp = HL_TABLE() + idx; struct hl_group *sgp = HL_TABLE() + idx;
/* The "Normal" group doesn't need an attribute number */ // The "Normal" group doesn't need an attribute number
if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) {
return; return;
}
at_en.cterm_ae_attr = sgp->sg_cterm; at_en.cterm_ae_attr = sgp->sg_cterm;
at_en.cterm_fg_color = sgp->sg_cterm_fg; at_en.cterm_fg_color = sgp->sg_cterm_fg;
@ -7124,10 +7142,10 @@ set_hl_attr (
} }
} }
/* /// Lookup a highlight group name and return its ID.
* Lookup a highlight group name and return it's ID. ///
* If it is not found, 0 is returned. /// @param highlight name e.g. 'Cursor', 'Normal'
*/ /// @return the highlight id, else 0 if \p name does not exist
int syn_name2id(const char_u *name) int syn_name2id(const char_u *name)
{ {
int i; int i;
@ -7176,7 +7194,7 @@ int syn_namen2id(char_u *linep, int len)
return id; return id;
} }
/// Find highlight group name in the table and return it's ID. /// Find highlight group name in the table and return its ID.
/// If it doesn't exist yet, a new entry is created. /// If it doesn't exist yet, a new entry is created.
/// ///
/// @param pp Highlight group name /// @param pp Highlight group name
@ -7195,11 +7213,11 @@ int syn_check_group(char_u *pp, int len)
return id; return id;
} }
/* /// Add new highlight group and return it's ID.
* Add new highlight group and return it's ID. ///
* "name" must be an allocated string, it will be consumed. /// @param name must be an allocated string, it will be consumed.
* Return 0 for failure. /// @return 0 for failure, else the allocated group id
*/ /// @see syn_check_group syn_unadd_group
static int syn_add_group(char_u *name) static int syn_add_group(char_u *name)
{ {
char_u *p; char_u *p;
@ -7237,25 +7255,26 @@ static int syn_add_group(char_u *name)
struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga); struct hl_group* hlgp = GA_APPEND_VIA_PTR(struct hl_group, &highlight_ga);
memset(hlgp, 0, sizeof(*hlgp)); memset(hlgp, 0, sizeof(*hlgp));
hlgp->sg_name = name; hlgp->sg_name = name;
hlgp->sg_rgb_bg = -1;
hlgp->sg_rgb_fg = -1;
hlgp->sg_rgb_sp = -1;
hlgp->sg_name_u = vim_strsave_up(name); hlgp->sg_name_u = vim_strsave_up(name);
return highlight_ga.ga_len; /* ID is index plus one */ return highlight_ga.ga_len; /* ID is index plus one */
} }
/* /// When, just after calling syn_add_group(), an error is discovered, this
* When, just after calling syn_add_group(), an error is discovered, this /// function deletes the new name.
* function deletes the new name.
*/
static void syn_unadd_group(void) static void syn_unadd_group(void)
{ {
--highlight_ga.ga_len; highlight_ga.ga_len--;
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name); xfree(HL_TABLE()[highlight_ga.ga_len].sg_name);
xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u); xfree(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
} }
/*
* Translate a group ID to highlight attributes. /// Translate a group ID to highlight attributes.
*/ /// @see syn_cterm_attr2entry
int syn_id2attr(int hl_id) int syn_id2attr(int hl_id)
{ {
struct hl_group *sgp; struct hl_group *sgp;

View File

@ -73,4 +73,14 @@ typedef struct attr_entry {
int cterm_fg_color, cterm_bg_color; int cterm_fg_color, cterm_bg_color;
} attrentry_T; } attrentry_T;
#define ATTRENTRY_INIT { \
.rgb_ae_attr = 0, \
.cterm_ae_attr = 0, \
.rgb_fg_color = -1, \
.rgb_bg_color = -1, \
.rgb_sp_color = -1, \
.cterm_fg_color = 0, \
.cterm_bg_color = 0, \
}
#endif // NVIM_SYNTAX_DEFS_H #endif // NVIM_SYNTAX_DEFS_H

View File

@ -5515,11 +5515,14 @@ void restore_buffer(bufref_T *save_curbuf)
} }
// Add match to the match list of window 'wp'. The pattern 'pat' will be /// Add match to the match list of window 'wp'. The pattern 'pat' will be
// highlighted with the group 'grp' with priority 'prio'. /// highlighted with the group 'grp' with priority 'prio'.
// Optionally, a desired ID 'id' can be specified (greater than or equal to 1). /// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
// If no particular ID is desired, -1 must be specified for 'id'. ///
// Return ID of added match, -1 on failure. /// @param[in] id a desired ID 'id' can be specified
/// (greater than or equal to 1). -1 must be specified if no
/// particular ID is desired
/// @return ID of added match, -1 on failure.
int match_add(win_T *wp, const char *const grp, const char *const pat, int match_add(win_T *wp, const char *const grp, const char *const pat,
int prio, int id, list_T *pos_list, int prio, int id, list_T *pos_list,
const char *const conceal_char) const char *const conceal_char)
@ -5697,10 +5700,9 @@ fail:
return -1; return -1;
} }
/*
* Delete match with ID 'id' in the match list of window 'wp'. /// Delete match with ID 'id' in the match list of window 'wp'.
* Print error messages if 'perr' is TRUE. /// Print error messages if 'perr' is TRUE.
*/
int match_delete(win_T *wp, int id, int perr) int match_delete(win_T *wp, int id, int perr)
{ {
matchitem_T *cur = wp->w_match_head; matchitem_T *cur = wp->w_match_head;

View File

@ -37,6 +37,7 @@ describe(':highlight', function()
feed('q') feed('q')
wait() -- wait until we're back to normal wait() -- wait until we're back to normal
command('hi Search') command('hi Search')
command('hi Normal')
-- Test setting colors. -- Test setting colors.
-- Test clearing one color and all doesn't generate error or warning -- Test clearing one color and all doesn't generate error or warning