Commit: patch 9.2.0929: incorrect completion for 'pumopt' and 'pumborder'

3 views
Skip to first unread message

Christian Brabandt

unread,
Aug 10, 2026, 3:00:14 PM (21 hours ago) Aug 10
to vim...@googlegroups.com
patch 9.2.0929: incorrect completion for 'pumopt' and 'pumborder'

Commit: https://github.com/vim/vim/commit/9aba04ff7a3205147a465c7214d666f13ff8b447
Author: Shane Harper <sh...@shaneharper.net>
Date: Mon Aug 10 18:47:11 2026 +0000

patch 9.2.0929: incorrect completion for 'pumopt' and 'pumborder'

Problem: Incorrect completions are offered for the 'pumopt' and
'pumborder' options.
Solution: Fix expand_set_pumborder() and expand_set_pumopt() to only
offer valid completions (Shane Harper).

The "single", "double" and "round" border styles aren't offered when
they cannot be used: 'encoding' must be "utf-8" and 'ambiwidth' must be
"single" to use them.

"custom:" is now offered instead of "custom".

For 'pumopt', previously sub-option names were incorrectly offered as
the only possible completions for a sub-option value.

No completions are offered for the values of 'pumopt' sub-options that
take a number. Offering all of the integers from 0 to 100 for "opacity:"
wouldn't be useful.

related: #20676
closes: #20910

Signed-off-by: Shane Harper <sh...@shaneharper.net>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/optionstr.c b/src/optionstr.c
index 59a5a7e1d..9a275ef85 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -1131,10 +1131,8 @@ did_set_ambiwidth(optset_T *args UNUSED)
return check_chars_options();
}

-#if defined(FEAT_TABPANEL) || defined(FEAT_DIFF) || defined(FEAT_PROP_POPUP)
-
// "name" must be a string literal, the length is computed at compile time.
-# define completing_value_for_subopt(args, name) \
+#define completing_value_for_subopt(args, name) \
completing_value_for_subopt_len(args, name, (int)STRLEN_LITERAL(name))

/*
@@ -1155,7 +1153,6 @@ completing_value_for_subopt_len(optexpand_T *args, char *name, int len)

return STRNCMP(colon - len, name, len) == 0;
}
-#endif

int
expand_set_ambiwidth(optexpand_T *args, int *numMatches, char_u ***matches)
@@ -3921,9 +3918,29 @@ error:
return e_invalid_argument;
}

+ static char_u *
+get_pum_border_style(expand_T *xp UNUSED, int idx)
+{
+ static char *styles[] = {"ascii", "custom:", "single", "double", "round"};
+ return idx < ((enc_utf8 && *p_ambw == 's') ? (int)ARRAY_LENGTH(styles) : 2)
+ ? (char_u *)styles[idx] : NULL;
+}
+
int
expand_set_pumopt(optexpand_T *args, int *numMatches, char_u ***matches)
{
+ expand_T *xp = args->oe_xp;
+
+ if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':')
+ {
+ if (completing_value_for_subopt(args, "border"))
+ {
+ return expand_set_opt_generic(
+ args, get_pum_border_style, numMatches, matches);
+ }
+ return FAIL;
+ }
+
static char *(p_pumopt_values[]) = {"border:", "height:", "width:",
"maxwidth:", "opacity:", "shadow", "margin", NULL};
return expand_set_opt_string(
@@ -3996,17 +4013,19 @@ error:
return e_invalid_argument;
}

+ static char_u *
+get_pumborder_token(expand_T *xp, int idx)
+{
+ return idx == 0 ? (char_u *)"margin"
+ : idx == 1 ? (char_u *)"shadow"
+ : get_pum_border_style(xp, idx - 2);
+}
+
int
expand_set_pumborder(optexpand_T *args, int *numMatches, char_u ***matches)
{
- static char *(p_pb_values[]) = {"single", "double", "round", "ascii",
- "custom", "shadow", "margin", NULL};
- return expand_set_opt_string(
- args,
- p_pb_values,
- ARRAY_LENGTH(p_pb_values) - 1,
- numMatches,
- matches);
+ return expand_set_opt_generic(
+ args, get_pumborder_token, numMatches, matches);
}

#if defined(FEAT_STL_OPT)
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 93d0e6144..4754ce32c 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -820,6 +820,32 @@ func Test_set_completion_string_values()
set ww&
endfunc

+func Test_set_pumopt_and_pumborder_completion()
+ let Chk = {cmd, completions ->
+ \ assert_equal(sort(completions),
+ \ sort(getcompletion(cmd, 'cmdline')))}
+
+ " opacity can be any integer from 0 to 100; no completions are offered.
+ call Chk('set pumopt=opacity:', [])
+
+ set encoding=utf-8 ambiwidth=single
+ call Chk('set pumborder=',
+ \ ['ascii', 'custom:', 'double', 'margin', 'round', 'shadow', 'single'])
+ call Chk('set pumborder=s', ['shadow', 'single'])
+ call Chk('set pumopt=shadow,border:',
+ \ ['ascii', 'custom:', 'double', 'round', 'single'])
+
+ for [&encoding, &ambiwidth] in
+ \ [['utf-8', 'double'], ['latin1', 'single'], ['latin1', 'double']]
+ call Chk('set pumborder=', ['ascii', 'custom:', 'margin', 'shadow'])
+ call Chk('set pumborder=s', ['shadow'])
+ call Chk('set pumopt=shadow,border:', ['ascii', 'custom:'])
+ endfor
+
+ set encoding&
+ set ambiwidth&
+endfunc
+
func Test_set_option_errors()
call assert_fails('set scroll=-1', 'E49:')
call assert_fails('set backupcopy=', 'E474:')
diff --git a/src/version.c b/src/version.c
index ccd80f56b..e0bd6e1e0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 929,
/**/
928,
/**/
Reply all
Reply to author
Forward
0 new messages