diff options
Diffstat (limited to 'src/nvim/option.c')
-rw-r--r-- | src/nvim/option.c | 224 |
1 files changed, 137 insertions, 87 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c index af7b272467..2f22c245dd 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -32,6 +32,7 @@ #include "nvim/vim.h" #include "nvim/ascii.h" +#include "nvim/edit.h" #include "nvim/option.h" #include "nvim/buffer.h" #include "nvim/charset.h" @@ -1177,28 +1178,27 @@ do_set ( errmsg = e_invarg; goto skip; } - arg[len] = NUL; /* put NUL after name */ - if (arg[1] == 't' && arg[2] == '_') /* could be term code */ - opt_idx = findoption(arg + 1); - arg[len++] = '>'; /* restore '>' */ - if (opt_idx == -1) + if (arg[1] == 't' && arg[2] == '_') { // could be term code + opt_idx = findoption_len(arg + 1, (size_t) (len - 1)); + } + len++; + if (opt_idx == -1) { key = find_key_option(arg + 1); + } } else { len = 0; - /* - * The two characters after "t_" may not be alphanumeric. - */ - if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) + // The two characters after "t_" may not be alphanumeric. + if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) { len = 4; - else - while (ASCII_ISALNUM(arg[len]) || arg[len] == '_') - ++len; - nextchar = arg[len]; - arg[len] = NUL; /* put NUL after name */ - opt_idx = findoption(arg); - arg[len] = nextchar; /* restore nextchar */ - if (opt_idx == -1) + } else { + while (ASCII_ISALNUM(arg[len]) || arg[len] == '_') { + len++; + } + } + opt_idx = findoption_len(arg, (size_t) len); + if (opt_idx == -1) { key = find_key_option(arg); + } } /* remember character after option name */ @@ -1448,7 +1448,7 @@ do_set ( char_u *oldval = NULL; // previous value if *varp char_u *newval; char_u *origval = NULL; - char_u *saved_origval = NULL; + char *saved_origval = NULL; unsigned newlen; int comma; int bs; @@ -1725,7 +1725,7 @@ do_set ( if (!starting && origval != NULL) { // origval may be freed by // did_set_string_option(), make a copy. - saved_origval = vim_strsave(origval); + saved_origval = xstrdup((char *) origval); } /* Handle side effects, and set the global value for @@ -1740,11 +1740,10 @@ do_set ( } if (saved_origval != NULL) { - char_u buf_type[7]; - vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s", + char buf_type[7]; + vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); - set_vim_var_string(VV_OPTION_NEW, - *(char_u **)varp, -1); + set_vim_var_string(VV_OPTION_NEW, *(char **) varp, -1); set_vim_var_string(VV_OPTION_OLD, saved_origval, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); apply_autocmds(EVENT_OPTIONSET, @@ -2058,6 +2057,7 @@ static void didset_options(void) (void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, true); (void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true); (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, true); + (void)opt_strings_flags(p_tc, p_tc_values, &tc_flags, false); (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, true); (void)spell_check_msm(); (void)spell_check_sps(); @@ -2145,6 +2145,7 @@ void check_buf_options(buf_T *buf) check_string_option(&buf->b_p_ep); check_string_option(&buf->b_p_path); check_string_option(&buf->b_p_tags); + check_string_option(&buf->b_p_tc); check_string_option(&buf->b_p_dict); check_string_option(&buf->b_p_tsr); check_string_option(&buf->b_p_lw); @@ -2324,7 +2325,7 @@ set_string_option ( char_u *s; char_u **varp; char_u *oldval; - char_u *saved_oldval = NULL; + char *saved_oldval = NULL; char_u *r = NULL; if (options[opt_idx].var == NULL) /* don't set hidden option */ @@ -2340,7 +2341,7 @@ set_string_option ( *varp = s; if (!starting) { - saved_oldval = vim_strsave(oldval); + saved_oldval = xstrdup((char *) oldval); } if ((r = did_set_string_option(opt_idx, varp, (int)true, oldval, NULL, @@ -2349,10 +2350,10 @@ set_string_option ( // call autocommand after handling side effects if (saved_oldval != NULL) { - char_u buf_type[7]; - vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s", + char buf_type[7]; + vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); - set_vim_var_string(VV_OPTION_NEW, *varp, -1); + set_vim_var_string(VV_OPTION_NEW, (char *) (*varp), -1); set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); apply_autocmds(EVENT_OPTIONSET, @@ -2958,13 +2959,17 @@ did_set_string_option ( } /* 'completeopt' */ else if (varp == &p_cot) { - if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK) + if (check_opt_strings(p_cot, p_cot_values, true) != OK) { errmsg = e_invarg; + } else { + completeopt_was_set(); + } } /* 'pastetoggle': translate key codes like in a mapping */ else if (varp == &p_pt) { if (*p_pt) { - (void)replace_termcodes(p_pt, &p, TRUE, TRUE, FALSE); + (void)replace_termcodes(p_pt, STRLEN(p_pt), &p, true, true, false, + CPO_TO_CPO_FLAGS); if (p != NULL) { if (new_value_alloced) free_string_option(p_pt); @@ -2984,6 +2989,24 @@ did_set_string_option ( if (opt_strings_flags(p_bo, p_bo_values, &bo_flags, true) != OK) { errmsg = e_invarg; } + } else if (gvarp == &p_tc) { // 'tagcase' + unsigned int *flags; + + if (opt_flags & OPT_LOCAL) { + p = curbuf->b_p_tc; + flags = &curbuf->b_tc_flags; + } else { + p = p_tc; + flags = &tc_flags; + } + + if ((opt_flags & OPT_LOCAL) && *p == NUL) { + // make the local value empty: use the global value + *flags = 0; + } else if (*p == NUL + || opt_strings_flags(p, p_tc_values, flags, false) != OK) { + errmsg = e_invarg; + } } else if (varp == &p_cmp) { // 'casemap' if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, true) != OK) errmsg = e_invarg; @@ -3800,7 +3823,7 @@ set_bool_option ( msg_source(hl_attr(HLF_W)); MSG_ATTR(_(w_arabic), hl_attr(HLF_W)); - set_vim_var_string(VV_WARNINGMSG, (char_u *)_(w_arabic), -1); + set_vim_var_string(VV_WARNINGMSG, _(w_arabic), -1); } /* set 'delcombine' */ @@ -3847,14 +3870,14 @@ set_bool_option ( options[opt_idx].flags |= P_WAS_SET; if (!starting) { - char_u buf_old[2]; - char_u buf_new[2]; - char_u buf_type[7]; - vim_snprintf((char *)buf_old, ARRAY_SIZE(buf_old), "%d", + char buf_old[2]; + char buf_new[2]; + char buf_type[7]; + vim_snprintf(buf_old, ARRAY_SIZE(buf_old), "%d", old_value ? true: false); - vim_snprintf((char *)buf_new, ARRAY_SIZE(buf_new), "%d", + vim_snprintf(buf_new, ARRAY_SIZE(buf_new), "%d", value ? true: false); - vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s", + vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); set_vim_var_string(VV_OPTION_NEW, buf_new, -1); set_vim_var_string(VV_OPTION_OLD, buf_old, -1); @@ -4237,12 +4260,12 @@ set_num_option ( options[opt_idx].flags |= P_WAS_SET; if (!starting && errmsg == NULL) { - char_u buf_old[NUMBUFLEN]; - char_u buf_new[NUMBUFLEN]; - char_u buf_type[7]; - vim_snprintf((char *)buf_old, ARRAY_SIZE(buf_old), "%ld", old_value); - vim_snprintf((char *)buf_new, ARRAY_SIZE(buf_new), "%ld", value); - vim_snprintf((char *)buf_type, ARRAY_SIZE(buf_type), "%s", + char buf_old[NUMBUFLEN]; + char buf_new[NUMBUFLEN]; + char buf_type[7]; + vim_snprintf(buf_old, ARRAY_SIZE(buf_old), "%ld", old_value); + vim_snprintf(buf_new, ARRAY_SIZE(buf_new), "%ld", value); + vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global"); set_vim_var_string(VV_OPTION_NEW, buf_new, -1); set_vim_var_string(VV_OPTION_OLD, buf_old, -1); @@ -4284,14 +4307,16 @@ static void check_redraw(uint32_t flags) redraw_all_later(NOT_VALID); } -/* - * Find index for option 'arg'. - * Return -1 if not found. - */ -static int findoption(char_u *arg) +/// Find index for named option +/// +/// @param[in] arg Option to find index for. +/// @param[in] len Length of the option. +/// +/// @return Index of the option or -1 if option was not found. +int findoption_len(const char_u *const arg, const size_t len) { - char *s, *p; - static short quick_tab[27] = {0, 0}; /* quick access table */ + char *s, *p; + static int quick_tab[27] = { 0, 0 }; // quick access table int is_term_opt; /* @@ -4315,25 +4340,31 @@ static int findoption(char_u *arg) /* * Check for name starting with an illegal character. */ - if (arg[0] < 'a' || arg[0] > 'z') + if (len == 0 || arg[0] < 'a' || arg[0] > 'z') { return -1; + } int opt_idx; - is_term_opt = (arg[0] == 't' && arg[1] == '_'); - if (is_term_opt) + is_term_opt = (len > 2 && arg[0] == 't' && arg[1] == '_'); + if (is_term_opt) { opt_idx = quick_tab[26]; - else + } else { opt_idx = quick_tab[CharOrdLow(arg[0])]; + } + // Match full name for (; (s = options[opt_idx].fullname) != NULL; opt_idx++) { - if (STRCMP(arg, s) == 0) /* match full name */ + if (STRNCMP(arg, s, len) == 0 && s[len] == NUL) { break; + } } if (s == NULL && !is_term_opt) { opt_idx = quick_tab[CharOrdLow(arg[0])]; + // Match short name for (; options[opt_idx].fullname != NULL; opt_idx++) { s = options[opt_idx].shortname; - if (s != NULL && STRCMP(arg, s) == 0) /* match short name */ + if (s != NULL && STRNCMP(arg, s, len) == 0 && s[len] == NUL) { break; + } s = NULL; } } @@ -4401,6 +4432,15 @@ bool set_tty_option(char *name, char *value) } /* + * Find index for option 'arg'. + * Return -1 if not found. + */ +static int findoption(char_u *arg) +{ + return findoption_len(arg, STRLEN(arg)); +} + +/* * Get the value for an option. * * Returns: @@ -4656,27 +4696,32 @@ char_u *get_highlight_default(void) /* * Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number. */ -static int find_key_option(char_u *arg) +int find_key_option_len(const char_u *arg, size_t len) { int key; int modifiers; - /* - * Don't use get_special_key_code() for t_xx, we don't want it to call - * add_termcap_entry(). - */ - if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3]) + // Don't use get_special_key_code() for t_xx, we don't want it to call + // add_termcap_entry(). + if (len >= 4 && arg[0] == 't' && arg[1] == '_') { key = TERMCAP2KEY(arg[2], arg[3]); - else { - --arg; /* put arg at the '<' */ + } else { + arg--; // put arg at the '<' modifiers = 0; - key = find_special_key(&arg, &modifiers, TRUE, TRUE); - if (modifiers) /* can't handle modifiers here */ + key = find_special_key(&arg, len + 1, &modifiers, true, true); + if (modifiers) { // can't handle modifiers here key = 0; + } } return key; } +static int find_key_option(const char_u *arg) +{ + return find_key_option_len(arg, STRLEN(arg)); +} + + /* * if 'all' == 0: show changed options * if 'all' == 1: show all normal options @@ -4737,9 +4782,10 @@ showoptions ( option_value2string(p, opt_flags); len = (int)STRLEN(p->fullname) + vim_strsize(NameBuff) + 1; } - if ((len <= INC - GAP && run == 1) || - (len > INC - GAP && run == 2)) + if ((len <= INC - GAP && run == 1) + || (len > INC - GAP && run == 2)) { items[item_count++] = p; + } } } @@ -4928,18 +4974,15 @@ int makeset(FILE *fd, int opt_flags, int local_only) } else { /* P_STRING */ int do_endif = FALSE; - /* Don't set 'syntax' and 'filetype' again if the value is - * already right, avoids reloading the syntax file. */ - if ( - p->indir == PV_SYN - || - p->indir == PV_FT - ) { + // Don't set 'syntax' and 'filetype' again if the value is + // already right, avoids reloading the syntax file. + if (p->indir == PV_SYN || p->indir == PV_FT) { if (fprintf(fd, "if &%s != '%s'", p->fullname, - *(char_u **)(varp)) < 0 - || put_eol(fd) < 0) + *(char_u **)(varp)) < 0 + || put_eol(fd) < 0) { return FAIL; - do_endif = TRUE; + } + do_endif = true; } if (put_setstring(fd, cmd, p->fullname, (char_u **)varp, (p->flags & P_EXPAND) != 0) == FAIL) @@ -5112,6 +5155,10 @@ void unset_global_local_option(char *name, void *from) case PV_TAGS: clear_string_option(&buf->b_p_tags); break; + case PV_TC: + clear_string_option(&buf->b_p_tc); + buf->b_tc_flags = 0; + break; case PV_DEF: clear_string_option(&buf->b_p_def); break; @@ -5165,6 +5212,7 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags) case PV_PATH: return (char_u *)&(curbuf->b_p_path); case PV_AR: return (char_u *)&(curbuf->b_p_ar); case PV_TAGS: return (char_u *)&(curbuf->b_p_tags); + case PV_TC: return (char_u *)&(curbuf->b_p_tc); case PV_DEF: return (char_u *)&(curbuf->b_p_def); case PV_INC: return (char_u *)&(curbuf->b_p_inc); case PV_DICT: return (char_u *)&(curbuf->b_p_dict); @@ -5202,6 +5250,8 @@ static char_u *get_varp(vimoption_T *p) ? (char_u *)&(curbuf->b_p_ar) : p->var; case PV_TAGS: return *curbuf->b_p_tags != NUL ? (char_u *)&(curbuf->b_p_tags) : p->var; + case PV_TC: return *curbuf->b_p_tc != NUL + ? (char_u *)&(curbuf->b_p_tc) : p->var; case PV_BKC: return *curbuf->b_p_bkc != NUL ? (char_u *)&(curbuf->b_p_bkc) : p->var; case PV_DEF: return *curbuf->b_p_def != NUL @@ -5581,6 +5631,8 @@ void buf_copy_options(buf_T *buf, int flags) buf->b_p_kp = empty_option; buf->b_p_path = empty_option; buf->b_p_tags = empty_option; + buf->b_p_tc = empty_option; + buf->b_tc_flags = 0; buf->b_p_def = empty_option; buf->b_p_inc = empty_option; buf->b_p_inex = vim_strsave(p_inex); @@ -6167,16 +6219,14 @@ int has_format_option(int x) return vim_strchr(curbuf->b_p_fo, x) != NULL; } -/* - * Return TRUE if "x" is present in 'shortmess' option, or - * 'shortmess' contains 'a' and "x" is present in SHM_A. - */ -int shortmess(int x) +/// @returns true if "x" is present in 'shortmess' option, or +/// 'shortmess' contains 'a' and "x" is present in SHM_ALL_ABBREVIATIONS. +bool shortmess(int x) { - return p_shm != NULL && - ( vim_strchr(p_shm, x) != NULL - || (vim_strchr(p_shm, 'a') != NULL - && vim_strchr((char_u *)SHM_A, x) != NULL)); + return (p_shm != NULL + && (vim_strchr(p_shm, x) != NULL + || (vim_strchr(p_shm, 'a') != NULL + && vim_strchr((char_u *)SHM_ALL_ABBREVIATIONS, x) != NULL))); } /* |