patch 9.2.0263: hlset() cannot handle attributes with spaces

Problem:  hlset() cannot handle attributes with spaces
Solution: Handle attributes with spaces by quoting those
          (Yasuhiro Matsumoto).

hlset(hlget('Normal')) fails with E416 when a highlight attribute value
contains spaces (e.g. font name "Monospace 10"). hlg_add_or_update()
builds a string like "font=Monospace 10" and passes it to do_highlight(),
whose parser splits on whitespace and treats "10" as a separate key
without "=".

Fix by quoting values with single quotes (e.g. font='Monospace 10')
when the value contains spaces and the attribute is a key=value pair.
do_highlight() already supports single-quoted values.

closes: #19843

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yasuhiro Matsumoto
2026-03-28 09:47:15 +00:00
committed by Christian Brabandt
parent 80a0c355cf
commit 8e29c35a04
3 changed files with 31 additions and 12 deletions
+17 -1
View File
@@ -5309,7 +5309,23 @@ add_attr_and_value(char_u *dptr, char_u *attr, int attrlen, char_u *value)
return dptr;
vallen = STRLEN(value);
if (dptr + attrlen + vallen + 1 < hlsetBuf + HLSETBUFSZ)
// When the value contains a space and the attribute has an "=" (i.e. it
// is a key=value pair), surround the value with single quotes so that
// do_highlight() can parse it correctly.
if (vim_strchr(value, ' ') != NULL && vim_strchr(attr, '=') != NULL)
{
if (dptr + attrlen + vallen + 3 < hlsetBuf + HLSETBUFSZ)
{
STRCPY(dptr, attr);
dptr += attrlen;
*dptr++ = '\'';
STRCPY(dptr, value);
dptr += vallen;
*dptr++ = '\'';
*dptr = NUL;
}
}
else if (dptr + attrlen + vallen + 1 < hlsetBuf + HLSETBUFSZ)
{
STRCPY(dptr, attr);
dptr += attrlen;
+12 -11
View File
@@ -1142,17 +1142,9 @@ endfunc
" Test for the hlset() function
func Test_hlset()
" FIXME: With GVim, _current_ test cases that are run before this one may
" influence the result of calling "hlset(hlget())", depending on what
" "&guifont" is set to. For example, introduce SetUp() as follows:
"
" if CanRunVimInTerminal() && has('gui_running') && has('gui_gtk')
" def SetUp()
" set guifont=Monospace\ 10
" enddef
" endif
"
" and see "E416: Missing equal sign: ... line 4" for this test case.
" Note: hlset() now correctly handles attribute values containing spaces
" by quoting them, so hlset(hlget()) works even with font names like
" "Monospace 10".
let lines =<< trim END
call assert_equal(0, hlset(test_null_list()))
call assert_equal(0, hlset([]))
@@ -1353,6 +1345,15 @@ func Test_hlset()
call hlset([{'name': 'hlg11', 'stop': ''}])
call hlset([{'name': 'hlg11', 'term': {}}])
call assert_true(hlget('hlg11')[0].cleared)
" Test that hlset() handles attribute values containing spaces
call hlset([{'name': 'hlg12', 'guifg': 'light blue'}])
call assert_equal('light blue', hlget('hlg12')[0].guifg)
call hlset([{'name': 'hlg12', 'guibg': 'dark red'}])
call assert_equal('dark red', hlget('hlg12')[0].guibg)
call hlset([{'name': 'hlg12', 'guisp': 'sea green'}])
call assert_equal('sea green', hlget('hlg12')[0].guisp)
highlight clear hlg12
endfunc
" Test for the 'winhighlight' option
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
263,
/**/
262,
/**/