mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
Merge #6973 from teto/normal_hl
This commit is contained in:
commit
7f7698649f
@ -81,7 +81,10 @@ struct hl_group {
|
||||
// highlight groups for 'highlight' option
|
||||
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. */
|
||||
|
||||
@ -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_link = 0; /* when 2 include "nvim/link" and "clear" */
|
||||
|
||||
/*
|
||||
* The "term", "cterm" and "gui" arguments can be any combination of the
|
||||
* following names, separated by commas (but no spaces!).
|
||||
*/
|
||||
/// 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",
|
||||
"italic", "reverse", "inverse", "NONE"};
|
||||
@ -1775,8 +1776,9 @@ syn_current_attr (
|
||||
cur_si->si_trans_id = CUR_STATE(
|
||||
current_state.ga_len - 2).si_trans_id;
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
cur_si->si_attr = syn_id2attr(syn_id);
|
||||
}
|
||||
cur_si->si_cont_list = NULL;
|
||||
cur_si->si_next_list = next_list;
|
||||
check_keepend();
|
||||
@ -5252,12 +5254,10 @@ get_id_list (
|
||||
/*
|
||||
* 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));
|
||||
else {
|
||||
/*
|
||||
* Handle match of regexp with group names.
|
||||
*/
|
||||
} else {
|
||||
// Handle match of regexp with group names.
|
||||
*name = '^';
|
||||
STRCAT(name, "$");
|
||||
regmatch.regprog = vim_regcomp(name, RE_MAGIC);
|
||||
@ -5958,6 +5958,7 @@ static char *highlight_init_light[] =
|
||||
"Title ctermfg=DarkMagenta gui=bold guifg=Magenta",
|
||||
"Visual guibg=LightGrey",
|
||||
"WarningMsg ctermfg=DarkRed guifg=Red",
|
||||
"Normal gui=NONE",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -5991,23 +5992,25 @@ static char *highlight_init_dark[] =
|
||||
"Title ctermfg=LightMagenta gui=bold guifg=Magenta",
|
||||
"Visual guibg=DarkGrey",
|
||||
"WarningMsg ctermfg=LightRed guifg=Red",
|
||||
"Normal gui=NONE",
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
init_highlight (
|
||||
int both, /* include groups where 'bg' doesn't matter */
|
||||
int reset /* clear group first */
|
||||
)
|
||||
|
||||
/// 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(int both, int reset)
|
||||
{
|
||||
int i;
|
||||
char **pp;
|
||||
static int had_both = FALSE;
|
||||
|
||||
/*
|
||||
* Try finding the color scheme file. Used when a color file was loaded
|
||||
* and 'background' or 't_Co' is changed.
|
||||
*/
|
||||
// Try finding the color scheme file. Used when a color file was loaded
|
||||
// and 'background' or 't_Co' is changed.
|
||||
char_u *p = get_var_value("g:colors_name");
|
||||
if (p != NULL) {
|
||||
// Value of g:colors_name could be freed in load_colors() and make
|
||||
@ -6026,33 +6029,34 @@ init_highlight (
|
||||
if (both) {
|
||||
had_both = TRUE;
|
||||
pp = highlight_init_both;
|
||||
for (i = 0; pp[i] != NULL; ++i)
|
||||
do_highlight((char_u *)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. */
|
||||
for (i = 0; pp[i] != NULL; i++) {
|
||||
do_highlight((char_u *)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;
|
||||
}
|
||||
|
||||
if (*p_bg == 'l')
|
||||
pp = highlight_init_light;
|
||||
else
|
||||
pp = highlight_init_dark;
|
||||
for (i = 0; pp[i] != NULL; ++i)
|
||||
do_highlight((char_u *)pp[i], reset, TRUE);
|
||||
pp = (*p_bg == 'l') ? highlight_init_light : highlight_init_dark;
|
||||
|
||||
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
|
||||
* depend on the number of colors available.
|
||||
* With 8 colors brown is equal to yellow, need to use black for Search fg
|
||||
* to avoid Statement highlighted text disappears.
|
||||
* Clear the attributes, needed when changing the t_Co value. */
|
||||
if (t_colors > 8)
|
||||
if (t_colors > 8) {
|
||||
do_highlight(
|
||||
(char_u *)(*p_bg == 'l'
|
||||
? "Visual cterm=NONE ctermbg=LightGrey"
|
||||
: "Visual cterm=NONE ctermbg=DarkGrey"), FALSE,
|
||||
TRUE);
|
||||
else {
|
||||
: "Visual cterm=NONE ctermbg=DarkGrey"), false,
|
||||
true);
|
||||
} else {
|
||||
do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
|
||||
FALSE, TRUE);
|
||||
if (*p_bg == 'l')
|
||||
@ -6112,12 +6116,7 @@ int load_colors(char_u *name)
|
||||
/// "forceit" and "init" both TRUE.
|
||||
/// @param init TRUE when called for initializing
|
||||
void
|
||||
do_highlight(
|
||||
char_u *line,
|
||||
int forceit,
|
||||
int init
|
||||
)
|
||||
{
|
||||
do_highlight(char_u *line, int forceit, int init) {
|
||||
char_u *name_end;
|
||||
char_u *linep;
|
||||
char_u *key_start;
|
||||
@ -6134,15 +6133,16 @@ do_highlight(
|
||||
int dolink = FALSE;
|
||||
int error = FALSE;
|
||||
int color;
|
||||
int is_normal_group = FALSE; /* "Normal" group */
|
||||
bool is_normal_group = false; // "Normal" group
|
||||
|
||||
/*
|
||||
* If no argument, list current highlighting.
|
||||
*/
|
||||
if (ends_excmd(*line)) {
|
||||
for (int i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
|
||||
/* TODO: only call when the group has attributes set */
|
||||
for (int i = 1; i <= highlight_ga.ga_len && !got_int; i++) {
|
||||
// todo(vim): only call when the group has attributes set
|
||||
highlight_list_one(i);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6270,12 +6270,12 @@ do_highlight(
|
||||
return;
|
||||
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 if "default" was used and the group already has settings
|
||||
if (dodefault && hl_has_settings(idx, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
|
||||
is_normal_group = TRUE;
|
||||
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)) {
|
||||
@ -6284,7 +6284,7 @@ do_highlight(
|
||||
HL_TABLE()[idx].sg_set = 0;
|
||||
}
|
||||
|
||||
if (!doclear)
|
||||
if (!doclear) {
|
||||
while (!ends_excmd(*linep)) {
|
||||
key_start = linep;
|
||||
if (*linep == '=') {
|
||||
@ -6390,12 +6390,12 @@ do_highlight(
|
||||
}
|
||||
}
|
||||
} else if (STRCMP(key, "FONT") == 0) {
|
||||
/* in non-GUI fonts are simply ignored */
|
||||
} else if (STRCMP(key,
|
||||
"CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 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)
|
||||
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 */
|
||||
@ -6489,9 +6489,10 @@ do_highlight(
|
||||
* colors (on some terminals, e.g. "linux") */
|
||||
if (color & 8) {
|
||||
HL_TABLE()[idx].sg_cterm |= HL_BOLD;
|
||||
HL_TABLE()[idx].sg_cterm_bold = TRUE;
|
||||
} else
|
||||
HL_TABLE()[idx].sg_cterm_bold = true;
|
||||
} else {
|
||||
HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
|
||||
}
|
||||
}
|
||||
color &= 7; // truncate to 8 colors
|
||||
} 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.
|
||||
*/
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
|
||||
if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) {
|
||||
HL_TABLE()[idx].sg_link = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continue with next argument.
|
||||
*/
|
||||
linep = skipwhite(linep);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
else {
|
||||
} else {
|
||||
if (is_normal_group) {
|
||||
HL_TABLE()[idx].sg_attr = 0;
|
||||
// Need to update all groups, because they might be using "bg" and/or
|
||||
@ -6625,16 +6628,17 @@ do_highlight(
|
||||
highlight_attr_set_all();
|
||||
// If the normal group has changed, it is simpler to refresh every UI
|
||||
ui_refresh();
|
||||
} else
|
||||
} else {
|
||||
set_hl_attr(idx);
|
||||
}
|
||||
HL_TABLE()[idx].sg_scriptID = current_SID;
|
||||
redraw_all_later(NOT_VALID);
|
||||
}
|
||||
xfree(key);
|
||||
xfree(arg);
|
||||
|
||||
/* Only call highlight_changed() once, after sourcing a syntax file */
|
||||
need_highlight_changed = TRUE;
|
||||
// Only call highlight_changed() once, after sourcing a syntax file
|
||||
need_highlight_changed = true;
|
||||
}
|
||||
|
||||
#if defined(EXITFREE)
|
||||
@ -6707,14 +6711,15 @@ static void highlight_clear(int idx)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Table with the specifications for an attribute number.
|
||||
* Note that this table is used by ALL buffers. This is required because the
|
||||
* GUI can redraw at any time for any buffer.
|
||||
*/
|
||||
/// Table with the specifications for an attribute number.
|
||||
/// Note that this table is used by ALL buffers. This is required because the
|
||||
/// GUI can redraw at any time for any buffer.
|
||||
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.
|
||||
@ -6804,7 +6809,7 @@ int hl_combine_attr(int char_attr, int prim_attr)
|
||||
{
|
||||
attrentry_T *char_aep = NULL;
|
||||
attrentry_T *spell_aep;
|
||||
attrentry_T new_en;
|
||||
attrentry_T new_en = ATTRENTRY_INIT;
|
||||
|
||||
if (char_attr == 0) {
|
||||
return prim_attr;
|
||||
@ -6852,17 +6857,24 @@ int hl_combine_attr(int char_attr, int prim_attr)
|
||||
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)
|
||||
{
|
||||
attr -= ATTR_OFF;
|
||||
if (attr >= attr_table.ga_len) /* did ":syntax clear" */
|
||||
if (attr >= attr_table.ga_len) {
|
||||
// did ":syntax clear"
|
||||
return NULL;
|
||||
return &(ATTR_ENTRY(attr));
|
||||
}
|
||||
return ATTR_ENTRY(attr);
|
||||
}
|
||||
|
||||
/// \addtogroup LIST_XXX
|
||||
/// @{
|
||||
#define LIST_ATTR 1
|
||||
#define LIST_STRING 2
|
||||
#define LIST_INT 3
|
||||
/// @}
|
||||
|
||||
static void highlight_list_one(int id)
|
||||
{
|
||||
@ -6901,7 +6913,13 @@ static void highlight_list_one(int id)
|
||||
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 *ts;
|
||||
@ -7041,24 +7059,23 @@ const char *highlight_color(const int id, const char *const what,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Output the syntax list header.
|
||||
* Return TRUE when started a new line.
|
||||
*/
|
||||
static int
|
||||
syn_list_header (
|
||||
int did_header, /* did header already */
|
||||
int outlen, /* length of string that comes */
|
||||
int id /* highlight group id */
|
||||
)
|
||||
/// Output the syntax list header.
|
||||
///
|
||||
/// @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
|
||||
syn_list_header(int did_header, int outlen, int id)
|
||||
{
|
||||
int endcol = 19;
|
||||
int newline = TRUE;
|
||||
|
||||
if (!did_header) {
|
||||
msg_putchar('\n');
|
||||
if (got_int)
|
||||
return TRUE;
|
||||
if (got_int) {
|
||||
return true;
|
||||
}
|
||||
msg_outtrans(HL_TABLE()[id - 1].sg_name);
|
||||
endcol = 15;
|
||||
} else if (msg_col + outlen + 1 >= Columns) {
|
||||
@ -7095,12 +7112,13 @@ set_hl_attr (
|
||||
int idx /* index in array */
|
||||
)
|
||||
{
|
||||
attrentry_T at_en;
|
||||
attrentry_T at_en = ATTRENTRY_INIT;
|
||||
struct hl_group *sgp = HL_TABLE() + idx;
|
||||
|
||||
/* The "Normal" group doesn't need an attribute number */
|
||||
if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
|
||||
// The "Normal" group doesn't need an attribute number
|
||||
if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
at_en.cterm_ae_attr = sgp->sg_cterm;
|
||||
at_en.cterm_fg_color = sgp->sg_cterm_fg;
|
||||
@ -7124,10 +7142,10 @@ set_hl_attr (
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup a highlight group name and return it's ID.
|
||||
* If it is not found, 0 is returned.
|
||||
*/
|
||||
/// 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(const char_u *name)
|
||||
{
|
||||
int i;
|
||||
@ -7176,7 +7194,7 @@ int syn_namen2id(char_u *linep, int len)
|
||||
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.
|
||||
///
|
||||
/// @param pp Highlight group name
|
||||
@ -7195,11 +7213,11 @@ int syn_check_group(char_u *pp, int len)
|
||||
return id;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add new highlight group and return it's ID.
|
||||
* "name" must be an allocated string, it will be consumed.
|
||||
* Return 0 for failure.
|
||||
*/
|
||||
/// Add new highlight group and return it's 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 syn_unadd_group
|
||||
static int syn_add_group(char_u *name)
|
||||
{
|
||||
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);
|
||||
memset(hlgp, 0, sizeof(*hlgp));
|
||||
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);
|
||||
|
||||
return highlight_ga.ga_len; /* ID is index plus one */
|
||||
}
|
||||
|
||||
/*
|
||||
* When, just after calling syn_add_group(), an error is discovered, this
|
||||
* function deletes the new name.
|
||||
*/
|
||||
/// When, just after calling syn_add_group(), an error is discovered, this
|
||||
/// function deletes the new name.
|
||||
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_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)
|
||||
{
|
||||
struct hl_group *sgp;
|
||||
|
@ -73,4 +73,14 @@ typedef struct attr_entry {
|
||||
int cterm_fg_color, cterm_bg_color;
|
||||
} 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
|
||||
|
@ -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
|
||||
// highlighted with the group 'grp' with priority 'prio'.
|
||||
// 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.
|
||||
/// Add match to the match list of window 'wp'. The pattern 'pat' will be
|
||||
/// highlighted with the group 'grp' with priority 'prio'.
|
||||
/// Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
|
||||
///
|
||||
/// @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 prio, int id, list_T *pos_list,
|
||||
const char *const conceal_char)
|
||||
@ -5697,10 +5700,9 @@ fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete match with ID 'id' in the match list of window 'wp'.
|
||||
* Print error messages if 'perr' is TRUE.
|
||||
*/
|
||||
|
||||
/// Delete match with ID 'id' in the match list of window 'wp'.
|
||||
/// Print error messages if 'perr' is TRUE.
|
||||
int match_delete(win_T *wp, int id, int perr)
|
||||
{
|
||||
matchitem_T *cur = wp->w_match_head;
|
||||
|
@ -37,6 +37,7 @@ describe(':highlight', function()
|
||||
feed('q')
|
||||
wait() -- wait until we're back to normal
|
||||
command('hi Search')
|
||||
command('hi Normal')
|
||||
|
||||
-- Test setting colors.
|
||||
-- Test clearing one color and all doesn't generate error or warning
|
||||
|
Loading…
Reference in New Issue
Block a user