diff options
Diffstat (limited to 'src/option.c')
-rw-r--r-- | src/option.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/option.c b/src/option.c index 56f86e34fd..89069d96ef 100644 --- a/src/option.c +++ b/src/option.c @@ -32,6 +32,7 @@ #define IN_OPTION_C #include <string.h> +#include <stdint.h> #include <stdlib.h> #include "vim.h" @@ -5946,6 +5947,124 @@ get_option_value ( return 1; } +// Returns the option attributes and its value. Unlike the above function it +// will return either global value or local value of the option depending on +// what was requested, but it will never return global value if it was +// requested to return local one and vice versa. Neither it will return +// buffer-local value if it was requested to return window-local one. +// +// Pretends that option is absent if it is not present in the requested scope +// (i.e. has no global, window-local or buffer-local value depending on +// opt_type). Uses +// +// Returned flags: +// 0 hidden or unknown option, also option that does not have requested +// type (see SREQ_* in vim.h) +// see SOPT_* in vim.h for other flags +// +// Possible opt_type values: see SREQ_* in vim.h +int get_option_value_strict(char *name, + int64_t *numval, + char **stringval, + int opt_type, + void *from) +{ + char_u *varp = NULL; + struct vimoption *p; + int rv = 0; + int opt_idx = findoption((uint8_t *)name); + if (opt_idx < 0) { + return 0; + } + + p = &(options[opt_idx]); + + // Hidden option + if (p->var == NULL) { + return 0; + } + + if (p->flags & P_BOOL) { + rv |= SOPT_BOOL; + } else if (p->flags & P_NUM) { + rv |= SOPT_NUM; + } else if (p->flags & P_STRING) { + rv |= SOPT_STRING; + } + + if (p->indir == PV_NONE) { + if (opt_type == SREQ_GLOBAL) + rv |= SOPT_GLOBAL; + else + return 0; // Did not request global-only option + } else { + if (p->indir & PV_BOTH) { + rv |= SOPT_GLOBAL; + } else if (opt_type == SREQ_GLOBAL) { + return 0; // Requested global option + } + + if (p->indir & PV_WIN) { + if (opt_type == SREQ_BUF) { + return 0; // Did not request window-local option + } else { + rv |= SOPT_WIN; + } + } else if (p->indir & PV_BUF) { + if (opt_type == SREQ_WIN) { + return 0; // Did not request buffer-local option + } else { + rv |= SOPT_BUF; + } + } + } + + if (stringval == NULL) { + return rv; + } + + if (opt_type == SREQ_GLOBAL) { + varp = p->var; + } else { + if (opt_type == SREQ_BUF) { + // Special case: 'modified' is b_changed, but we also want to + // consider it set when 'ff' or 'fenc' changed. + if (p->indir == PV_MOD) { + *numval = bufIsChanged((buf_T *) from); + varp = NULL; + } else { + aco_save_T aco; + aucmd_prepbuf(&aco, (buf_T *) from); + varp = get_varp(p); + aucmd_restbuf(&aco); + } + } else if (opt_type == SREQ_WIN) { + win_T *save_curwin; + save_curwin = curwin; + curwin = (win_T *) from; + curbuf = curwin->w_buffer; + varp = get_varp(p); + curwin = save_curwin; + curbuf = curwin->w_buffer; + } + + if (varp == p->var) { + return (rv | SOPT_UNSET); + } + } + + if (varp != NULL) { + if (p->flags & P_STRING) { + *stringval = xstrdup(*(char **)(varp)); + } else if (p->flags & P_NUM) { + *numval = *(long *) varp; + } else { + *numval = *(int *)varp; + } + } + + return rv; +} /* * Set the value of option "name". @@ -6554,6 +6673,64 @@ void comp_col(void) ru_col = 1; } +// Unset local option value, similar to ":set opt<". +void unset_global_local_option(char *name, void *from) +{ + struct vimoption *p; + int opt_idx; + buf_T *buf = (buf_T *)from; + + opt_idx = findoption((uint8_t *)name); + p = &(options[opt_idx]); + + switch ((int)p->indir) + { + // global option with local value: use local value if it's been set + case PV_EP: + clear_string_option(&buf->b_p_ep); + break; + case PV_KP: + clear_string_option(&buf->b_p_kp); + break; + case PV_PATH: + clear_string_option(&buf->b_p_path); + break; + case PV_AR: + buf->b_p_ar = -1; + break; + case PV_TAGS: + clear_string_option(&buf->b_p_tags); + break; + case PV_DEF: + clear_string_option(&buf->b_p_def); + break; + case PV_INC: + clear_string_option(&buf->b_p_inc); + break; + case PV_DICT: + clear_string_option(&buf->b_p_dict); + break; + case PV_TSR: + clear_string_option(&buf->b_p_tsr); + break; + case PV_EFM: + clear_string_option(&buf->b_p_efm); + break; + case PV_GP: + clear_string_option(&buf->b_p_gp); + break; + case PV_MP: + clear_string_option(&buf->b_p_mp); + break; + case PV_STL: + clear_string_option(&((win_T *)from)->w_p_stl); + break; + case PV_UL: + buf->b_p_ul = NO_LOCAL_UNDOLEVEL; + break; + } +} + /* * Get pointer to option variable, depending on local or global scope. */ |