diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/autocmd.c | 10 | ||||
-rw-r--r-- | src/clipboard.c | 1 | ||||
-rw-r--r-- | src/cmdexpand.c | 12 | ||||
-rw-r--r-- | src/diff.c | 2 | ||||
-rw-r--r-- | src/ex_getln.c | 1 | ||||
-rw-r--r-- | src/highlight.c | 1 | ||||
-rw-r--r-- | src/indent.c | 1 | ||||
-rw-r--r-- | src/mbyte.c | 13 | ||||
-rw-r--r-- | src/option.c | 375 | ||||
-rw-r--r-- | src/option.h | 3 | ||||
-rw-r--r-- | src/optiondefs.h | 1239 | ||||
-rw-r--r-- | src/optionstr.c | 1118 | ||||
-rw-r--r-- | src/popupwin.c | 3 | ||||
-rw-r--r-- | src/proto/autocmd.pro | 1 | ||||
-rw-r--r-- | src/proto/cmdexpand.pro | 1 | ||||
-rw-r--r-- | src/proto/mbyte.pro | 1 | ||||
-rw-r--r-- | src/proto/option.pro | 2 | ||||
-rw-r--r-- | src/proto/optionstr.pro | 65 | ||||
-rw-r--r-- | src/proto/screen.pro | 2 | ||||
-rw-r--r-- | src/screen.c | 101 | ||||
-rw-r--r-- | src/spellsuggest.c | 1 | ||||
-rw-r--r-- | src/structs.h | 28 | ||||
-rw-r--r-- | src/term.c | 1 | ||||
-rw-r--r-- | src/testdir/test_options.vim | 290 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 16 |
26 files changed, 2566 insertions, 724 deletions
diff --git a/src/autocmd.c b/src/autocmd.c index c09e12f404..a78e78b024 100644 --- a/src/autocmd.c +++ b/src/autocmd.c @@ -2737,6 +2737,16 @@ get_event_name(expand_T *xp UNUSED, int idx) return (char_u *)event_names[idx - augroups.ga_len].name; } +/* + * Function given to ExpandGeneric() to obtain the list of event names. Don't + * include groups. + */ + char_u * +get_event_name_no_group(expand_T *xp UNUSED, int idx) +{ + return (char_u *)event_names[idx].name; +} + #if defined(FEAT_EVAL) || defined(PROTO) /* diff --git a/src/clipboard.c b/src/clipboard.c index 4ce536ac47..d80699b059 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -1266,6 +1266,7 @@ did_set_clipboard(optset_T *args UNUSED) for (p = p_cb; *p != NUL; ) { + // Note: Keep this in sync with p_cb_values. if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL)) { new_unnamed |= CLIP_UNNAMED; diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 40778cc219..b59610c02e 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -15,9 +15,6 @@ static int cmd_showtail; // Only show path tail in lists ? -static int ExpandGeneric(char_u *pat, expand_T *xp, regmatch_T *regmatch, - char_u ***matches, int *numMatches, - char_u *((*func)(expand_T *, int)), int escaped); static int ExpandFromContext(expand_T *xp, char_u *, char_u ***, int *, int); static char_u *showmatches_gettail(char_u *s); static int expand_showtail(expand_T *xp); @@ -54,6 +51,8 @@ cmdline_fuzzy_completion_supported(expand_T *xp) && xp->xp_context != EXPAND_FILETYPE && xp->xp_context != EXPAND_HELP && xp->xp_context != EXPAND_OLD_SETTING + && xp->xp_context != EXPAND_STRING_SETTING + && xp->xp_context != EXPAND_SETTING_SUBTRACT && xp->xp_context != EXPAND_OWNSYNTAX && xp->xp_context != EXPAND_PACKADD && xp->xp_context != EXPAND_RUNTIME @@ -3093,6 +3092,10 @@ ExpandFromContext( if (xp->xp_context == EXPAND_SETTINGS || xp->xp_context == EXPAND_BOOL_SETTINGS) ret = ExpandSettings(xp, ®match, pat, numMatches, matches, fuzzy); + else if (xp->xp_context == EXPAND_STRING_SETTING) + ret = ExpandStringSetting(xp, ®match, numMatches, matches); + else if (xp->xp_context == EXPAND_SETTING_SUBTRACT) + ret = ExpandSettingSubtract(xp, ®match, numMatches, matches); else if (xp->xp_context == EXPAND_MAPPINGS) ret = ExpandMappings(pat, ®match, numMatches, matches); #if defined(FEAT_EVAL) @@ -3121,7 +3124,7 @@ ExpandFromContext( * * Returns OK when no problems encountered, FAIL for error (out of memory). */ - static int + int ExpandGeneric( char_u *pat, expand_T *xp, @@ -3226,6 +3229,7 @@ ExpandGeneric( // applies to the completion context. Menus and scriptnames should be kept // in the specified order. if (!fuzzy && xp->xp_context != EXPAND_MENUNAMES + && xp->xp_context != EXPAND_STRING_SETTING && xp->xp_context != EXPAND_MENUS && xp->xp_context != EXPAND_SCRIPTNAMES) sort_matches = TRUE; diff --git a/src/diff.c b/src/diff.c index 1873767106..158870402b 100644 --- a/src/diff.c +++ b/src/diff.c @@ -2266,6 +2266,7 @@ diffopt_changed(void) p = p_dip; while (*p != NUL) { + // Note: Keep this in sync with p_dip_values if (STRNCMP(p, "filler", 6) == 0) { p += 6; @@ -2343,6 +2344,7 @@ diffopt_changed(void) } else if (STRNCMP(p, "algorithm:", 10) == 0) { + // Note: Keep this in sync with p_dip_algorithm_values. p += 10; if (STRNCMP(p, "myers", 5) == 0) { diff --git a/src/ex_getln.c b/src/ex_getln.c index ad3a3106a7..5baffa77fb 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -2650,6 +2650,7 @@ check_opt_wim(void) for (p = p_wim; *p; ++p) { + // Note: Keep this in sync with p_wim_values. for (i = 0; ASCII_ISALPHA(p[i]); ++i) ; if (p[i] != NUL && p[i] != ',' && p[i] != ':') diff --git a/src/highlight.c b/src/highlight.c index 8b1e832d7b..31c3280e85 100644 --- a/src/highlight.c +++ b/src/highlight.c @@ -3814,6 +3814,7 @@ highlight_changed(void) if (attr > HL_ALL) // Combination with ':' is not allowed. return FAIL; + // Note: Keep this in sync with expand_set_highlight(). switch (*p) { case 'b': attr |= HL_BOLD; diff --git a/src/indent.c b/src/indent.c index 3c38b4ec37..1858ecf8f3 100644 --- a/src/indent.c +++ b/src/indent.c @@ -871,6 +871,7 @@ briopt_check(win_T *wp) p = wp->w_p_briopt; while (*p != NUL) { + // Note: Keep this in sync with p_briopt_values if (STRNCMP(p, "shift:", 6) == 0 && ((p[6] == '-' && VIM_ISDIGIT(p[7])) || VIM_ISDIGIT(p[6]))) { diff --git a/src/mbyte.c b/src/mbyte.c index c4d1ddb3b8..4951f78323 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -5782,3 +5782,16 @@ f_charclass(typval_T *argvars, typval_T *rettv UNUSED) rettv->vval.v_number = mb_get_class(argvars[0].vval.v_string); } #endif + +/* + * Function given to ExpandGeneric() to obtain the possible arguments of the + * encoding options. + */ + char_u * +get_encoding_name(expand_T *xp UNUSED, int idx) +{ + if (idx >= (int)(sizeof(enc_canon_table) / sizeof(enc_canon_table[0]))) + return NULL; + + return (char_u*)enc_canon_table[idx].name; +} diff --git a/src/option.c b/src/option.c index 9f20bb244b..5140c39260 100644 --- a/src/option.c +++ b/src/option.c @@ -1632,7 +1632,7 @@ stropt_copy_value( // For MS-DOS and WIN32 backslashes before normal file name characters // are not removed, and keep backslash at start, for "\\machine\path", // but do remove it for "\\\\machine\\path". - // The reverse is found in ExpandOldSetting(). + // The reverse is found in escape_option_str_cmdline(). while (*arg != NUL && !VIM_ISWHITE(*arg)) { int i; @@ -1837,7 +1837,7 @@ stropt_get_newval( &(options[opt_idx]), OPT_GLOBAL)); else { - ++arg; // jump to after the '=' or ':' + ++arg; // joption_value2stringump to after the '=' or ':' // Set 'keywordprg' to ":help" if an empty // value was passed to :set by the user. @@ -7232,8 +7232,10 @@ set_imsearch_global(void) } static int expand_option_idx = -1; +static int expand_option_start_col = 0; static char_u expand_option_name[5] = {'t', '_', NUL, NUL, NUL}; static int expand_option_flags = 0; +static int expand_option_append = FALSE; void set_context_in_set_cmd( @@ -7348,8 +7350,14 @@ set_context_in_set_cmd( } } // handle "-=" and "+=" + expand_option_append = FALSE; + int expand_option_subtract = FALSE; if ((nextchar == '-' || nextchar == '+' || nextchar == '^') && p[1] == '=') { + if (nextchar == '-') + expand_option_subtract = TRUE; + if (nextchar == '+' || nextchar == '^') + expand_option_append = TRUE; ++p; nextchar = '='; } @@ -7359,22 +7367,20 @@ set_context_in_set_cmd( xp->xp_context = EXPAND_UNSUCCESSFUL; return; } - if (xp->xp_context != EXPAND_BOOL_SETTINGS && p[1] == NUL) - { - xp->xp_context = EXPAND_OLD_SETTING; - if (is_term_option) - expand_option_idx = -1; - else - expand_option_idx = opt_idx; - xp->xp_pattern = p + 1; - return; - } - xp->xp_context = EXPAND_NOTHING; - if (is_term_option || (flags & P_NUM)) - return; + + // Below are for handling expanding a specific option's value after the '=' + // or ':' + + if (is_term_option) + expand_option_idx = -1; + else + expand_option_idx = opt_idx; xp->xp_pattern = p + 1; + expand_option_start_col = (int)(p + 1 - xp->xp_line); + // Certain options currently have special case handling to reuse the + // expansion logic with other commands. #ifdef FEAT_SYN_HL if (options[opt_idx].var == (char_u *)&p_syn) { @@ -7382,7 +7388,38 @@ set_context_in_set_cmd( return; } #endif + if (options[opt_idx].var == (char_u *)&p_ft) + { + xp->xp_context = EXPAND_FILETYPE; + return; + } + // Now pick. If the option has a custom expander, use that. Otherwise, just + // fill with the existing option value. + if (expand_option_subtract) + { + xp->xp_context = EXPAND_SETTING_SUBTRACT; + return; + } + else if (expand_option_idx >= 0 && + options[expand_option_idx].opt_expand_cb != NULL) + { + xp->xp_context = EXPAND_STRING_SETTING; + } + else if (*xp->xp_pattern == NUL) + { + xp->xp_context = EXPAND_OLD_SETTING; + return; + } + else + xp->xp_context = EXPAND_NOTHING; + + if (is_term_option || (flags & P_NUM)) + return; + + // Only string options below + + // Options that have P_EXPAND are considered to all use file/dir expansion. if (flags & P_EXPAND) { p = options[opt_idx].var; @@ -7403,10 +7440,6 @@ set_context_in_set_cmd( else xp->xp_backslash = XP_BS_ONE; } - else if (p == (char_u *)&p_ft) - { - xp->xp_context = EXPAND_FILETYPE; - } else { xp->xp_context = EXPAND_FILES; @@ -7418,34 +7451,55 @@ set_context_in_set_cmd( } } - // For an option that is a list of file names, find the start of the - // last file name. - for (p = arg + STRLEN(arg) - 1; p > xp->xp_pattern; --p) + // For an option that is a list of file names, or comma/colon-separated + // values, split it by the delimiter and find the start of the current + // pattern, while accounting for backslash-escaped space/commas/colons. + // Triple-backslashed escaped file names (e.g. 'path') can also be + // delimited by space. + if ((flags & P_EXPAND) || (flags & P_COMMA) || (flags & P_COLON)) { - // count number of backslashes before ' ' or ',' - if (*p == ' ' || *p == ',') + for (p = arg + STRLEN(arg) - 1; p >= xp->xp_pattern; --p) { - s = p; - while (s > xp->xp_pattern && *(s - 1) == '\\') - --s; - if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3)) - || (*p == ',' && (flags & P_COMMA) && ((p - s) & 1) == 0)) + // count number of backslashes before ' ' or ',' or ':' + if (*p == ' ' || *p == ',' || + (*p == ':' && (flags & P_COLON))) { - xp->xp_pattern = p + 1; - break; + s = p; + while (s > xp->xp_pattern && *(s - 1) == '\\') + --s; + if ((*p == ' ' && (xp->xp_backslash == XP_BS_THREE && (p - s) < 3)) + || (*p == ',' && (flags & P_COMMA) && ((p - s) % 1) == 0) + || (*p == ':' && (flags & P_COLON))) + { + xp->xp_pattern = p + 1; + break; + } } } + } + + // An option that is a list of single-character flags should always start + // at the end as we don't complete words. + if (flags & P_FLAGLIST) + xp->xp_pattern = arg + STRLEN(arg); + // Some options can either be using file/dir expansions, or custom value + // expansion depending on what the user typed. Unfortunately we have to + // manually handle it here to make sure we have the correct xp_context set. #ifdef FEAT_SPELL - // for 'spellsuggest' start at "file:" - if (options[opt_idx].var == (char_u *)&p_sps - && STRNCMP(p, "file:", 5) == 0) + if (options[opt_idx].var == (char_u *)&p_sps) + { + if (STRNCMP(xp->xp_pattern, "file:", 5) == 0) { - xp->xp_pattern = p + 5; - break; + xp->xp_pattern += 5; + return; + } + else if (options[expand_option_idx].opt_expand_cb != NULL) + { + xp->xp_context = EXPAND_STRING_SETTING; } -#endif } +#endif } /* @@ -7464,7 +7518,7 @@ set_context_in_set_cmd( * If 'test_only' is FALSE and 'fuzzy' is TRUE and if 'str' fuzzy matches * 'fuzzystr', then stores the match details in fuzmatch[idx] and returns TRUE. */ - static int + int match_str( char_u *str, regmatch_T *regmatch, @@ -7711,6 +7765,37 @@ ExpandSettings( return OK; } +// Escape an option value that can be used on the command-line with :set. +// Caller needs to free the returned string, unless NULL is returned. + static char_u* +escape_option_str_cmdline(char_u *var) +{ + char_u *buf; + + // A backslash is required before some characters. This is the reverse of + // what happens in do_set(). + buf = vim_strsave_escaped(var, escape_chars); + if (buf == NULL) + return NULL; + +#ifdef BACKSLASH_IN_FILENAME + // For MS-Windows et al. we don't double backslashes at the start and + // before a file name character. + // The reverse is found at stropt_copy_value(). + for (var = buf; *var != NUL; MB_PTR_ADV(var)) + if (var[0] == '\\' && var[1] == '\\' + && expand_option_idx >= 0 + && (options[expand_option_idx].flags & P_EXPAND) + && vim_isfilec(var[2]) + && (var[2] != '\\' || (var == buf && var[4] != '\\'))) + STRMOVE(var, var + 1); +#endif + return buf; +} + +/* + * Expansion handler for :set= when we just want to fill in with the existing value. + */ int ExpandOldSetting(int *numMatches, char_u ***matches) { @@ -7718,7 +7803,7 @@ ExpandOldSetting(int *numMatches, char_u ***matches) char_u *buf; *numMatches = 0; - *matches = ALLOC_ONE(char_u *); + *matches = ALLOC_MULT(char_u *, 1); if (*matches == NULL) return FAIL; @@ -7739,34 +7824,211 @@ ExpandOldSetting(int *numMatches, char_u ***matches) else if (var == NULL) var = (char_u *)""; - // A backslash is required before some characters. This is the reverse of - // what happens in do_set(). - buf = vim_strsave_escaped(var, escape_chars); - + buf = escape_option_str_cmdline(var); if (buf == NULL) { VIM_CLEAR(*matches); return FAIL; } -#ifdef BACKSLASH_IN_FILENAME - // For MS-Windows et al. we don't double backslashes at the start and - // before a file name character. - for (var = buf; *var != NUL; MB_PTR_ADV(var)) - if (var[0] == '\\' && var[1] == '\\' - && expand_option_idx >= 0 - && (options[expand_option_idx].flags & P_EXPAND) - && vim_isfilec(var[2]) - && (var[2] != '\\' || (var == buf && var[4] != '\\'))) - STRMOVE(var, var + 1); -#endif - - *matches[0] = buf; + (*matches)[0] = buf; *numMatches = 1; return OK; } /* + * Expansion handler for :set=/:set+= when the option has a custom expansion handler. + */ + int +ExpandStringSetting( + expand_T *xp, + regmatch_T *regmatch, + int *numMatches, + char_u ***matches) +{ + char_u *var = NULL; // init for GCC + char_u *buf; + + if (expand_option_idx < 0 || + options[expand_option_idx].opt_expand_cb == NULL) + { + // Not supposed to reach this. This function is only for options with + // custom expansion callbacks. + return FAIL; + } + + optexpand_T args; + args.oe_varp = get_varp_scope(&options[expand_option_idx], expand_option_flags); + args.oe_append = expand_option_append; + args.oe_regmatch = regmatch; + args.oe_xp = xp; + args.oe_set_arg = xp->xp_line + expand_option_start_col; + args.oe_include_orig_val = + !expand_option_append && + (*args.oe_set_arg == NUL); + + // Retrieve the existing value, but escape it as a reverse of setting it. + // We technically only need to do this when oe_append or + // oe_include_orig_val is true. + option_value2string(&options[expand_option_idx], expand_option_flags); + var = NameBuff; + buf = escape_option_str_cmdline(var); + if (buf == NULL) + return FAIL; + + args.oe_opt_value = buf; + + int num_ret = options[expand_option_idx].opt_expand_cb(&args, numMatches, matches); + + vim_free(buf); + return num_ret; +} + +/* + * Expansion handler for :set-= + */ + int +ExpandSettingSubtract( + expand_T *xp, + regmatch_T *regmatch, + int *numMatches, + char_u ***matches) +{ + if (expand_option_idx < 0) + // term option + return ExpandOldSetting(numMatches, matches); + + char_u *option_val = *(char_u**)get_option_varp_scope( + expand_option_idx, expand_option_flags); + + long_u option_flags = options[expand_option_idx].flags; + + if (option_flags & P_NUM) + return ExpandOldSetting(numMatches, matches); + else if (option_flags & P_COMMA) + { + // Split the option by comma, then present each option to the user if + // it matches the pattern. + // This condition needs to go first, because 'whichwrap' has both + // P_COMMA and P_FLAGLIST. + garray_T ga; + + char_u *item; + char_u *option_copy; + char_u *next_val; + char_u *comma; + + if (*option_val == NUL) + return FAIL; + + // Make a copy as we need to inject null characters destructively. + option_copy = vim_strsave(option_val); + if (option_copy == NULL) + return FAIL; + next_val = option_copy; + + ga_init2(&ga, sizeof(char_u *), 10); + + do + { + item = next_val; + comma = vim_strchr(next_val, ','); + while (comma != NULL && comma != next_val && *(comma - 1) == '\\') + { + // "\," is interpreted as a literal comma rather than option + // separator when reading options in copy_option_part(). Skip + // it. + comma = vim_strchr(comma + 1, ','); + } + if (comma != NULL) + { + *comma = NUL; // null-terminate this value, required by later functions + next_val = comma + 1; + } + else + next_val = NULL; + + if (*item == NUL) + // empty value, don't add to list + continue; + + if (!vim_regexec(regmatch, item, (colnr_T)0)) + continue; + + char_u *buf = escape_option_str_cmdline(item); + if (buf == NULL) + { + vim_free(option_copy); + ga_clear_strings(&ga); + return FAIL; + } + if (ga_add_string(&ga, buf) != OK) + { + vim_free(buf); + break; + } + } while (next_val != NULL); + + vim_free(option_copy); + + *matches = ga.ga_data; + *numMatches = ga.ga_len; + return OK; + } + else if (option_flags & P_FLAGLIST) + { + // Only present the flags that are set on the option as the other flags + // are not meaningful to do set-= on. + + if (*xp->xp_pattern != NUL) + { + // Don't suggest anything if cmdline is non-empty. Vim's set-= + // behavior requires consecutive strings and it's usually + // unintuitive to users if ther try to subtract multiple flags at + // once. + return FAIL; + } + + int num_flags = STRLEN(option_val); + if (num_flags == 0) + return FAIL; + + *matches = ALLOC_MULT(char_u *, num_flags + 1); + if (*matches == NULL) + return FAIL; + + int count = 0; + char_u *p; + + p = vim_strsave(option_val); + if (p == NULL) + { + VIM_CLEAR(*matches); + return FAIL; + } + (*matches)[count++] = p; + + if (num_flags > 1) + { + // If more than one flags, split the flags up and expose each + // character as individual choice. + for (char_u *flag = option_val; *flag != NUL; flag++) + { + char_u *p = vim_strnsave(flag, 1); + if (p == NULL) + break; + (*matches)[count++] = p; + } + } + + *numMatches = count; + return OK; + } + + return ExpandOldSetting(numMatches, matches); +} + +/* * Get the value for the numeric or string option *opp in a nice format into * NameBuff[]. Must not be called with a hidden option! */ @@ -8097,6 +8359,7 @@ fill_culopt_flags(char_u *val, win_T *wp) p = val; while (*p != NUL) { + // Note: Keep this in sync with p_culopt_values. if (STRNCMP(p, "line", 4) == 0) { p += 4; diff --git a/src/option.h b/src/option.h index 68748304bf..ced4f3e4b7 100644 --- a/src/option.h +++ b/src/option.h @@ -60,6 +60,7 @@ #define P_RWINONLY 0x10000000L // only redraw current window #define P_MLE 0x20000000L // under control of 'modelineexpr' #define P_FUNC 0x40000000L // accept a function reference or a lambda +#define P_COLON 0x80000000L // values use colons to create sublists // Returned by get_option_value(). typedef enum { @@ -230,7 +231,7 @@ typedef enum { #define CPO_ALL "aAbBcCdDeEfFgHiIjJkKlLmMnoOpPqrRsStuvwWxXyZ$!%*-+<>#{|&/\\.;" // characters for p_ww option: -#define WW_ALL "bshl<>[],~" +#define WW_ALL "bshl<>[]~" // characters for p_mouse option: #define MOUSE_NORMAL 'n' // use mouse in Normal mode diff --git a/src/optiondefs.h b/src/optiondefs.h index 4f3a1524a9..08de5bf406 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -272,6 +272,11 @@ struct vimoption // callback function to invoke after an option is modified to validate and // apply the new value. opt_did_set_cb_T opt_did_set_cb; + + // callback function to invoke when expanding possible values on the + // cmdline. Only useful for string options. + opt_expand_cb_T opt_expand_cb; + char_u *def_val[2]; // default values for variable (vi and vim) #ifdef FEAT_EVAL sctx_T script_ctx; // script context where the option was last set @@ -324,7 +329,7 @@ static struct vimoption options[] = #else (char_u *)NULL, PV_NONE, #endif - NULL, + NULL, NULL, { #if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) (char_u *)128L, @@ -333,72 +338,72 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"antialias", "anti", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)FALSE} SCTX_INIT}, {"arabic", "arab", P_BOOL|P_VI_DEF|P_VIM|P_CURSWANT, #ifdef FEAT_ARABIC - (char_u *)VAR_WIN, PV_ARAB, did_set_arabic, + (char_u *)VAR_WIN, PV_ARAB, did_set_arabic, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"arabicshape", "arshape", P_BOOL|P_VI_DEF|P_VIM|P_RCLR, #ifdef FEAT_ARABIC - (char_u *)&p_arshape, PV_NONE, NULL, + (char_u *)&p_arshape, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)TRUE, (char_u *)0L} SCTX_INIT}, {"allowrevins", "ari", P_BOOL|P_VI_DEF|P_VIM, #ifdef FEAT_RIGHTLEFT - (char_u *)&p_ari, PV_NONE, NULL, + (char_u *)&p_ari, PV_NONE, NULL, NULL, #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, #endif {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"altkeymap", "akm", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"ambiwidth", "ambw", P_STRING|P_VI_DEF|P_RCLR, - (char_u *)&p_ambw, PV_NONE, did_set_ambiwidth, + (char_u *)&p_ambw, PV_NONE, did_set_ambiwidth, expand_set_ambiwidth, {(char_u *)"single", (char_u *)0L} SCTX_INIT}, {"autochdir", "acd", P_BOOL|P_VI_DEF, #ifdef FEAT_AUTOCHDIR - (char_u *)&p_acd, PV_NONE, did_set_autochdir, + (char_u *)&p_acd, PV_NONE, did_set_autochdir, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"autoshelldir", "asd", P_BOOL|P_VI_DEF, #ifdef FEAT_AUTOSHELLDIR - (char_u *)&p_asd, PV_NONE, NULL, + (char_u *)&p_asd, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"autoindent", "ai", P_BOOL|P_VI_DEF, - (char_u *)&p_ai, PV_AI, NULL, + (char_u *)&p_ai, PV_AI, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autoprint", "ap", P_BOOL|P_VI_DEF, - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autoread", "ar", P_BOOL|P_VI_DEF, - (char_u *)&p_ar, PV_AR, NULL, + (char_u *)&p_ar, PV_AR, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autowrite", "aw", P_BOOL|P_VI_DEF, - (char_u *)&p_aw, PV_NONE, NULL, + (char_u *)&p_aw, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autowriteall","awa", P_BOOL|P_VI_DEF, - (char_u *)&p_awa, PV_NONE, NULL, + (char_u *)&p_awa, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"background", "bg", P_STRING|P_VI_DEF|P_RCLR, - (char_u *)&p_bg, PV_NONE, did_set_background, + (char_u *)&p_bg, PV_NONE, did_set_background, expand_set_background, { #if (defined(MSWIN)) && !defined(FEAT_GUI) (char_u *)"dark", @@ -407,13 +412,13 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"backspace", "bs", P_STRING|P_VI_DEF|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_bs, PV_NONE, did_set_backspace, + (char_u *)&p_bs, PV_NONE, did_set_backspace, expand_set_backspace, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"backup", "bk", P_BOOL|P_VI_DEF|P_VIM, - (char_u *)&p_bk, PV_NONE, NULL, + (char_u *)&p_bk, PV_NONE, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"backupcopy", "bkc", P_STRING|P_VIM|P_ONECOMMA|P_NODUP, - (char_u *)&p_bkc, PV_BKC, did_set_backupcopy, + (char_u *)&p_bkc, PV_BKC, did_set_backupcopy, expand_set_backupcopy, #ifdef UNIX {(char_u *)"yes", (char_u *)"auto"} #else @@ -422,11 +427,11 @@ static struct vimoption options[] = SCTX_INIT}, {"backupdir", "bdir", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA |P_NODUP|P_SECURE, - (char_u *)&p_bdir, PV_NONE, NULL, + (char_u *)&p_bdir, PV_NONE, NULL, NULL, {(char_u *)DFLT_BDIR, (char_u *)0L} SCTX_INIT}, {"backupext", "bex", P_STRING|P_VI_DEF|P_NFNAME, (char_u *)&p_bex, PV_NONE, - did_set_backupext_or_patchmode, + did_set_backupext_or_patchmode, NULL, { #ifdef VMS (char_u *)"_", @@ -435,77 +440,77 @@ static struct vimoption options[] = #endif (char_u *)0L} SCTX_INIT}, {"backupskip", "bsk", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, - (char_u *)&p_bsk, PV_NONE, NULL, + (char_u *)&p_bsk, PV_NONE, NULL, NULL, {(char_u *)"", (char_u *)0L} SCTX_INIT}, {"balloondelay","bdlay",P_NUM|P_VI_DEF, #ifdef FEAT_BEVAL - (char_u *)&p_bdlay, PV_NONE, NULL, + (char_u *)&p_bdlay, PV_NONE, NULL, NULL, {(char_u *)600L, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"ballooneval", "beval",P_BOOL|P_VI_DEF|P_NO_MKRC, #ifdef FEAT_BEVAL_GUI - (char_u *)&p_beval, PV_NONE, did_set_ballooneval, + (char_u *)&p_beval, PV_NONE, did_set_ballooneval, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NONE, NULL, NULL, {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"balloonevalterm", "bevalterm",P_BOOL|P_VI_DEF|P_NO_MKRC, #ifdef FEAT_BEVAL_TERM (char_u *)&p_bevalterm, PV_NONE, - did_set_balloonevalterm, + did_set_balloonevalterm, NULL, {(char_u *)FALSE, (char_u *)0L} #else - (char_u *)NULL, PV_NONE, NULL, + (char_u *)NULL, PV_NO |