summaryrefslogtreecommitdiffstats
path: root/src/optionstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/optionstr.c')
-rw-r--r--src/optionstr.c1118
1 files changed, 1117 insertions, 1 deletions
diff --git a/src/optionstr.c b/src/optionstr.c
index 9b4464d85c..010bec769f 100644
--- a/src/optionstr.c
+++ b/src/optionstr.c
@@ -24,8 +24,21 @@ static char *(p_bo_values[]) = {"all", "backspace", "cursor", "complete",
"hangul", "insertmode", "lang", "mess",
"showmatch", "operator", "register", "shell",
"spell", "term", "wildmode", NULL};
+#if defined(FEAT_LINEBREAK)
+// Note: Keep this in sync with briopt_check()
+static char *(p_briopt_values[]) = {"shift:", "min:", "sbr", "list:", "column:", NULL};
+#endif
+#if defined(FEAT_DIFF)
+// Note: Keep this in sync with diffopt_changed()
+static char *(p_dip_values[]) = {"filler", "context:", "iblank", "icase", "iwhite", "iwhiteall", "iwhiteeol", "horizontal", "vertical", "closeoff", "hiddenoff", "foldcolumn:", "followwrap", "internal", "indent-heuristic", "algorithm:", NULL};
+static char *(p_dip_algorithm_values[]) = {"myers", "minimal", "patience", "histogram", NULL};
+#endif
static char *(p_nf_values[]) = {"bin", "octal", "hex", "alpha", "unsigned", NULL};
static char *(p_ff_values[]) = {FF_UNIX, FF_DOS, FF_MAC, NULL};
+#ifdef FEAT_CLIPBOARD
+// Note: Keep this in sync with did_set_clipboard()
+static char *(p_cb_values[]) = {"unnamed", "unnamedplus", "autoselect", "autoselectplus", "autoselectml", "html", "exclude:", NULL};
+#endif
#ifdef FEAT_CRYPT
static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2",
# ifdef FEAT_SODIUM
@@ -34,6 +47,10 @@ static char *(p_cm_values[]) = {"zip", "blowfish", "blowfish2",
NULL};
#endif
static char *(p_cmp_values[]) = {"internal", "keepascii", NULL};
+#ifdef FEAT_SYN_HL
+// Note: Keep this in sync with fill_culopt_flags()
+static char *(p_culopt_values[]) = {"line", "screenline", "number", "both", NULL};
+#endif
static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL};
static char *(p_jop_values[]) = {"stack", NULL};
#ifdef FEAT_FOLDING
@@ -41,6 +58,18 @@ static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent",
"quickfix", "search", "tag", "insert",
"undo", "jump", NULL};
#endif
+// Note: Keep this in sync with match_keyprotocol()
+static char *(p_kpc_protocol_values[]) = {"none", "mok2", "kitty", NULL};
+#ifdef FEAT_PROP_POPUP
+// Note: Keep this in sync with parse_popup_option()
+static char *(p_popup_option_values[]) = {"height:", "width:", "highlight:", "border:", "align:", NULL};
+static char *(p_popup_option_border_values[]) = {"on", "off", NULL};
+static char *(p_popup_option_align_values[]) = {"item", "menu", NULL};
+#endif
+#if defined(FEAT_SPELL)
+// Note: Keep this in sync with spell_check_sps()
+static char *(p_sps_values[]) = {"best", "fast", "double", "expr:", "file:", "timeout:", NULL};
+#endif
#ifdef FEAT_SESSION
// Also used for 'viewoptions'! Keep in sync with SSOP_ flags.
static char *(p_ssop_values[]) = {"buffers", "winpos", "resize", "winsize",
@@ -62,6 +91,8 @@ static char *(p_tbis_values[]) = {"tiny", "small", "medium", "large", "huge", "g
static char *(p_ttym_values[]) = {"xterm", "xterm2", "dec", "netterm", "jsbterm", "pterm", "urxvt", "sgr", NULL};
#endif
static char *(p_ve_values[]) = {"block", "insert", "all", "onemore", "none", "NONE", NULL};
+// Note: Keep this in sync with check_opt_wim()
+static char *(p_wim_values[]) = {"full", "longest", "list", "lastused", NULL};
static char *(p_wop_values[]) = {"fuzzy", "tagfile", "pum", NULL};
#ifdef FEAT_WAK
static char *(p_wak_values[]) = {"yes", "menu", "no", NULL};
@@ -700,6 +731,198 @@ did_set_option_listflag(char_u *val, char_u *flags, char *errbuf)
}
/*
+ * Expand an option that accepts a list of string values.
+ */
+ int
+expand_set_opt_string(
+ optexpand_T *args,
+ char **values,
+ int numValues,
+ int *numMatches,
+ char_u ***matches)
+{
+ char_u *p;
+ regmatch_T *regmatch = args->oe_regmatch;
+ int include_orig_val = args->oe_include_orig_val;
+ char_u *option_val = args->oe_opt_value;
+
+ // Assume numValues is small since they are fixed enums, so just allocate
+ // upfront instead of needing two passes to calculate output size.
+ *matches = ALLOC_MULT(char_u *, numValues + 1);
+ if (*matches == NULL)
+ return FAIL;
+
+ int count = 0;
+
+ if (include_orig_val && *option_val != NUL)
+ {
+ p = vim_strsave(option_val);
+ if (p == NULL)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ (*matches)[count++] = p;
+ }
+
+ for (char **val = values; *val != NULL; val++)
+ {
+ if (include_orig_val && *option_val != NUL)
+ {
+ if (STRCMP((char_u*)*val, option_val) == 0)
+ continue;
+ }
+ if (vim_regexec(regmatch, (char_u*)(*val), (colnr_T)0))
+ {
+ p = vim_strsave((char_u*)*val);
+ if (p == NULL)
+ {
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ else
+ break;
+ }
+ (*matches)[count++] = p;
+ }
+ }
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+ return OK;
+}
+
+static char_u *set_opt_callback_orig_option = NULL;
+static char_u *((*set_opt_callback_func)(expand_T *, int));
+
+/*
+ * Callback used by expand_set_opt_generic to also include the original value.
+ */
+ static char_u *
+expand_set_opt_callback(expand_T *xp, int idx)
+{
+ if (idx == 0)
+ {
+ if (set_opt_callback_orig_option != NULL)
+ return set_opt_callback_orig_option;
+ else
+ return (char_u *)""; // empty strings are ignored
+ }
+ return set_opt_callback_func(xp, idx - 1);
+}
+
+/*
+ * Expand an option with a callback that iterates through a list of possible names.
+ */
+ int
+expand_set_opt_generic(
+ optexpand_T *args,
+ char_u *((*func)(expand_T *, int)),
+ int *numMatches,
+ char_u ***matches)
+{
+ int ret;
+
+ set_opt_callback_orig_option = args->oe_include_orig_val ?
+ args->oe_opt_value : NULL;
+ set_opt_callback_func = func;
+
+ ret = ExpandGeneric(
+ (char_u*)"", // not using fuzzy as currently EXPAND_STRING_SETTING doesn't use it
+ args->oe_xp,
+ args->oe_regmatch,
+ matches,
+ numMatches,
+ expand_set_opt_callback,
+ FALSE);
+
+ set_opt_callback_orig_option = NULL;
+ set_opt_callback_func = NULL;
+ return ret;
+}
+
+
+/*
+ * Expand an option which is a list of flags.
+ */
+ int
+expand_set_opt_listflag(
+ optexpand_T *args,
+ char_u *flags,
+ int *numMatches,
+ char_u ***matches)
+{
+ char_u *p;
+ char_u *option_val = args->oe_opt_value;
+ char_u *cmdline_val = args->oe_set_arg;
+ int append = args->oe_append;
+ int include_orig_val = args->oe_include_orig_val && (*option_val != NUL);
+
+ int num_flags = STRLEN(flags);
+
+ // Assume we only have small number of flags, so just allocate max size.
+ *matches = ALLOC_MULT(char_u *, num_flags + 1);
+ if (*matches == NULL)
+ return FAIL;
+
+ int count = 0;
+
+ if (include_orig_val)
+ {
+ p = vim_strsave(option_val);
+ if (p == NULL)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ (*matches)[count++] = p;
+ }
+
+ for (char_u *flag = flags; *flag != NUL; flag++)
+ {
+ if (append && vim_strchr(option_val, *flag) != NULL)
+ continue;
+
+ if (vim_strchr(cmdline_val, *flag) == NULL)
+ {
+ if (include_orig_val
+ && option_val[1] == NUL
+ && *flag == option_val[0])
+ {
+ // This value is already used as the first choice as it's the
+ // existing flag. Just skip it to avoid duplicate.
+ continue;
+ }
+ p = vim_strnsave(flag, 1);
+ if (p == NULL)
+ {
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ else
+ break;
+ }
+ (*matches)[count++] = p;
+ }
+ }
+
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+ return OK;
+}
+
+/*
* The 'ambiwidth' option is changed.
*/
char *
@@ -711,6 +934,17 @@ did_set_ambiwidth(optset_T *args UNUSED)
return check_chars_options();
}
+ int
+expand_set_ambiwidth(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_ambw_values,
+ sizeof(p_ambw_values) / sizeof(p_ambw_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'background' option is changed.
*/
@@ -747,6 +981,17 @@ did_set_background(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_background(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bg_values,
+ sizeof(p_bg_values) / sizeof(p_bg_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'backspace' option is changed.
*/
@@ -764,6 +1009,17 @@ did_set_backspace(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_backspace(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bs_values,
+ sizeof(p_bs_values) / sizeof(p_bs_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'backupcopy' option is changed.
*/
@@ -801,6 +1057,17 @@ did_set_backupcopy(optset_T *args)
return errmsg;
}
+ int
+expand_set_backupcopy(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bkc_values,
+ sizeof(p_bkc_values) / sizeof(p_bkc_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'backupext' or the 'patchmode' option is changed.
*/
@@ -823,6 +1090,17 @@ did_set_belloff(optset_T *args UNUSED)
return did_set_opt_flags(p_bo, p_bo_values, &bo_flags, TRUE);
}
+ int
+expand_set_belloff(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bo_values,
+ sizeof(p_bo_values) / sizeof(p_bo_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_LINEBREAK) || defined(PROTO)
/*
* The 'breakindentopt' option is changed.
@@ -840,6 +1118,17 @@ did_set_breakindentopt(optset_T *args UNUSED)
return errmsg;
}
+
+ int
+expand_set_breakindentopt(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_briopt_values,
+ sizeof(p_briopt_values) / sizeof(p_briopt_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if defined(FEAT_BROWSE) || defined(PROTO)
@@ -855,6 +1144,17 @@ did_set_browsedir(optset_T *args UNUSED)
return NULL;
}
+
+ int
+expand_set_browsedir(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bsdir_values,
+ sizeof(p_bsdir_values) / sizeof(p_bsdir_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
/*
@@ -866,6 +1166,17 @@ did_set_bufhidden(optset_T *args UNUSED)
return did_set_opt_strings(curbuf->b_p_bh, p_bufhidden_values, FALSE);
}
+ int
+expand_set_bufhidden(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_bufhidden_values,
+ sizeof(p_bufhidden_values) / sizeof(p_bufhidden_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'buftype' option is changed.
*/
@@ -886,6 +1197,17 @@ did_set_buftype(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_buftype(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_buftype_values,
+ sizeof(p_buftype_values) / sizeof(p_buftype_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'casemap' option is changed.
*/
@@ -895,6 +1217,30 @@ did_set_casemap(optset_T *args UNUSED)
return did_set_opt_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
}
+ int
+expand_set_casemap(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_cmp_values,
+ sizeof(p_cmp_values) / sizeof(p_cmp_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
+#if defined(FEAT_CLIPBOARD) || defined(PROTO)
+ int
+expand_set_clipboard(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_cb_values,
+ sizeof(p_cb_values) / sizeof(p_cb_values[0]) - 1,
+ numMatches,
+ matches);
+}
+#endif
+
/*
* The global 'listchars' or 'fillchars' option is changed.
*/
@@ -967,6 +1313,21 @@ did_set_chars_option(optset_T *args)
}
/*
+ * Expand 'fillchars' or 'listchars' option value.
+ */
+ int
+expand_set_chars_option(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ char_u **varp = (char_u **)args->oe_varp;
+ int is_lcs = (varp == &p_lcs || varp == &curwin->w_p_lcs);
+ return expand_set_opt_generic(
+ args,
+ is_lcs ? get_listchars_name : get_fillchars_name,
+ numMatches,
+ matches);
+}
+
+/*
* The 'cinoptions' option is changed.
*/
char *
@@ -1091,6 +1452,20 @@ did_set_complete(optset_T *args)
return NULL;
}
+ int
+expand_set_complete(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ static char *(p_cpt_values[]) = {
+ ".", "w", "b", "u", "k", "kspell", "s", "i", "d", "]", "t", "U",
+ NULL};
+ return expand_set_opt_string(
+ args,
+ p_cpt_values,
+ sizeof(p_cpt_values) / sizeof(p_cpt_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'completeopt' option is changed.
*/
@@ -1104,6 +1479,17 @@ did_set_completeopt(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_completeopt(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_cot_values,
+ sizeof(p_cot_values) / sizeof(p_cot_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if (defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)) || defined(PROTO)
/*
* The 'completepopup' option is changed.
@@ -1132,6 +1518,17 @@ did_set_completeslash(optset_T *args UNUSED)
return NULL;
}
+
+ int
+expand_set_completeslash(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_csl_values,
+ sizeof(p_csl_values) / sizeof(p_csl_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if defined(FEAT_CONCEAL) || defined(PROTO)
@@ -1145,6 +1542,12 @@ did_set_concealcursor(optset_T *args)
return did_set_option_listflag(*varp, (char_u *)COCU_ALL, args->os_errbuf);
}
+
+ int
+expand_set_concealcursor(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_listflag(args, (char_u*)COCU_ALL, numMatches, matches);
+}
#endif
/*
@@ -1158,6 +1561,12 @@ did_set_cpoptions(optset_T *args)
return did_set_option_listflag(*varp, (char_u *)CPO_ALL, args->os_errbuf);
}
+ int
+expand_set_cpoptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_listflag(args, (char_u*)CPO_ALL, numMatches, matches);
+}
+
#if defined(FEAT_CRYPT) || defined(PROTO)
/*
* The 'cryptkey' option is changed.
@@ -1244,6 +1653,17 @@ did_set_cryptmethod(optset_T *args)
}
return NULL;
}
+
+ int
+expand_set_cryptmethod(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_cm_values,
+ sizeof(p_cm_values) / sizeof(p_cm_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if (defined(FEAT_CSCOPE) && defined(FEAT_QUICKFIX)) || defined(PROTO)
@@ -1285,11 +1705,23 @@ did_set_cursorlineopt(optset_T *args)
{
char_u **varp = (char_u **)args->os_varp;
+ // This could be changed to use opt_strings_flags() instead.
if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK)
return e_invalid_argument;
return NULL;
}
+
+ int
+expand_set_cursorlineopt(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_culopt_values,
+ sizeof(p_culopt_values) / sizeof(p_culopt_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
/*
@@ -1301,6 +1733,17 @@ did_set_debug(optset_T *args UNUSED)
return did_set_opt_strings(p_debug, p_debug_values, TRUE);
}
+ int
+expand_set_debug(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_debug_values,
+ sizeof(p_debug_values) / sizeof(p_debug_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_DIFF) || defined(PROTO)
/*
* The 'diffopt' option is changed.
@@ -1313,6 +1756,36 @@ did_set_diffopt(optset_T *args UNUSED)
return NULL;
}
+
+ int
+expand_set_diffopt(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) == ':')
+ {
+ // Within "algorithm:", we have a subgroup of possible options.
+ int algo_len = STRLEN("algorithm:");
+ if (xp->xp_pattern - args->oe_set_arg >= algo_len &&
+ STRNCMP(xp->xp_pattern - algo_len, "algorithm:", algo_len) == 0)
+ {
+ return expand_set_opt_string(
+ args,
+ p_dip_algorithm_values,
+ sizeof(p_dip_algorithm_values) / sizeof(p_dip_algorithm_values[0]) - 1,
+ numMatches,
+ matches);
+ }
+ return FAIL;
+ }
+
+ return expand_set_opt_string(
+ args,
+ p_dip_values,
+ sizeof(p_dip_values) / sizeof(p_dip_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
/*
@@ -1328,6 +1801,17 @@ did_set_display(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_display(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_dy_values,
+ sizeof(p_dy_values) / sizeof(p_dy_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'eadirection' option is changed.
*/
@@ -1337,6 +1821,17 @@ did_set_eadirection(optset_T *args UNUSED)
return did_set_opt_strings(p_ead, p_ead_values, FALSE);
}
+ int
+expand_set_eadirection(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_ead_values,
+ sizeof(p_ead_values) / sizeof(p_ead_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* One of the 'encoding', 'fileencoding', 'termencoding' or 'makeencoding'
* options is changed.
@@ -1430,6 +1925,16 @@ did_set_encoding(optset_T *args)
return errmsg;
}
+ int
+expand_set_encoding(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_generic(
+ args,
+ get_encoding_name,
+ numMatches,
+ matches);
+}
+
/*
* The 'eventignore' option is changed.
*/
@@ -1441,6 +1946,26 @@ did_set_eventignore(optset_T *args UNUSED)
return NULL;
}
+ static char_u *
+get_eventignore_name(expand_T *xp, int idx)
+{
+ // 'eventignore' allows special keyword "all" in addition to
+ // all event names.
+ if (idx == 0)
+ return (char_u *)"all";
+ return get_event_name_no_group(xp, idx - 1);
+}
+
+ int
+expand_set_eventignore(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_generic(
+ args,
+ get_eventignore_name,
+ numMatches,
+ matches);
+}
+
/*
* The 'fileformat' option is changed.
*/
@@ -1470,6 +1995,17 @@ did_set_fileformat(optset_T *args)
return NULL;
}
+ int
+expand_set_fileformat(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_ff_values,
+ sizeof(p_ff_values) / sizeof(p_ff_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'fileformats' option is changed.
*/
@@ -1517,6 +2053,17 @@ did_set_foldclose(optset_T *args UNUSED)
{
return did_set_opt_strings(p_fcl, p_fcl_values, TRUE);
}
+
+ int
+expand_set_foldclose(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_fcl_values,
+ sizeof(p_fcl_values) / sizeof(p_fcl_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if (defined(FEAT_EVAL) && defined(FEAT_FOLDING)) || defined(PROTO)
@@ -1583,6 +2130,17 @@ did_set_foldmethod(optset_T *args)
return NULL;
}
+ int
+expand_set_foldmethod(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_fdm_values,
+ sizeof(p_fdm_values) / sizeof(p_fdm_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'foldopen' option is changed.
*/
@@ -1591,6 +2149,17 @@ did_set_foldopen(optset_T *args UNUSED)
{
return did_set_opt_flags(p_fdo, p_fdo_values, &fdo_flags, TRUE);
}
+
+ int
+expand_set_foldopen(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_fdo_values,
+ sizeof(p_fdo_values) / sizeof(p_fdo_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
/*
@@ -1604,6 +2173,12 @@ did_set_formatoptions(optset_T *args)
return did_set_option_listflag(*varp, (char_u *)FO_ALL, args->os_errbuf);
}
+ int
+expand_set_formatoptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_listflag(args, (char_u*)FO_ALL, numMatches, matches);
+}
+
#if defined(CURSOR_SHAPE) || defined(PROTO)
/*
* The 'guicursor' option is changed.
@@ -1722,6 +2297,12 @@ did_set_guioptions(optset_T *args)
gui_init_which_components(args->os_oldval.string);
return NULL;
}
+
+ int
+expand_set_guioptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_listflag(args, (char_u*)GO_ALL, numMatches, matches);
+}
#endif
#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
@@ -1788,6 +2369,125 @@ did_set_highlight(optset_T *args UNUSED)
}
/*
+ * Expand 'highlight' option.
+ */
+ int
+expand_set_highlight(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ char_u *p;
+ expand_T *xp = args->oe_xp;
+ static char_u hl_flags[HLF_COUNT] = HL_FLAGS;
+ int i;
+ int count = 0;
+
+ if (xp->xp_pattern > args->oe_set_arg && *(xp->xp_pattern-1) == ':')
+ {
+ // Right after a ':', meaning we just return all highlight names.
+ return expand_set_opt_generic(
+ args,
+ get_highlight_name,
+ numMatches,
+ matches);
+ }
+
+ if (*xp->xp_pattern == NUL)
+ {
+ // At beginning of a comma-separated list. Return the specific list of
+ // supported occasions.
+ *matches = ALLOC_MULT(char_u *, HLF_COUNT + 1);
+ if (*matches == NULL)
+ return FAIL;
+
+ // We still want to return the full option if it's requested.
+ if (args->oe_include_orig_val)
+ {
+ p = vim_strsave(args->oe_opt_value);
+ if (p == NULL)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ (*matches)[count++] = p;
+ }
+
+ for (i = 0; i < HLF_COUNT; i++)
+ {
+ p = vim_strnsave(&hl_flags[i], 1);
+ if (p == NULL)
+ {
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ else
+ break;
+ }
+ (*matches)[count++] = p;
+ }
+
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+ return OK;
+ }
+
+ // We are after the initial character (which indicates the occasion). We
+ // already made sure we are not matching after a ':' above, so now we want
+ // to match against display mode modifiers.
+ // Since the xp_pattern starts from the beginning, we need to include it in
+ // the returned match.
+
+ // Note: Keep this in sync with highlight_changed()
+ static char p_hl_mode_values[] =
+ {':', 'b', 'i', '-', 'n', 'r', 's', 'u', 'c', '2', 'd', '=', 't'};
+ int num_hl_modes = sizeof(p_hl_mode_values) / sizeof(p_hl_mode_values[0]);
+
+ *matches = ALLOC_MULT(char_u *, num_hl_modes);
+ if (*matches == NULL)
+ return FAIL;
+
+ int pattern_len = STRLEN(xp->xp_pattern);
+
+ for (i = 0; i < num_hl_modes; i++)
+ {
+ // Don't allow duplicates as these are unique flags
+ if (vim_strchr(xp->xp_pattern + 1, p_hl_mode_values[i]) != NULL)
+ continue;
+
+ // ':' only works by itself, not with other flags.
+ if (pattern_len > 1 && p_hl_mode_values[i] == ':')
+ continue;
+
+ p = vim_strnsave(xp->xp_pattern, pattern_len + 1);
+ if (p == NULL)
+ {
+ if (i == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ else
+ break;
+ }
+ p[pattern_len] = p_hl_mode_values[i];
+ p[pattern_len + 1] = NUL;
+ (*matches)[count++] = p;
+ }
+ if (count == 0)
+ {
+ VIM_CLEAR(*matches);
+ return FAIL;
+ }
+ *numMatches = count;
+
+ return OK;
+}
+
+/*
* The 'titlestring' or the 'iconstring' option is changed.
*/
static char *
@@ -1866,6 +2566,17 @@ did_set_jumpoptions(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_jumpoptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_jop_values,
+ sizeof(p_jop_values) / sizeof(p_jop_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_KEYMAP) || defined(PROTO)
/*
* The 'keymap' option is changed.
@@ -1939,6 +2650,17 @@ did_set_keymodel(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_keymodel(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_km_values,
+ sizeof(p_km_values) / sizeof(p_km_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'keyprotocol' option is changed.
*/
@@ -1955,6 +2677,27 @@ did_set_keyprotocol(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_keyprotocol(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) == ':')
+ {
+ // 'keyprotocol' only has well-defined terms for completion for the
+ // protocol part after the colon.
+ return expand_set_opt_string(
+ args,
+ p_kpc_protocol_values,
+ sizeof(p_kpc_protocol_values) / sizeof(p_kpc_protocol_values[0]) - 1,
+ numMatches,
+ matches);
+ }
+ // Use expand_set_opt_string instead of returning FAIL so that we can
+ // include the original value if args->oe_include_orig_val is set.
+ static char *(empty[]) = {NULL};
+ return expand_set_opt_string(args, empty, 0, numMatches, matches);
+}
+
/*
* The 'lispoptions' option is changed.
*/
@@ -1971,6 +2714,18 @@ did_set_lispoptions(optset_T *args)
return NULL;
}
+ int
+expand_set_lispoptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ static char *(p_lop_values[]) = {"expr:0", "expr:1", NULL};
+ return expand_set_opt_string(
+ args,
+ p_lop_values,
+ sizeof(p_lop_values) / sizeof(p_lop_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'matchpairs' option is changed.
*/
@@ -2042,6 +2797,12 @@ did_set_mouse(optset_T *args)
args->os_errbuf);
}
+ int
+expand_set_mouse(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_listflag(args, (char_u*)MOUSE_ALL, numMatches, matches);
+}
+
/*
* The 'mousemodel' option is changed.
*/
@@ -2060,6 +2821,17 @@ did_set_mousemodel(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_mousemodel(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_mousem_values,
+ sizeof(p_mousem_values) / sizeof(p_mousem_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_MOUSESHAPE) || defined(PROTO)
char *
did_set_mouseshape(optset_T *args UNUSED)
@@ -2084,6 +2856,17 @@ did_set_nrformats(optset_T *args)
return did_set_opt_strings(*varp, p_nf_values, TRUE);
}
+ int
+expand_set_nrformats(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_nf_values,
+ sizeof(p_nf_values) / sizeof(p_nf_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_EVAL) || defined(PROTO)
/*
* One of the '*expr' options is changed: 'balloonexpr', 'diffexpr',
@@ -2144,6 +2927,58 @@ did_set_previewpopup(optset_T *args UNUSED)
return NULL;
}
+
+ int
+expand_set_popupoption(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) == ':')
+ {
+ // Within "highlight:"/"border:"/"align:", we have a subgroup of possible options.
+ int border_len = STRLEN("border:");
+ if (xp->xp_pattern - args->oe_set_arg >= border_len &&
+ STRNCMP(xp->xp_pattern - border_len, "border:", border_len) == 0)
+ {
+ return expand_set_opt_string(
+ args,
+ p_popup_option_border_values,
+ sizeof(p_popup_option_border_values) / sizeof(p_popup_option_border_values[0]) - 1,
+ numMatches,
+ matches);
+ }
+ int align_len = STRLEN("align:");
+ if (xp->xp_pattern - args->oe_set_arg >= align_len &&
+ STRNCMP(xp->xp_pattern - align_len, "align:", align_len) == 0)
+ {
+ return expand_set_opt_string(
+ args,
+ p_popup_option_align_values,
+ sizeof(p_popup_option_align_values) / sizeof(p_popup_option_align_values[0]) - 1,
+ numMatches,
+ matches);
+ }
+ int highlight_len = STRLEN("highlight:");
+ if (xp->xp_pattern - args->oe_set_arg >= highlight_len &&
+ STRNCMP(xp->xp_pattern - highlight_len, "highlight:", highlight_len) == 0)
+ {
+ // Return the list of all highlight names
+ return expand_set_opt_generic(
+ args,
+ get_highlight_name,
+ numMatches,
+ matches);
+ }
+ return FAIL;
+ }
+
+ return expand_set_opt_string(
+ args,
+ p_popup_option_values,
+ sizeof(p_popup_option_values) / sizeof(p_popup_option_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if defined(FEAT_POSTSCRIPT) || defined(PROTO)
@@ -2178,6 +3013,30 @@ did_set_printencoding(optset_T *args UNUSED)
}
#endif
+#if defined(FEAT_PRINTER) || defined(PROTO)
+
+ static char_u *
+get_printoptions_names(expand_T *xp UNUSED, int idx)
+{
+ if (idx >= (int)(sizeof(printer_opts) / sizeof(printer_opts[0])))
+ return NULL;
+ return (char_u*)printer_opts[idx].name;
+}
+
+/*
+ * Expand 'printoptions' option
+ */
+ int
+expand_set_printoptions(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_generic(
+ args,
+ get_printoptions_names,
+ numMatches,
+ matches);
+}
+#endif
+
#if defined(FEAT_STL_OPT) || defined(PROTO)
/*
* The 'statusline' or the 'tabline' or the 'rulerformat' option is changed.
@@ -2244,6 +3103,18 @@ did_set_rightleftcmd(optset_T *args)
return NULL;
}
+
+ int
+expand_set_rightleftcmd(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ static char *(p_rlc_values[]) = {"search", NULL};
+ return expand_set_opt_string(
+ args,
+ p_rlc_values,
+ sizeof(p_rlc_values) / sizeof(p_rlc_values[0]) - 1,
+ numMatches,
+ matches);
+}
#endif
#if defined(FEAT_STL_OPT) || defined(PROTO)
@@ -2266,6 +3137,17 @@ did_set_scrollopt(optset_T *args UNUSED)
return did_set_opt_strings(p_sbo, p_scbopt_values, TRUE);
}
+ int
+expand_set_scrollopt(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_scbopt_values,
+ sizeof(p_scbopt_values) / sizeof(p_scbopt_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'selection' option is changed.
*/
@@ -2278,6 +3160,17 @@ did_set_selection(optset_T *args UNUSED)
return NULL;
}
+ int
+expand_set_selection(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_sel_values,
+ sizeof(p_sel_values) / sizeof(p_sel_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
/*
* The 'selectmode' option is changed.
*/
@@ -2287,6 +3180,17 @@ did_set_selectmode(optset_T *args UNUSED)
return did_set_opt_strings(p_slm, p_slm_values, TRUE);
}
+ int
+expand_set_selectmode(optexpand_T *args, int *numMatches, char_u ***matches)
+{
+ return expand_set_opt_string(
+ args,
+ p_slm_values,
+ sizeof(p_slm_values) / sizeof(p_slm_values[0]) - 1,
+ numMatches,
+ matches);
+}
+
#if defined(FEAT_SESSION) || defined(PROTO)
/*