aboutsummaryrefslogtreecommitdiff
path: root/src/option.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/option.c')
-rw-r--r--src/option.c177
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.
*/