forked from aniani/vim
patch 8.2.3578: manipulating highlighting is complicated
Problem: Manipulating highlighting is complicated. Solution: Add the hlget() and hlset() functions. (Yegappan Lakshmanan, closes #9039)
This commit is contained in:
parent
0f0044125c
commit
d1a8d658e1
@ -2718,6 +2718,8 @@ histget({history} [, {index}]) String get the item {index} from a history
|
||||
histnr({history}) Number highest index of a history
|
||||
hlID({name}) Number syntax ID of highlight group {name}
|
||||
hlexists({name}) Number |TRUE| if highlight group {name} exists
|
||||
hlget([{name} [, {resolve}]]) List get highlight group attributes
|
||||
hlset({list}) Number set highlight group attributes
|
||||
hostname() String name of the machine Vim is running on
|
||||
iconv({expr}, {from}, {to}) String convert encoding of {expr}
|
||||
indent({lnum}) Number indent of line {lnum}
|
||||
@ -6716,6 +6718,93 @@ hlexists({name}) *hlexists()*
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetName()->hlexists()
|
||||
<
|
||||
hlget([{name} [, {resolve}]]) *hlget()*
|
||||
Returns a List of all the highlight group attributes. If the
|
||||
optional {name} is specified, then returns a List with only
|
||||
the attributes of the specified highlight group. Returns an
|
||||
empty List if the highlight group {name} is not present.
|
||||
|
||||
If the optional {resolve} argument is set to v:true and the
|
||||
highlight group {name} is linked to another group, then the
|
||||
link is resolved recursively and the attributes of the
|
||||
resolved highlight group are returned.
|
||||
|
||||
Each entry in the returned List is a Dictionary with the
|
||||
following items:
|
||||
cleared Boolean flag, set to v:true if the highlight
|
||||
group attributes are cleared or not yet
|
||||
specified. See |highlight-clear|.
|
||||
cterm cterm attributes. See |highlight-cterm|.
|
||||
ctermbg cterm background color.
|
||||
See |highlight-ctermbg|.
|
||||
ctermfg cterm foreground color.
|
||||
See |highlight-ctermfg|.
|
||||
ctermul cterm underline color. See |highlight-ctermul|.
|
||||
font highlight group font. See |highlight-font|.
|
||||
gui gui attributes. See |highlight-gui|.
|
||||
guibg gui background color. See |highlight-guibg|.
|
||||
guifg gui foreground color. See |highlight-guifg|.
|
||||
guisp gui special color. See |highlight-guisp|.
|
||||
id highlight group ID.
|
||||
linksto linked highlight group name.
|
||||
See |:highlight-link|.
|
||||
name highlight group name. See |group-name|.
|
||||
start start terminal keycode. See |highlight-start|.
|
||||
stop stop terminal keycode. See |highlight-stop|.
|
||||
term term attributes. See |highlight-term|.
|
||||
|
||||
The 'term', 'cterm' and 'gui' items in the above Dictionary
|
||||
have a dictionary value with the following optional boolean
|
||||
items: 'bold', 'standout', 'underline', 'undercurl', 'italic',
|
||||
'reverse', 'inverse' and 'strikethrough'.
|
||||
|
||||
Example(s): >
|
||||
:echo hlget()
|
||||
:echo hlget('ModeMsg')
|
||||
:echo hlget('Number', v:true)
|
||||
<
|
||||
Can also be used as a |method|: >
|
||||
GetName()->hlget()
|
||||
<
|
||||
hlset({list}) *hlset()*
|
||||
Creates or modifies the attributes of a List of highlight
|
||||
groups. Each item in {list} is a dictionary containing the
|
||||
attributes of a highlight group. See |hlget()| for the list of
|
||||
supported items in this dictionary.
|
||||
|
||||
The highlight group is identified using the 'name' item and
|
||||
the 'id' item (if supplied) is ignored. If a highlight group
|
||||
with a specified name doesn't exist, then it is created.
|
||||
Otherwise the attributes of an existing highlight group are
|
||||
modified.
|
||||
|
||||
If an empty dictionary value is used for the 'term' or 'cterm'
|
||||
or 'gui' entries, then the corresponding attributes are
|
||||
cleared. If the 'cleared' item is set to v:true, then all the
|
||||
attributes of the highlight group are cleared.
|
||||
|
||||
The 'linksto' item can be used to link a highlight group to
|
||||
another highlight group. See |:highlight-link|.
|
||||
|
||||
Returns zero for success, -1 for failure.
|
||||
|
||||
Example(s): >
|
||||
" add bold attribute to the Visual highlight group
|
||||
:call hlset([#{name: 'Visual',
|
||||
\ term: #{reverse: 1 , bold: 1}}])
|
||||
:call hlset([#{name: 'Type', guifg: 'DarkGreen'}])
|
||||
:let l = hlget()
|
||||
:call hlset(l)
|
||||
" clear the Search highlight group
|
||||
:call hlset([#{name: 'Search', cleared: v:true}])
|
||||
" clear the 'term' attributes for a highlight group
|
||||
:call hlset([#{name: 'Title', term: {}}])
|
||||
" create the MyHlg group linking it to DiffAdd
|
||||
:call hlset([#{name: 'MyHlg', linksto: 'DiffAdd'}])
|
||||
<
|
||||
Can also be used as a |method|: >
|
||||
GetAttrList()->hlset()
|
||||
<
|
||||
*hlID()*
|
||||
hlID({name}) The result is a Number, which is the ID of the highlight group
|
||||
|
@ -4849,6 +4849,7 @@ in their own color.
|
||||
:hi[ghlight] {group-name}
|
||||
List one highlight group.
|
||||
|
||||
*highlight-clear*
|
||||
:hi[ghlight] clear Reset all highlighting to the defaults. Removes all
|
||||
highlighting for groups added by the user!
|
||||
Uses the current value of 'background' to decide which
|
||||
|
@ -925,6 +925,8 @@ Syntax and highlighting: *syntax-functions* *highlighting-functions*
|
||||
getmatches() get all matches defined by |matchadd()| and
|
||||
the |:match| commands
|
||||
hlexists() check if a highlight group exists
|
||||
hlget() get highlight group attributes
|
||||
hlset() set highlight group attributes
|
||||
hlID() get ID of a highlight group
|
||||
synID() get syntax ID at a specific position
|
||||
synIDattr() get a specific attribute of a syntax ID
|
||||
|
@ -1358,6 +1358,7 @@ directory Displays directory contents. Can be used by a file explorer
|
||||
< The buffer name is the name of the directory and is adjusted
|
||||
when using the |:cd| command.
|
||||
|
||||
*scratch-buffer*
|
||||
scratch Contains text that can be discarded at any time. It is kept
|
||||
when closing the window, it must be deleted explicitly.
|
||||
Settings: >
|
||||
|
@ -1527,6 +1527,10 @@ static funcentry_T global_functions[] =
|
||||
ret_number, f_hlID},
|
||||
{"hlexists", 1, 1, FEARG_1, arg1_string,
|
||||
ret_number_bool, f_hlexists},
|
||||
{"hlget", 0, 2, FEARG_1, arg2_string_bool,
|
||||
ret_list_dict_any, f_hlget},
|
||||
{"hlset", 1, 1, FEARG_1, arg1_list_any,
|
||||
ret_number_bool, f_hlset},
|
||||
{"hostname", 0, 0, 0, NULL,
|
||||
ret_string, f_hostname},
|
||||
{"iconv", 3, 3, FEARG_1, arg3_string,
|
||||
|
454
src/highlight.c
454
src/highlight.c
@ -4081,3 +4081,457 @@ free_highlight_fonts(void)
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
/*
|
||||
* Convert each of the highlight attribute bits (bold, standout, underline,
|
||||
* etc.) set in 'hlattr' into a separate boolean item in a Dictionary with
|
||||
* the attribute name as the key.
|
||||
*/
|
||||
static dict_T *
|
||||
highlight_get_attr_dict(int hlattr)
|
||||
{
|
||||
dict_T *dict;
|
||||
int i;
|
||||
|
||||
dict = dict_alloc();
|
||||
if (dict == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; hl_attr_table[i] != 0; ++i)
|
||||
{
|
||||
if (hlattr & hl_attr_table[i])
|
||||
{
|
||||
dict_add_bool(dict, hl_name_table[i], VVAL_TRUE);
|
||||
hlattr &= ~hl_attr_table[i]; // don't want "inverse"
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the attributes of the highlight group at index 'hl_idx' as a
|
||||
* Dictionary. If 'resolve_link' is TRUE, then resolves the highlight group
|
||||
* links recursively.
|
||||
*/
|
||||
static dict_T *
|
||||
highlight_get_info(int hl_idx, int resolve_link)
|
||||
{
|
||||
dict_T *dict;
|
||||
hl_group_T *sgp;
|
||||
dict_T *attr_dict;
|
||||
int hlgid;
|
||||
|
||||
dict = dict_alloc();
|
||||
if (dict == NULL)
|
||||
return dict;
|
||||
|
||||
sgp = &HL_TABLE()[hl_idx];
|
||||
// highlight group id is 1-based
|
||||
hlgid = hl_idx + 1;
|
||||
|
||||
if (dict_add_string(dict, "name", sgp->sg_name) == FAIL)
|
||||
goto error;
|
||||
if (dict_add_number(dict, "id", hlgid) == FAIL)
|
||||
goto error;
|
||||
|
||||
if (sgp->sg_link && resolve_link)
|
||||
{
|
||||
// resolve the highlight group link recursively
|
||||
while (sgp->sg_link)
|
||||
{
|
||||
hlgid = sgp->sg_link;
|
||||
sgp = &HL_TABLE()[sgp->sg_link - 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (sgp->sg_term != 0)
|
||||
{
|
||||
attr_dict = highlight_get_attr_dict(sgp->sg_term);
|
||||
if (attr_dict != NULL)
|
||||
if (dict_add_dict(dict, "term", attr_dict) == FAIL)
|
||||
goto error;
|
||||
}
|
||||
if (sgp->sg_start != NULL)
|
||||
if (dict_add_string(dict, "start", sgp->sg_start) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_stop != NULL)
|
||||
if (dict_add_string(dict, "stop", sgp->sg_stop) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_cterm != 0)
|
||||
{
|
||||
attr_dict = highlight_get_attr_dict(sgp->sg_cterm);
|
||||
if (attr_dict != NULL)
|
||||
if (dict_add_dict(dict, "cterm", attr_dict) == FAIL)
|
||||
goto error;
|
||||
}
|
||||
if (sgp->sg_cterm_fg != 0)
|
||||
if (dict_add_string(dict, "ctermfg",
|
||||
highlight_color(hlgid, (char_u *)"fg", 'c')) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_cterm_bg != 0)
|
||||
if (dict_add_string(dict, "ctermbg",
|
||||
highlight_color(hlgid, (char_u *)"bg", 'c')) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_cterm_ul != 0)
|
||||
if (dict_add_string(dict, "ctermul",
|
||||
highlight_color(hlgid, (char_u *)"ul", 'c')) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_gui != 0)
|
||||
{
|
||||
attr_dict = highlight_get_attr_dict(sgp->sg_gui);
|
||||
if (attr_dict != NULL)
|
||||
if (dict_add_dict(dict, "gui", attr_dict) == FAIL)
|
||||
goto error;
|
||||
}
|
||||
if (sgp->sg_gui_fg_name != NULL)
|
||||
if (dict_add_string(dict, "guifg",
|
||||
highlight_color(hlgid, (char_u *)"fg", 'g')) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_gui_bg_name != NULL)
|
||||
if (dict_add_string(dict, "guibg",
|
||||
highlight_color(hlgid, (char_u *)"bg", 'g')) == FAIL)
|
||||
goto error;
|
||||
if (sgp->sg_gui_sp_name != NULL)
|
||||
if (dict_add_string(dict, "guisp",
|
||||
highlight_color(hlgid, (char_u *)"sp", 'g')) == FAIL)
|
||||
goto error;
|
||||
# ifdef FEAT_GUI
|
||||
if (sgp->sg_font_name != NULL)
|
||||
if (dict_add_string(dict, "font", sgp->sg_font_name) == FAIL)
|
||||
goto error;
|
||||
# endif
|
||||
if (sgp->sg_link)
|
||||
{
|
||||
char_u *link;
|
||||
|
||||
link = HL_TABLE()[sgp->sg_link - 1].sg_name;
|
||||
if (link != NULL && dict_add_string(dict, "linksto", link) == FAIL)
|
||||
goto error;
|
||||
}
|
||||
if (dict_len(dict) == 2)
|
||||
// If only 'name' is present, then the highlight group is cleared.
|
||||
dict_add_bool(dict, "cleared", VVAL_TRUE);
|
||||
|
||||
return dict;
|
||||
|
||||
error:
|
||||
vim_free(dict);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* "hlget([name])" function
|
||||
* Return the attributes of a specific highlight group (if specified) or all
|
||||
* the highlight groups.
|
||||
*/
|
||||
void
|
||||
f_hlget(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
list_T *list;
|
||||
dict_T *dict;
|
||||
int i;
|
||||
char_u *hlarg = NULL;
|
||||
int resolve_link = FALSE;
|
||||
|
||||
if (rettv_list_alloc(rettv) == FAIL)
|
||||
return;
|
||||
|
||||
if (check_for_opt_string_arg(argvars, 0) == FAIL
|
||||
|| (argvars[0].v_type != VAR_UNKNOWN
|
||||
&& check_for_opt_bool_arg(argvars, 1) == FAIL))
|
||||
return;
|
||||
|
||||
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
// highlight group name supplied
|
||||
hlarg = tv_get_string_chk(&argvars[0]);
|
||||
if (hlarg == NULL)
|
||||
return;
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
int error = FALSE;
|
||||
|
||||
resolve_link = tv_get_bool_chk(&argvars[1], &error);
|
||||
if (error)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list = rettv->vval.v_list;
|
||||
for (i = 0; i < highlight_ga.ga_len && !got_int; ++i)
|
||||
{
|
||||
if (hlarg == NULL || STRICMP(hlarg, HL_TABLE()[i].sg_name) == 0)
|
||||
{
|
||||
dict = highlight_get_info(i, resolve_link);
|
||||
if (dict != NULL)
|
||||
list_append_dict(list, dict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the string value at 'dict[key]'. Returns NULL, if 'key' is not in
|
||||
* 'dict' or the value is not a string type. If the value is not a string type
|
||||
* or is NULL, then 'error' is set to TRUE.
|
||||
*/
|
||||
static char_u *
|
||||
hldict_get_string(dict_T *dict, char_u *key, int *error)
|
||||
{
|
||||
dictitem_T *di;
|
||||
|
||||
*error = FALSE;
|
||||
di = dict_find(dict, key, -1);
|
||||
if (di == NULL)
|
||||
return NULL;
|
||||
|
||||
if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL)
|
||||
{
|
||||
emsg(_(e_stringreq));
|
||||
*error = TRUE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return di->di_tv.vval.v_string;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the highlight attribute Dictionary at 'dict[key]' into a string
|
||||
* value in 'attr_str' of length 'len'. Returns FALSE if 'dict[key]' is not a
|
||||
* Dictionary or is NULL.
|
||||
*/
|
||||
static int
|
||||
hldict_attr_to_str(
|
||||
dict_T *dict,
|
||||
char_u *key,
|
||||
char_u *attr_str,
|
||||
int len)
|
||||
{
|
||||
dictitem_T *di;
|
||||
dict_T *attrdict;
|
||||
int i;
|
||||
|
||||
attr_str[0] = NUL;
|
||||
di = dict_find(dict, key, -1);
|
||||
if (di == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (di->di_tv.v_type != VAR_DICT || di->di_tv.vval.v_dict == NULL)
|
||||
{
|
||||
emsg(_(e_dictreq));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
attrdict = di->di_tv.vval.v_dict;
|
||||
|
||||
// If the attribute dict is empty, then return NONE to clear the attributes
|
||||
if (dict_len(attrdict) == 0)
|
||||
{
|
||||
vim_strcat(attr_str, (char_u *)"NONE", len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)ARRAY_LENGTH(hl_name_table); i++)
|
||||
{
|
||||
if (dict_get_bool(attrdict, (char_u *)hl_name_table[i],
|
||||
VVAL_FALSE) == VVAL_TRUE)
|
||||
{
|
||||
if (attr_str[0] != NUL)
|
||||
vim_strcat(attr_str, (char_u *)",", len);
|
||||
vim_strcat(attr_str, (char_u *)hl_name_table[i], len);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add or update a highlight group using 'dict' items. Returns TRUE if
|
||||
* successfully updated the highlight group.
|
||||
*/
|
||||
static int
|
||||
hlg_add_or_update(dict_T *dict)
|
||||
{
|
||||
char_u *name;
|
||||
int error;
|
||||
char_u term_attr[80];
|
||||
char_u cterm_attr[80];
|
||||
char_u gui_attr[80];
|
||||
char_u *start;
|
||||
char_u *stop;
|
||||
char_u *ctermfg;
|
||||
char_u *ctermbg;
|
||||
char_u *ctermul;
|
||||
char_u *guifg;
|
||||
char_u *guibg;
|
||||
char_u *guisp;
|
||||
# ifdef FEAT_GUI
|
||||
char_u *font;
|
||||
# endif
|
||||
|
||||
name = hldict_get_string(dict, (char_u *)"name", &error);
|
||||
if (name == NULL || error)
|
||||
return FALSE;
|
||||
|
||||
if (dict_find(dict, (char_u *)"linksto", -1) != NULL)
|
||||
{
|
||||
char_u *linksto;
|
||||
|
||||
// link highlight groups
|
||||
linksto = hldict_get_string(dict, (char_u *)"linksto", &error);
|
||||
if (linksto == NULL || error)
|
||||
return FALSE;
|
||||
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "link %s %s", name, linksto);
|
||||
do_highlight(IObuff, FALSE, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (dict_find(dict, (char_u *)"cleared", -1) != NULL)
|
||||
{
|
||||
varnumber_T cleared;
|
||||
|
||||
// clear a highlight group
|
||||
cleared = dict_get_bool(dict, (char_u *)"cleared", FALSE);
|
||||
if (cleared == TRUE)
|
||||
{
|
||||
vim_snprintf((char *)IObuff, IOSIZE, "clear %s", name);
|
||||
do_highlight(IObuff, FALSE, FALSE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
start = hldict_get_string(dict, (char_u *)"start", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
stop = hldict_get_string(dict, (char_u *)"stop", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
if (!hldict_attr_to_str(dict, (char_u *)"term", term_attr,
|
||||
sizeof(term_attr)))
|
||||
return FALSE;
|
||||
|
||||
if (!hldict_attr_to_str(dict, (char_u *)"cterm", cterm_attr,
|
||||
sizeof(cterm_attr)))
|
||||
return FALSE;
|
||||
|
||||
ctermfg = hldict_get_string(dict, (char_u *)"ctermfg", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
ctermbg = hldict_get_string(dict, (char_u *)"ctermbg", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
ctermul = hldict_get_string(dict, (char_u *)"ctermul", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
if (!hldict_attr_to_str(dict, (char_u *)"gui", gui_attr,
|
||||
sizeof(gui_attr)))
|
||||
return FALSE;
|
||||
|
||||
guifg = hldict_get_string(dict, (char_u *)"guifg", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
guibg = hldict_get_string(dict, (char_u *)"guibg", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
guisp = hldict_get_string(dict, (char_u *)"guisp", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
|
||||
# ifdef FEAT_GUI
|
||||
font = hldict_get_string(dict, (char_u *)"font", &error);
|
||||
if (error)
|
||||
return FALSE;
|
||||
# endif
|
||||
|
||||
// If none of the attributes are specified, then do nothing.
|
||||
if (term_attr[0] == NUL && start == NULL && stop == NULL
|
||||
&& cterm_attr[0] == NUL && ctermfg == NULL && ctermbg == NULL
|
||||
&& ctermul == NULL && gui_attr[0] == NUL
|
||||
# ifdef FEAT_GUI
|
||||
&& font == NULL
|
||||
# endif
|
||||
&& guifg == NULL && guibg == NULL && guisp == NULL
|
||||
)
|
||||
return TRUE;
|
||||
|
||||
vim_snprintf((char *)IObuff, IOSIZE,
|
||||
"%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s",
|
||||
name,
|
||||
term_attr[0] != NUL ? "term=" : "",
|
||||
term_attr[0] != NUL ? term_attr : (char_u *)"",
|
||||
start != NULL ? "start=" : "",
|
||||
start != NULL ? start : (char_u *)"",
|
||||
stop != NULL ? "stop=" : "",
|
||||
stop != NULL ? stop : (char_u *)"",
|
||||
cterm_attr[0] != NUL ? "cterm=" : "",
|
||||
cterm_attr[0] != NUL ? cterm_attr : (char_u *)"",
|
||||
ctermfg != NULL ? "ctermfg=" : "",
|
||||
ctermfg != NULL ? ctermfg : (char_u *)"",
|
||||
ctermbg != NULL ? "ctermbg=" : "",
|
||||
ctermbg != NULL ? ctermbg : (char_u *)"",
|
||||
ctermul != NULL ? "ctermul=" : "",
|
||||
ctermul != NULL ? ctermul : (char_u *)"",
|
||||
gui_attr[0] != NUL ? "gui=" : "",
|
||||
gui_attr[0] != NUL ? gui_attr : (char_u *)"",
|
||||
# ifdef FEAT_GUI
|
||||
font != NULL ? "font=" : "",
|
||||
font != NULL ? font : (char_u *)"",
|
||||
# else
|
||||
"", "",
|
||||
# endif
|
||||
guifg != NULL ? "guifg=" : "",
|
||||
guifg != NULL ? guifg : (char_u *)"",
|
||||
guibg != NULL ? "guibg=" : "",
|
||||
guibg != NULL ? guibg : (char_u *)"",
|
||||
guisp != NULL ? "guisp=" : "",
|
||||
guisp != NULL ? guisp : (char_u *)""
|
||||
);
|
||||
|
||||
do_highlight(IObuff, FALSE, FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* "hlset([{highlight_attr}])" function
|
||||
* Add or modify highlight groups
|
||||
*/
|
||||
void
|
||||
f_hlset(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
listitem_T *li;
|
||||
dict_T *dict;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
|
||||
if (check_for_list_arg(argvars, 0) == FAIL)
|
||||
return;
|
||||
|
||||
FOR_ALL_LIST_ITEMS(argvars->vval.v_list, li)
|
||||
{
|
||||
if (li->li_tv.v_type != VAR_DICT)
|
||||
{
|
||||
emsg(_(e_dictreq));
|
||||
return;
|
||||
}
|
||||
|
||||
dict = li->li_tv.vval.v_dict;
|
||||
if (!hlg_add_or_update(dict))
|
||||
return;
|
||||
}
|
||||
|
||||
rettv->vval.v_number = 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -49,4 +49,6 @@ void set_context_in_highlight_cmd(expand_T *xp, char_u *arg);
|
||||
char_u *get_highlight_name(expand_T *xp, int idx);
|
||||
char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
|
||||
void free_highlight_fonts(void);
|
||||
void f_hlget(typval_T *argvars, typval_T *rettv);
|
||||
void f_hlset(typval_T *argvars, typval_T *rettv);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -4,6 +4,7 @@ source view_util.vim
|
||||
source screendump.vim
|
||||
source check.vim
|
||||
source script_util.vim
|
||||
source vim9.vim
|
||||
|
||||
func Test_highlight()
|
||||
" basic test if ":highlight" doesn't crash
|
||||
@ -970,4 +971,164 @@ func Test_colornames_assignment_and_unassignment()
|
||||
call assert_fails("echo v:colornames['x1']")
|
||||
endfunc
|
||||
|
||||
" Test for the hlget() function
|
||||
func Test_hlget()
|
||||
let lines =<< trim END
|
||||
call assert_notequal([], filter(hlget(), 'v:val.name == "Visual"'))
|
||||
call assert_equal([], hlget('SomeHLGroup'))
|
||||
highlight MyHLGroup term=standout cterm=reverse ctermfg=10 ctermbg=Black
|
||||
call assert_equal([{'id': hlID('MyHLGroup'), 'ctermfg': '10', 'name': 'MyHLGroup', 'term': {'standout': v:true}, 'ctermbg': '0', 'cterm': {'reverse': v:true}}], hlget('MyHLGroup'))
|
||||
highlight clear MyHLGroup
|
||||
call assert_equal(v:true, hlget('MyHLGroup')[0].cleared)
|
||||
highlight link MyHLGroup IncSearch
|
||||
call assert_equal('IncSearch', hlget('MyHLGroup')[0].linksto)
|
||||
highlight clear MyHLGroup
|
||||
call assert_equal([], hlget(test_null_string()))
|
||||
call assert_equal([], hlget(""))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
" Test for resolving highlight group links
|
||||
let lines =<< trim END
|
||||
highlight hlgA term=bold
|
||||
VAR hlgAid = hlID('hlgA')
|
||||
highlight link hlgB hlgA
|
||||
VAR hlgBid = hlID('hlgB')
|
||||
highlight link hlgC hlgB
|
||||
VAR hlgCid = hlID('hlgC')
|
||||
call assert_equal('hlgA', hlget('hlgB')[0].linksto)
|
||||
call assert_equal('hlgB', hlget('hlgC')[0].linksto)
|
||||
call assert_equal([{'id': hlgAid, 'name': 'hlgA',
|
||||
\ 'term': {'bold': v:true}}], hlget('hlgA'))
|
||||
call assert_equal([{'id': hlgBid, 'name': 'hlgB',
|
||||
\ 'linksto': 'hlgA'}], hlget('hlgB'))
|
||||
call assert_equal([{'id': hlgCid, 'name': 'hlgC',
|
||||
\ 'linksto': 'hlgB'}], hlget('hlgC'))
|
||||
call assert_equal([{'id': hlgAid, 'name': 'hlgA',
|
||||
\ 'term': {'bold': v:true}}], hlget('hlgA', v:false))
|
||||
call assert_equal([{'id': hlgBid, 'name': 'hlgB',
|
||||
\ 'linksto': 'hlgA'}], hlget('hlgB', 0))
|
||||
call assert_equal([{'id': hlgCid, 'name': 'hlgC',
|
||||
\ 'linksto': 'hlgB'}], hlget('hlgC', v:false))
|
||||
call assert_equal([{'id': hlgAid, 'name': 'hlgA',
|
||||
\ 'term': {'bold': v:true}}], hlget('hlgA', v:true))
|
||||
call assert_equal([{'id': hlgBid, 'name': 'hlgB',
|
||||
\ 'term': {'bold': v:true}}], hlget('hlgB', 1))
|
||||
call assert_equal([{'id': hlgCid, 'name': 'hlgC',
|
||||
\ 'term': {'bold': v:true}}], hlget('hlgC', v:true))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
call assert_fails('call hlget([])', 'E1174:')
|
||||
call assert_fails('call hlget("abc", "xyz")', 'E1212:')
|
||||
endfunc
|
||||
|
||||
" Test for the hlset() function
|
||||
func Test_hlset()
|
||||
let lines =<< trim END
|
||||
call assert_equal(0, hlset(test_null_list()))
|
||||
call assert_equal(0, hlset([]))
|
||||
call assert_fails('call hlset(["Search"])', 'E715:')
|
||||
call hlset(hlget())
|
||||
call hlset([{'name': 'NewHLGroup', 'cterm': {'reverse': v:true}, 'ctermfg': '10'}])
|
||||
call assert_equal({'reverse': v:true}, hlget('NewHLGroup')[0].cterm)
|
||||
call hlset([{'name': 'NewHLGroup', 'cterm': {'bold': v:true}}])
|
||||
call assert_equal({'bold': v:true}, hlget('NewHLGroup')[0].cterm)
|
||||
call hlset([{'name': 'NewHLGroup', 'cleared': v:true}])
|
||||
call assert_equal(v:true, hlget('NewHLGroup')[0].cleared)
|
||||
call hlset([{'name': 'NewHLGroup', 'linksto': 'Search'}])
|
||||
call assert_false(has_key(hlget('NewHLGroup')[0], 'cleared'))
|
||||
call assert_equal('Search', hlget('NewHLGroup')[0].linksto)
|
||||
call assert_fails("call hlset([{'name': [], 'ctermfg': '10'}])", 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'cleared': []}])",
|
||||
\ 'E745:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'cterm': 'Blue'}])",
|
||||
\ 'E715:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermbg': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermfg': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'ctermul': []}])",
|
||||
\ 'E928:')
|
||||
if has('gui')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'font': []}])",
|
||||
\ 'E928:')
|
||||
endif
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'gui': 'Cyan'}])",
|
||||
\ 'E715:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'guibg': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'guifg': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'guisp': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'linksto': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'start': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'stop': []}])",
|
||||
\ 'E928:')
|
||||
call assert_fails("call hlset([{'name': 'NewHLGroup', 'term': 'Cyan'}])",
|
||||
\ 'E715:')
|
||||
call assert_equal('Search', hlget('NewHLGroup')[0].linksto)
|
||||
highlight clear NewHLGroup
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
" Test for clearing the 'term', 'cterm' and 'gui' attributes of a highlight
|
||||
" group.
|
||||
let lines =<< trim END
|
||||
highlight myhlg1 term=bold cterm=italic gui=standout
|
||||
VAR id = hlID('myhlg1')
|
||||
call hlset([{'name': 'myhlg1', 'term': {}}])
|
||||
call assert_equal([{'id': id, 'name': 'myhlg1',
|
||||
\ 'cterm': {'italic': v:true}, 'gui': {'standout': v:true}}],
|
||||
\ hlget('myhlg1'))
|
||||
call hlset([{'name': 'myhlg1', 'cterm': {}}])
|
||||
call assert_equal([{'id': id, 'name': 'myhlg1',
|
||||
\ 'gui': {'standout': v:true}}], hlget('myhlg1'))
|
||||
call hlset([{'name': 'myhlg1', 'gui': {}}])
|
||||
call assert_equal([{'id': id, 'name': 'myhlg1', 'cleared': v:true}],
|
||||
\ hlget('myhlg1'))
|
||||
highlight clear myhlg1
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
" Test for setting all the 'term', 'cterm' and 'gui' attributes of a
|
||||
" highlight group
|
||||
let lines =<< trim END
|
||||
VAR attr = {'bold': v:true, 'underline': v:true, 'undercurl': v:true,
|
||||
\ 'strikethrough': v:true, 'reverse': v:true, 'italic': v:true,
|
||||
\ 'standout': v:true, 'nocombine': v:true}
|
||||
call hlset([{'name': 'myhlg2', 'term': attr, 'cterm': attr, 'gui': attr}])
|
||||
VAR id2 = hlID('myhlg2')
|
||||
VAR output =<< trim END
|
||||
myhlg2 xxx term=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
|
||||
cterm=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
|
||||
gui=bold,standout,underline,undercurl,italic,reverse,nocombine,strikethrough
|
||||
END
|
||||
call assert_equal(output, execute('highlight myhlg2')->split("\n"))
|
||||
call assert_equal([{'id': id2, 'name': 'myhlg2', 'gui': attr,
|
||||
\ 'term': attr, 'cterm': attr}], hlget('myhlg2'))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
|
||||
" Test for clearing some of the 'term', 'cterm' and 'gui' attributes of a
|
||||
" highlight group
|
||||
let lines =<< trim END
|
||||
VAR attr = {'bold': v:false, 'underline': v:true, 'strikethrough': v:true}
|
||||
call hlset([{'name': 'myhlg2', 'term': attr, 'cterm': attr, 'gui': attr}])
|
||||
VAR id2 = hlID('myhlg2')
|
||||
VAR output =<< trim END
|
||||
myhlg2 xxx term=underline,strikethrough cterm=underline,strikethrough
|
||||
gui=underline,strikethrough
|
||||
END
|
||||
call assert_equal(output, execute('highlight myhlg2')->split("\n"))
|
||||
LET attr = {'underline': v:true, 'strikethrough': v:true}
|
||||
call assert_equal([{'id': id2, 'name': 'myhlg2', 'gui': attr,
|
||||
\ 'term': attr, 'cterm': attr}], hlget('myhlg2'))
|
||||
END
|
||||
call CheckLegacyAndVim9Success(lines)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1721,6 +1721,16 @@ def Test_hlexists()
|
||||
hlexists('')->assert_equal(0)
|
||||
enddef
|
||||
|
||||
def Test_hlget()
|
||||
CheckDefAndScriptFailure2(['hlget([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
|
||||
hlget('')->assert_equal([])
|
||||
enddef
|
||||
|
||||
def Test_hlset()
|
||||
CheckDefAndScriptFailure2(['hlset("id")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
|
||||
hlset([])->assert_equal(0)
|
||||
enddef
|
||||
|
||||
def Test_iconv()
|
||||
CheckDefAndScriptFailure2(['iconv(1, "from", "to")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
|
||||
CheckDefAndScriptFailure2(['iconv("abc", 10, "to")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
|
||||
|
Loading…
x
Reference in New Issue
Block a user