From 7224c889e0d5d70b99ae377036baa6377c33a568 Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Sat, 11 Feb 2023 10:25:24 +0100 Subject: build: enable MSVC level 3 warnings (#21934) MSVC has 4 different warning levels: 1 (severe), 2 (significant), 3 (production quality) and 4 (informational). Enabling level 3 warnings mostly revealed conversion problems, similar to GCC/clang -Wconversion flag. --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index bfcb99754f..2a54c3b132 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -181,7 +181,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error switch (value.type) { case kObjectTypeInteger: - numval = value.data.integer; + numval = (long)value.data.integer; break; case kObjectTypeBoolean: numval = value.data.boolean ? 1 : 0; -- cgit From 46a87a5d2bac598fed0870f0d3c926087f95d30f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 05:19:04 -0500 Subject: refactor(api): VALIDATE macros #22187 Problem: - API validation involves too much boilerplate. - API validation errors are not consistently worded. Solution: Introduce some macros. Currently these are clumsy, but they at least help with consistency and avoid some nesting. --- src/nvim/api/options.c | 128 ++++++++++++++++++++----------------------------- 1 file changed, 51 insertions(+), 77 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 2a54c3b132..5b57b49ad6 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -9,6 +9,7 @@ #include "nvim/api/options.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" +#include "nvim/api/private/validate.h" #include "nvim/autocmd.h" #include "nvim/buffer_defs.h" #include "nvim/eval/window.h" @@ -31,11 +32,14 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } else if (!strcmp(opts->scope.data.string.data, "global")) { *scope = OPT_GLOBAL; } else { - api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'"); - return FAIL; + VALIDATE(false, "Invalid scope (expected 'local' or 'global')", { + return FAIL; + }); } } else if (HAS_KEY(opts->scope)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: scope"); + VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { + return FAIL; + }); return FAIL; } @@ -48,8 +52,9 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t return FAIL; } } else if (HAS_KEY(opts->win)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: win"); - return FAIL; + VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + return FAIL; + }); } if (opts->buf.type == kObjectTypeInteger) { @@ -60,19 +65,17 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t return FAIL; } } else if (HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "invalid value for key: buf"); - return FAIL; + VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { + return FAIL; + }); } - if (HAS_KEY(opts->scope) && HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "scope and buf cannot be used together"); + VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "cannot use both 'scope' and 'buf'", { return FAIL; - } - - if (HAS_KEY(opts->win) && HAS_KEY(opts->buf)) { - api_set_error(err, kErrorTypeValidation, "buf and win cannot be used together"); + }); + VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "cannot use both 'buf' and 'win'", { return FAIL; - } + }); return OK; } @@ -132,8 +135,9 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) } break; default: - api_set_error(err, kErrorTypeValidation, "unknown option '%s'", name.data); - return rv; + VALIDATE_S(false, "option", name.data, { + return rv; + }); } return rv; @@ -193,8 +197,9 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error scope |= OPT_CLEAR; break; default: - api_set_error(err, kErrorTypeValidation, "invalid value for option"); - return; + VALIDATE_EXP(false, "option type", "Integer, Boolean, or String", api_typename(value.type), { + return; + }); } access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err); @@ -351,21 +356,18 @@ static Object get_option_from(void *from, int type, String name, Error *err) { Object rv = OBJECT_INIT; - if (name.size == 0) { - api_set_error(err, kErrorTypeValidation, "Empty option name"); + VALIDATE_S(name.size > 0, "option name", "", { return rv; - } + }); // Return values int64_t numval; char *stringval = NULL; - int flags = get_option_value_strict(name.data, &numval, &stringval, type, from); - if (!flags) { - api_set_error(err, kErrorTypeValidation, "Invalid option name: '%s'", - name.data); + int flags = get_option_value_strict(name.data, &numval, &stringval, type, from); + VALIDATE_S(flags != 0, "option name", name.data, { return rv; - } + }); if (flags & SOPT_BOOL) { rv.type = kObjectTypeBoolean; @@ -374,20 +376,15 @@ static Object get_option_from(void *from, int type, String name, Error *err) rv.type = kObjectTypeInteger; rv.data.integer = numval; } else if (flags & SOPT_STRING) { - if (stringval) { - rv.type = kObjectTypeString; - rv.data.string.data = stringval; - rv.data.string.size = strlen(stringval); - } else { - api_set_error(err, kErrorTypeException, - "Failed to get value for option '%s'", - name.data); + if (!stringval) { + api_set_error(err, kErrorTypeException, "Failed to get option '%s'", name.data); + return rv; } + rv.type = kObjectTypeString; + rv.data.string.data = stringval; + rv.data.string.size = strlen(stringval); } else { - api_set_error(err, - kErrorTypeException, - "Unknown type for option '%s'", - name.data); + api_set_error(err, kErrorTypeException, "Unknown type for option '%s'", name.data); } return rv; @@ -402,29 +399,22 @@ static Object get_option_from(void *from, int type, String name, Error *err) /// @param[out] err Details of an error that may have occurred void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err) { - if (name.size == 0) { - api_set_error(err, kErrorTypeValidation, "Empty option name"); + VALIDATE_S(name.size > 0, "option name", "", { return; - } + }); int flags = get_option_value_strict(name.data, NULL, NULL, type, to); - - if (flags == 0) { - api_set_error(err, kErrorTypeValidation, "Invalid option name '%s'", - name.data); + VALIDATE_S(flags != 0, "option name", name.data, { return; - } + }); if (value.type == kObjectTypeNil) { if (type == SREQ_GLOBAL) { - api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", - name.data); + api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", name.data); return; } else if (!(flags & SOPT_GLOBAL)) { - api_set_error(err, - kErrorTypeException, - "Cannot unset option '%s' " - "because it doesn't have a global value", + api_set_error(err, kErrorTypeException, + "Cannot unset option '%s' because it doesn't have a global value", name.data); return; } else { @@ -437,39 +427,23 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object char *stringval = NULL; if (flags & SOPT_BOOL) { - if (value.type != kObjectTypeBoolean) { - api_set_error(err, - kErrorTypeValidation, - "Option '%s' requires a Boolean value", - name.data); + VALIDATE_FMT(value.type == kObjectTypeBoolean, "Option '%s' value must be Boolean", name.data, { return; - } - + }); numval = value.data.boolean; } else if (flags & SOPT_NUM) { - if (value.type != kObjectTypeInteger) { - api_set_error(err, kErrorTypeValidation, - "Option '%s' requires an integer value", - name.data); + VALIDATE_FMT(value.type == kObjectTypeInteger, "Option '%s' value must be Integer", name.data, { return; - } - - if (value.data.integer > INT_MAX || value.data.integer < INT_MIN) { - api_set_error(err, kErrorTypeValidation, - "Value for option '%s' is out of range", - name.data); + }); + VALIDATE_FMT((value.data.integer <= INT_MAX && value.data.integer >= INT_MIN), + "Option '%s' value is out of range", name.data, { return; - } - + }); numval = (int)value.data.integer; } else { - if (value.type != kObjectTypeString) { - api_set_error(err, kErrorTypeValidation, - "Option '%s' requires a string value", - name.data); + VALIDATE_FMT(value.type == kObjectTypeString, "Option '%s' value must be String", name.data, { return; - } - + }); stringval = value.data.string.data; } -- cgit From ff3d04b75b4a9314815c37d53ebc4d035a043335 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 08:07:38 -0500 Subject: refactor(api): VALIDATE macros #22256 - VALIDATE() takes a format string - deduplicate check_string_array - VALIDATE_RANGE - validate UI args --- src/nvim/api/options.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 5b57b49ad6..40720c31c7 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -26,54 +26,54 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from, Error *err) { - if (opts->scope.type == kObjectTypeString) { + if (HAS_KEY(opts->scope)) { + VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { + return FAIL; + }); + if (!strcmp(opts->scope.data.string.data, "local")) { *scope = OPT_LOCAL; } else if (!strcmp(opts->scope.data.string.data, "global")) { *scope = OPT_GLOBAL; } else { - VALIDATE(false, "Invalid scope (expected 'local' or 'global')", { + VALIDATE(false, "%s", "Invalid scope: expected 'local' or 'global'", { return FAIL; }); } - } else if (HAS_KEY(opts->scope)) { - VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { - return FAIL; - }); - return FAIL; } *opt_type = SREQ_GLOBAL; - if (opts->win.type == kObjectTypeInteger) { + if (HAS_KEY(opts->win)) { + VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + return FAIL; + }); + *opt_type = SREQ_WIN; *from = find_window_by_handle((int)opts->win.data.integer, err); if (ERROR_SET(err)) { return FAIL; } - } else if (HAS_KEY(opts->win)) { - VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + } + + if (HAS_KEY(opts->buf)) { + VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { return FAIL; }); - } - if (opts->buf.type == kObjectTypeInteger) { *scope = OPT_LOCAL; *opt_type = SREQ_BUF; *from = find_buffer_by_handle((int)opts->buf.data.integer, err); if (ERROR_SET(err)) { return FAIL; } - } else if (HAS_KEY(opts->buf)) { - VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { - return FAIL; - }); } - VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "cannot use both 'scope' and 'buf'", { + VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "%s", + "cannot use both 'scope' and 'buf'", { return FAIL; }); - VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "cannot use both 'buf' and 'win'", { + VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "%s", "cannot use both 'buf' and 'win'", { return FAIL; }); @@ -427,21 +427,21 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object char *stringval = NULL; if (flags & SOPT_BOOL) { - VALIDATE_FMT(value.type == kObjectTypeBoolean, "Option '%s' value must be Boolean", name.data, { + VALIDATE(value.type == kObjectTypeBoolean, "Option '%s' value must be Boolean", name.data, { return; }); numval = value.data.boolean; } else if (flags & SOPT_NUM) { - VALIDATE_FMT(value.type == kObjectTypeInteger, "Option '%s' value must be Integer", name.data, { + VALIDATE(value.type == kObjectTypeInteger, "Option '%s' value must be Integer", name.data, { return; }); - VALIDATE_FMT((value.data.integer <= INT_MAX && value.data.integer >= INT_MIN), - "Option '%s' value is out of range", name.data, { + VALIDATE((value.data.integer <= INT_MAX && value.data.integer >= INT_MIN), + "Option '%s' value is out of range", name.data, { return; }); numval = (int)value.data.integer; } else { - VALIDATE_FMT(value.type == kObjectTypeString, "Option '%s' value must be String", name.data, { + VALIDATE(value.type == kObjectTypeString, "Option '%s' value must be String", name.data, { return; }); stringval = value.data.string.data; -- cgit From 556f8646c01d1751cf39fe4df9c622899dceab9d Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 14 Feb 2023 14:19:28 -0500 Subject: refactor(api): consistent VALIDATE messages #22262 Problem: Validation messages are not consistently formatted. - Parameter names sometimes are NOT quoted. - Descriptive names (non-parameters) sometimes ARE quoted. Solution: Always quote the `name` value passed to a VALIDATE macro _unless_ the value has whitespace. --- src/nvim/api/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 40720c31c7..ddaed3a254 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -36,7 +36,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } else if (!strcmp(opts->scope.data.string.data, "global")) { *scope = OPT_GLOBAL; } else { - VALIDATE(false, "%s", "Invalid scope: expected 'local' or 'global'", { + VALIDATE_EXP(false, "scope", "'local' or 'global'", NULL, { return FAIL; }); } @@ -197,7 +197,7 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error scope |= OPT_CLEAR; break; default: - VALIDATE_EXP(false, "option type", "Integer, Boolean, or String", api_typename(value.type), { + VALIDATE_EXP(false, name.data, "Integer/Boolean/String", api_typename(value.type), { return; }); } -- cgit From 6d0c61d90d316473eee0729363e20bf06825b09b Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 21:09:11 +0800 Subject: fix(api): set script context when setting usercmd or option (#22624) --- src/nvim/api/options.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index ddaed3a254..2d9ffcba06 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -157,7 +157,8 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) /// - win: |window-ID|. Used for setting window local option. /// - buf: Buffer number. Used for setting buffer local option. /// @param[out] err Error details, if any -void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error *err) +void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(option) *opts, + Error *err) FUNC_API_SINCE(9) { int scope = 0; @@ -202,7 +203,9 @@ void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error }); } - access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err); + WITH_SCRIPT_CONTEXT(channel_id, { + access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err); + }); } /// Gets the option information for all options. -- cgit From e1db0e35e4d5859b96e6aff882df62d6c714b569 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 15 Mar 2023 23:30:14 +0000 Subject: feat(api): add filetype option nvim_get_option_value - Also adjust the expr-mapping behaviour so normal commands and text changes are allowed in internal dummy buffers. --- src/nvim/api/options.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 2d9ffcba06..a0351cc6cd 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -24,7 +24,7 @@ #endif static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from, - Error *err) + char **filetype, Error *err) { if (HAS_KEY(opts->scope)) { VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { @@ -44,6 +44,14 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t *opt_type = SREQ_GLOBAL; + if (filetype != NULL && HAS_KEY(opts->filetype)) { + VALIDATE_T("scope", kObjectTypeString, opts->filetype.type, { + return FAIL; + }); + + *filetype = opts->filetype.data.string.data; + } + if (HAS_KEY(opts->win)) { VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { return FAIL; @@ -69,10 +77,17 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } } + VALIDATE((!HAS_KEY(opts->filetype) + || !(HAS_KEY(opts->buf) || HAS_KEY(opts->scope) || HAS_KEY(opts->win))), + "%s", "cannot use 'filetype' with 'scope', 'buf' or 'win'", { + return FAIL; + }); + VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "%s", "cannot use both 'scope' and 'buf'", { return FAIL; }); + VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "%s", "cannot use both 'buf' and 'win'", { return FAIL; }); @@ -80,6 +95,30 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t return OK; } +/// Create a dummy buffer and run the FileType autocmd on it. +static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) +{ + if (filetype == NULL) { + return NULL; + } + + // Allocate a buffer without putting it in the buffer list. + buf_T *ftbuf = buflist_new(NULL, NULL, 1, BLN_DUMMY); + if (ftbuf == NULL) { + api_set_error(err, kErrorTypeException, "Could not create internal buffer"); + return NULL; + } + + // Set curwin/curbuf to buf and save a few things. + aucmd_prepbuf(aco, ftbuf); + + ftbuf->b_p_ft = xstrdup(filetype); + + apply_autocmds(EVENT_FILETYPE, ftbuf->b_p_ft, ftbuf->b_fname, true, ftbuf); + + return ftbuf; +} + /// Gets the value of an option. The behavior of this function matches that of /// |:set|: the local value of an option is returned if it exists; otherwise, /// the global value is returned. Local values always correspond to the current @@ -92,6 +131,10 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t /// - win: |window-ID|. Used for getting window local options. /// - buf: Buffer number. Used for getting buffer local options. /// Implies {scope} is "local". +/// - filetype: |filetype|. Used to get the default option for a +/// specific filetype. Cannot be used with any other option. +/// Note: this is expensive, it is recommended to cache this +/// value. /// @param[out] err Error details, if any /// @return Option value Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) @@ -102,14 +145,37 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) int scope = 0; int opt_type = SREQ_GLOBAL; void *from = NULL; - if (!validate_option_value_args(opts, &scope, &opt_type, &from, err)) { + char *filetype = NULL; + + if (!validate_option_value_args(opts, &scope, &opt_type, &from, &filetype, err)) { + return rv; + } + + aco_save_T aco; + + buf_T *ftbuf = do_ft_buf(filetype, &aco, err); + if (ERROR_SET(err)) { return rv; } + if (ftbuf != NULL) { + assert(!from); + from = ftbuf; + } + long numval = 0; char *stringval = NULL; getoption_T result = access_option_value_for(name.data, &numval, &stringval, scope, opt_type, from, true, err); + + if (ftbuf != NULL) { + // restore curwin/curbuf and a few other things + aucmd_restbuf(&aco); + + assert(curbuf != ftbuf); // safety check + wipe_buffer(ftbuf, false); + } + if (ERROR_SET(err)) { return rv; } @@ -164,7 +230,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( int scope = 0; int opt_type = SREQ_GLOBAL; void *to = NULL; - if (!validate_option_value_args(opts, &scope, &opt_type, &to, err)) { + if (!validate_option_value_args(opts, &scope, &opt_type, &to, NULL, err)) { return; } -- cgit From e5641df6d3fc3bb6c3c55593b6152082bfc561b6 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 11 Mar 2023 17:11:02 +0000 Subject: feat: add `vim.filetype.get_option()` --- src/nvim/api/options.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index a0351cc6cd..7aef6e6146 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -114,7 +114,11 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) ftbuf->b_p_ft = xstrdup(filetype); - apply_autocmds(EVENT_FILETYPE, ftbuf->b_p_ft, ftbuf->b_fname, true, ftbuf); + TRY_WRAP({ + try_start(); + apply_autocmds(EVENT_FILETYPE, ftbuf->b_p_ft, ftbuf->b_fname, true, ftbuf); + try_end(err); + }); return ftbuf; } @@ -133,8 +137,8 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) /// Implies {scope} is "local". /// - filetype: |filetype|. Used to get the default option for a /// specific filetype. Cannot be used with any other option. -/// Note: this is expensive, it is recommended to cache this -/// value. +/// Note: this will trigger |ftplugin| and all |FileType| +/// autocommands for the corresponding filetype. /// @param[out] err Error details, if any /// @return Option value Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) -- cgit From 3285cd6eccd9b7f33cc32f992c2607c3fc4ca13f Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 22 Mar 2023 10:09:28 +0000 Subject: refactor: do more in TRY_WRAP --- src/nvim/api/options.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 7aef6e6146..502c73d02d 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -114,10 +114,8 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) ftbuf->b_p_ft = xstrdup(filetype); - TRY_WRAP({ - try_start(); + TRY_WRAP(err, { apply_autocmds(EVENT_FILETYPE, ftbuf->b_p_ft, ftbuf->b_fname, true, ftbuf); - try_end(err); }); return ftbuf; -- cgit From 28cfcf51269b7390b447c8a5b61d5083c830e834 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 22 Mar 2023 16:49:04 +0000 Subject: fix(api): vim.filetype.get_option() (#22753) - Fix a bug in the cache - Set some buffer options on the dummy buffer --- src/nvim/api/options.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 502c73d02d..7a453c01b4 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -111,6 +111,10 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) // Set curwin/curbuf to buf and save a few things. aucmd_prepbuf(aco, ftbuf); + set_option_value("bufhidden", 0L, "hide", OPT_LOCAL); + set_option_value("buftype", 0L, "nofile", OPT_LOCAL); + set_option_value("swapfile", 0L, NULL, OPT_LOCAL); + set_option_value("modeline", 0L, NULL, OPT_LOCAL); // 'nomodeline' ftbuf->b_p_ft = xstrdup(filetype); -- cgit From b7748662ed5b06c12a74560690b728fdf770666f Mon Sep 17 00:00:00 2001 From: Michal Liszcz Date: Wed, 29 Mar 2023 09:59:01 +0200 Subject: fix(api): Use local LastSet structure in nvim_get_option_info (#22741) fix(api): use local LastSet structure in nvim_get_option_info * nvim_get_option_info is deprecated. It is always using the global LastSet information as reported in #15232. * nvim_get_option_info2 is added. The new function additionally accepts an 'opts' table {scope, buf, win} allowing to specify the option scope and query local options from another buffer or window. --- src/nvim/api/options.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 7a453c01b4..31a2fb3b80 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -283,7 +283,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( /// Gets the option information for all options. /// /// The dictionary has the full option names as keys and option metadata -/// dictionaries as detailed at |nvim_get_option_info()|. +/// dictionaries as detailed at |nvim_get_option_info2()|. /// /// @return dictionary of all options Dictionary nvim_get_all_options_info(Error *err) @@ -292,7 +292,7 @@ Dictionary nvim_get_all_options_info(Error *err) return get_all_vimoptions(); } -/// Gets the option information for one option +/// Gets the option information for one option from arbitrary buffer or window /// /// Resulting dictionary has keys: /// - name: Name of the option (like 'filetype') @@ -311,15 +311,36 @@ Dictionary nvim_get_all_options_info(Error *err) /// - commalist: List of comma separated values /// - flaglist: List of single char flags /// +/// When {scope} is not provided, the last set information applies to the local +/// value in the current buffer or window if it is available, otherwise the +/// global value information is returned. This behavior can be disabled by +/// explicitly specifying {scope} in the {opts} table. /// -/// @param name Option name +/// @param name Option name +/// @param opts Optional parameters +/// - scope: One of "global" or "local". Analogous to +/// |:setglobal| and |:setlocal|, respectively. +/// - win: |window-ID|. Used for getting window local options. +/// - buf: Buffer number. Used for getting buffer local options. +/// Implies {scope} is "local". /// @param[out] err Error details, if any /// @return Option Information -Dictionary nvim_get_option_info(String name, Error *err) - FUNC_API_SINCE(7) +Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) + FUNC_API_SINCE(11) { - return get_vimoption(name, err); + int scope = 0; + int opt_type = SREQ_GLOBAL; + void *from = NULL; + if (!validate_option_value_args(opts, &scope, &opt_type, &from, NULL, err)) { + return (Dictionary)ARRAY_DICT_INIT; + } + + buf_T *buf = (opt_type == SREQ_BUF) ? (buf_T *)from : curbuf; + win_T *win = (opt_type == SREQ_WIN) ? (win_T *)from : curwin; + + return get_vimoption(name, scope, buf, win, err); } + /// Sets the global value of an option. /// /// @param channel_id -- cgit From 8b7fb668e440f7793564b764bc9a691e3f45382a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Wed, 29 Mar 2023 19:54:12 +0100 Subject: fix(filetype): avoid recursive FileType autocmds (#22813) --- src/nvim/api/options.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 31a2fb3b80..baeb3e88fb 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -111,15 +111,15 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) // Set curwin/curbuf to buf and save a few things. aucmd_prepbuf(aco, ftbuf); - set_option_value("bufhidden", 0L, "hide", OPT_LOCAL); - set_option_value("buftype", 0L, "nofile", OPT_LOCAL); - set_option_value("swapfile", 0L, NULL, OPT_LOCAL); - set_option_value("modeline", 0L, NULL, OPT_LOCAL); // 'nomodeline' - - ftbuf->b_p_ft = xstrdup(filetype); TRY_WRAP(err, { - apply_autocmds(EVENT_FILETYPE, ftbuf->b_p_ft, ftbuf->b_fname, true, ftbuf); + set_option_value("bufhidden", 0L, "hide", OPT_LOCAL); + set_option_value("buftype", 0L, "nofile", OPT_LOCAL); + set_option_value("swapfile", 0L, NULL, OPT_LOCAL); + set_option_value("modeline", 0L, NULL, OPT_LOCAL); // 'nomodeline' + + ftbuf->b_p_ft = xstrdup(filetype); + do_filetype_autocmd(ftbuf, false); }); return ftbuf; -- cgit From 371823d407d7d7519735131bcad4670c62a731a7 Mon Sep 17 00:00:00 2001 From: ii14 <59243201+ii14@users.noreply.github.com> Date: Wed, 5 Apr 2023 21:13:53 +0200 Subject: refactor: make error message definitions const message.c functions now take const char * as a format. Error message definitions can be made const. --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index baeb3e88fb..3e7f7e8781 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -559,7 +559,7 @@ static getoption_T access_option_value(char *key, long *numval, char **stringval if (get) { return get_option_value(key, numval, stringval, NULL, opt_flags); } else { - char *errmsg; + const char *errmsg; if ((errmsg = set_option_value(key, *numval, *stringval, opt_flags))) { if (try_end(err)) { return 0; -- cgit From 0f42aa1f2a860ce6d72a825b397fe09c875613b5 Mon Sep 17 00:00:00 2001 From: bfredl Date: Thu, 6 Apr 2023 10:03:37 +0200 Subject: fix(highlight): use winhl=Foo:Bar even when Bar is empty fixes #22906 --- src/nvim/api/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index baeb3e88fb..3e6466626f 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -53,7 +53,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } if (HAS_KEY(opts->win)) { - VALIDATE_T("win", kObjectTypeInteger, opts->win.type, { + VALIDATE_T_HANDLE("win", kObjectTypeWindow, opts->win.type, { return FAIL; }); @@ -65,7 +65,7 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t } if (HAS_KEY(opts->buf)) { - VALIDATE_T("buf", kObjectTypeInteger, opts->buf.type, { + VALIDATE_T_HANDLE("buf", kObjectTypeBuffer, opts->buf.type, { return FAIL; }); -- cgit From 3b0df1780e2c8526bda5dead18ee7cc45925caba Mon Sep 17 00:00:00 2001 From: dundargoc <33953936+dundargoc@users.noreply.github.com> Date: Wed, 26 Apr 2023 23:23:44 +0200 Subject: refactor: uncrustify Notable changes: replace all infinite loops to `while(true)` and remove `int` from `unsigned int`. --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 467a4720a6..2d1b170d2d 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -546,7 +546,7 @@ void set_option_to(uint64_t channel_id, void *to, int type, String name, Object // For global-win-local options -> setlocal // For win-local options -> setglobal and setlocal (opt_flags == 0) const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL)) ? 0 : - (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL; + (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL; WITH_SCRIPT_CONTEXT(channel_id, { access_option_value_for(name.data, &numval, &stringval, opt_flags, type, to, false, err); -- cgit From 1fe1bb084d0099fc4f9bfdc11189485d0f74b75a Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Mon, 19 Dec 2022 16:37:45 +0000 Subject: refactor(options): deprecate nvim[_buf|_win]_[gs]et_option Co-authored-by: zeertzjq Co-authored-by: famiu --- src/nvim/api/options.c | 216 +------------------------------------------------ 1 file changed, 2 insertions(+), 214 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 2d1b170d2d..6193a5c75b 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -341,218 +341,6 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) return get_vimoption(name, scope, buf, win, err); } -/// Sets the global value of an option. -/// -/// @param channel_id -/// @param name Option name -/// @param value New option value -/// @param[out] err Error details, if any -void nvim_set_option(uint64_t channel_id, String name, Object value, Error *err) - FUNC_API_SINCE(1) -{ - set_option_to(channel_id, NULL, SREQ_GLOBAL, name, value, err); -} - -/// Gets the global value of an option. -/// -/// @param name Option name -/// @param[out] err Error details, if any -/// @return Option value (global) -Object nvim_get_option(String name, Arena *arena, Error *err) - FUNC_API_SINCE(1) -{ - return get_option_from(NULL, SREQ_GLOBAL, name, err); -} - -/// Gets a buffer option value -/// -/// @param buffer Buffer handle, or 0 for current buffer -/// @param name Option name -/// @param[out] err Error details, if any -/// @return Option value -Object nvim_buf_get_option(Buffer buffer, String name, Arena *arena, Error *err) - FUNC_API_SINCE(1) -{ - buf_T *buf = find_buffer_by_handle(buffer, err); - - if (!buf) { - return (Object)OBJECT_INIT; - } - - return get_option_from(buf, SREQ_BUF, name, err); -} - -/// Sets a buffer option value. Passing `nil` as value deletes the option (only -/// works if there's a global fallback) -/// -/// @param channel_id -/// @param buffer Buffer handle, or 0 for current buffer -/// @param name Option name -/// @param value Option value -/// @param[out] err Error details, if any -void nvim_buf_set_option(uint64_t channel_id, Buffer buffer, String name, Object value, Error *err) - FUNC_API_SINCE(1) -{ - buf_T *buf = find_buffer_by_handle(buffer, err); - - if (!buf) { - return; - } - - set_option_to(channel_id, buf, SREQ_BUF, name, value, err); -} - -/// Gets a window option value -/// -/// @param window Window handle, or 0 for current window -/// @param name Option name -/// @param[out] err Error details, if any -/// @return Option value -Object nvim_win_get_option(Window window, String name, Arena *arena, Error *err) - FUNC_API_SINCE(1) -{ - win_T *win = find_window_by_handle(window, err); - - if (!win) { - return (Object)OBJECT_INIT; - } - - return get_option_from(win, SREQ_WIN, name, err); -} - -/// Sets a window option value. Passing `nil` as value deletes the option (only -/// works if there's a global fallback) -/// -/// @param channel_id -/// @param window Window handle, or 0 for current window -/// @param name Option name -/// @param value Option value -/// @param[out] err Error details, if any -void nvim_win_set_option(uint64_t channel_id, Window window, String name, Object value, Error *err) - FUNC_API_SINCE(1) -{ - win_T *win = find_window_by_handle(window, err); - - if (!win) { - return; - } - - set_option_to(channel_id, win, SREQ_WIN, name, value, err); -} - -/// Gets the value of a global or local (buffer, window) option. -/// -/// @param from If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer -/// to the window or buffer. -/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -/// @return the option value -static Object get_option_from(void *from, int type, String name, Error *err) -{ - Object rv = OBJECT_INIT; - - VALIDATE_S(name.size > 0, "option name", "", { - return rv; - }); - - // Return values - int64_t numval; - char *stringval = NULL; - - int flags = get_option_value_strict(name.data, &numval, &stringval, type, from); - VALIDATE_S(flags != 0, "option name", name.data, { - return rv; - }); - - if (flags & SOPT_BOOL) { - rv.type = kObjectTypeBoolean; - rv.data.boolean = numval ? true : false; - } else if (flags & SOPT_NUM) { - rv.type = kObjectTypeInteger; - rv.data.integer = numval; - } else if (flags & SOPT_STRING) { - if (!stringval) { - api_set_error(err, kErrorTypeException, "Failed to get option '%s'", name.data); - return rv; - } - rv.type = kObjectTypeString; - rv.data.string.data = stringval; - rv.data.string.size = strlen(stringval); - } else { - api_set_error(err, kErrorTypeException, "Unknown type for option '%s'", name.data); - } - - return rv; -} - -/// Sets the value of a global or local (buffer, window) option. -/// -/// @param to If `type` is `SREQ_WIN` or `SREQ_BUF`, this must be a pointer -/// to the window or buffer. -/// @param type One of `SREQ_GLOBAL`, `SREQ_WIN` or `SREQ_BUF` -/// @param name The option name -/// @param[out] err Details of an error that may have occurred -void set_option_to(uint64_t channel_id, void *to, int type, String name, Object value, Error *err) -{ - VALIDATE_S(name.size > 0, "option name", "", { - return; - }); - - int flags = get_option_value_strict(name.data, NULL, NULL, type, to); - VALIDATE_S(flags != 0, "option name", name.data, { - return; - }); - - if (value.type == kObjectTypeNil) { - if (type == SREQ_GLOBAL) { - api_set_error(err, kErrorTypeException, "Cannot unset option '%s'", name.data); - return; - } else if (!(flags & SOPT_GLOBAL)) { - api_set_error(err, kErrorTypeException, - "Cannot unset option '%s' because it doesn't have a global value", - name.data); - return; - } else { - unset_global_local_option(name.data, to); - return; - } - } - - long numval = 0; - char *stringval = NULL; - - if (flags & SOPT_BOOL) { - VALIDATE(value.type == kObjectTypeBoolean, "Option '%s' value must be Boolean", name.data, { - return; - }); - numval = value.data.boolean; - } else if (flags & SOPT_NUM) { - VALIDATE(value.type == kObjectTypeInteger, "Option '%s' value must be Integer", name.data, { - return; - }); - VALIDATE((value.data.integer <= INT_MAX && value.data.integer >= INT_MIN), - "Option '%s' value is out of range", name.data, { - return; - }); - numval = (int)value.data.integer; - } else { - VALIDATE(value.type == kObjectTypeString, "Option '%s' value must be String", name.data, { - return; - }); - stringval = value.data.string.data; - } - - // For global-win-local options -> setlocal - // For win-local options -> setglobal and setlocal (opt_flags == 0) - const int opt_flags = (type == SREQ_WIN && !(flags & SOPT_GLOBAL)) ? 0 : - (type == SREQ_GLOBAL) ? OPT_GLOBAL : OPT_LOCAL; - - WITH_SCRIPT_CONTEXT(channel_id, { - access_option_value_for(name.data, &numval, &stringval, opt_flags, type, to, false, err); - }); -} - static getoption_T access_option_value(char *key, long *numval, char **stringval, int opt_flags, bool get, Error *err) { @@ -571,8 +359,8 @@ static getoption_T access_option_value(char *key, long *numval, char **stringval } } -static getoption_T access_option_value_for(char *key, long *numval, char **stringval, int opt_flags, - int opt_type, void *from, bool get, Error *err) +getoption_T access_option_value_for(char *key, long *numval, char **stringval, int opt_flags, + int opt_type, void *from, bool get, Error *err) { bool need_switch = false; switchwin_T switchwin; -- cgit From cfd4fdfea4d0e68ea50ad412b88b5289ded6fd6f Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Tue, 23 May 2023 14:25:10 +0600 Subject: refactor(api): new helper macros Adds new API helper macros `CSTR_AS_OBJ()`, `STATIC_CSTR_AS_OBJ()`, and `STATIC_CSTR_TO_OBJ()`, which cleans up a lot of the current code. These macros will also be used extensively in the upcoming option refactor PRs because then API Objects will be used to get/set options. This PR also modifies pre-existing code to use old API helper macros like `CSTR_TO_OBJ()` to make them cleaner. --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 6193a5c75b..e18312a6dc 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -188,7 +188,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) switch (result) { case gov_string: - rv = STRING_OBJ(cstr_as_string(stringval)); + rv = CSTR_AS_OBJ(stringval); break; case gov_number: rv = INTEGER_OBJ(numval); -- cgit From b3d5138fd0066fda26ef7724a542ae45eb42fc84 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 7 Jun 2023 06:05:16 +0600 Subject: refactor(options): remove `getoption_T` and introduce `OptVal` (#23850) Removes the `getoption_T` struct and also introduces the `OptVal` struct to unify the methods of getting/setting different option value types. This is the first of many PRs to reduce code duplication in the Vim option code as well as to make options easier to maintain. It also increases the flexibility and extensibility of options. Which opens the door for things like Array and Dictionary options. --- src/nvim/api/options.c | 278 +++++++++++++++++++++++++++++++------------------ 1 file changed, 179 insertions(+), 99 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index e18312a6dc..ed13e51e90 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -113,10 +113,10 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) aucmd_prepbuf(aco, ftbuf); TRY_WRAP(err, { - set_option_value("bufhidden", 0L, "hide", OPT_LOCAL); - set_option_value("buftype", 0L, "nofile", OPT_LOCAL); - set_option_value("swapfile", 0L, NULL, OPT_LOCAL); - set_option_value("modeline", 0L, NULL, OPT_LOCAL); // 'nomodeline' + set_option_value("bufhidden", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value("swapfile", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value("modeline", BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' ftbuf->b_p_ft = xstrdup(filetype); do_filetype_autocmd(ftbuf, false); @@ -125,6 +125,54 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) return ftbuf; } +/// Consume an OptVal and convert it to an API Object. +static Object optval_as_object(OptVal o) +{ + switch (o.type) { + case kOptValTypeNil: + return NIL; + case kOptValTypeBoolean: + switch (o.data.boolean) { + case kFalse: + case kTrue: + return BOOLEAN_OBJ(o.data.boolean); + case kNone: + return NIL; + default: + abort(); + } + case kOptValTypeNumber: + return INTEGER_OBJ(o.data.number); + case kOptValTypeString: + return STRING_OBJ(o.data.string); + default: + abort(); + } +} + +/// Consume an API Object and convert it to an OptVal. +static OptVal object_as_optval(Object o, Error *err) +{ + switch (o.type) { + case kObjectTypeNil: + return NIL_OPTVAL; + break; + case kObjectTypeBoolean: + return BOOLEAN_OPTVAL(o.data.boolean); + break; + case kObjectTypeInteger: + return NUMBER_OPTVAL(o.data.integer); + break; + case kObjectTypeString: + return STRING_OPTVAL(o.data.string); + break; + default: + // Some Object types don't have an OptVal equivalent. Error out in those cases. + api_set_error(err, kErrorTypeException, "Invalid option value"); + return NIL_OPTVAL; + } +} + /// Gets the value of an option. The behavior of this function matches that of /// |:set|: the local value of an option is returned if it exists; otherwise, /// the global value is returned. Local values always correspond to the current @@ -147,6 +195,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) { Object rv = OBJECT_INIT; + OptVal value = NIL_OPTVAL; int scope = 0; int opt_type = SREQ_GLOBAL; @@ -154,14 +203,14 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) char *filetype = NULL; if (!validate_option_value_args(opts, &scope, &opt_type, &from, &filetype, err)) { - return rv; + goto err; } aco_save_T aco; buf_T *ftbuf = do_ft_buf(filetype, &aco, err); if (ERROR_SET(err)) { - return rv; + goto err; } if (ftbuf != NULL) { @@ -169,10 +218,8 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) from = ftbuf; } - long numval = 0; - char *stringval = NULL; - getoption_T result = access_option_value_for(name.data, &numval, &stringval, scope, opt_type, - from, true, err); + bool hidden; + value = get_option_value_for(name.data, NULL, scope, &hidden, opt_type, from, err); if (ftbuf != NULL) { // restore curwin/curbuf and a few other things @@ -183,35 +230,16 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) } if (ERROR_SET(err)) { - return rv; + goto err; } - switch (result) { - case gov_string: - rv = CSTR_AS_OBJ(stringval); - break; - case gov_number: - rv = INTEGER_OBJ(numval); - break; - case gov_bool: - switch (numval) { - case 0: - case 1: - rv = BOOLEAN_OBJ(numval); - break; - default: - // Boolean options that return something other than 0 or 1 should return nil. Currently this - // only applies to 'autoread' which uses -1 as a local value to indicate "unset" - rv = NIL; - break; - } - break; - default: - VALIDATE_S(false, "option", name.data, { - return rv; - }); - } + VALIDATE_S(!hidden && value.type != kOptValTypeNil, "option", name.data, { + goto err; + }); + return optval_as_object(value); +err: + optval_free(value); return rv; } @@ -253,30 +281,19 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( } } - long numval = 0; - char *stringval = NULL; + OptVal optval = object_as_optval(value, err); + + // Handle invalid option value type. + if (ERROR_SET(err)) { + api_clear_error(err); - switch (value.type) { - case kObjectTypeInteger: - numval = (long)value.data.integer; - break; - case kObjectTypeBoolean: - numval = value.data.boolean ? 1 : 0; - break; - case kObjectTypeString: - stringval = value.data.string.data; - break; - case kObjectTypeNil: - scope |= OPT_CLEAR; - break; - default: VALIDATE_EXP(false, name.data, "Integer/Boolean/String", api_typename(value.type), { return; }); } WITH_SCRIPT_CONTEXT(channel_id, { - access_option_value_for(name.data, &numval, &stringval, scope, opt_type, to, false, err); + set_option_value_for(name.data, optval, scope, opt_type, to, err); }); } @@ -341,72 +358,135 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) return get_vimoption(name, scope, buf, win, err); } -static getoption_T access_option_value(char *key, long *numval, char **stringval, int opt_flags, - bool get, Error *err) +/// Switch current context to get/set option value for window/buffer. +/// +/// @param[out] ctx Current context. switchwin_T for window and aco_save_T for buffer. +/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +/// +/// @return true if context was switched, false otherwise. +static bool switch_option_context(void *const ctx, int opt_type, void *const from, Error *err) { - if (get) { - return get_option_value(key, numval, stringval, NULL, opt_flags); - } else { - const char *errmsg; - if ((errmsg = set_option_value(key, *numval, *stringval, opt_flags))) { + switch (opt_type) { + case SREQ_WIN: { + win_T *const win = (win_T *)from; + switchwin_T *const switchwin = (switchwin_T *)ctx; + + if (win == curwin) { + return false; + } + + if (switch_win_noblock(switchwin, win, win_find_tabpage(win), true) + == FAIL) { + restore_win_noblock(switchwin, true); + if (try_end(err)) { - return 0; + return false; } + api_set_error(err, kErrorTypeException, "Problem while switching windows"); + return false; + } + return true; + } + case SREQ_BUF: { + buf_T *const buf = (buf_T *)from; + aco_save_T *const aco = (aco_save_T *)ctx; - api_set_error(err, kErrorTypeException, "%s", errmsg); + if (buf == curbuf) { + return false; } - return 0; + aucmd_prepbuf(aco, buf); + return true; + } + case SREQ_GLOBAL: + return false; + default: + abort(); // This should never happen. } } -getoption_T access_option_value_for(char *key, long *numval, char **stringval, int opt_flags, - int opt_type, void *from, bool get, Error *err) +/// Restore context after getting/setting option for window/buffer. See switch_option_context() for +/// params. +static void restore_option_context(void *const ctx, const int opt_type) { - bool need_switch = false; - switchwin_T switchwin; - aco_save_T aco; - getoption_T result = 0; - - try_start(); switch (opt_type) { case SREQ_WIN: - need_switch = (win_T *)from != curwin; - if (need_switch) { - if (switch_win_noblock(&switchwin, (win_T *)from, win_find_tabpage((win_T *)from), true) - == FAIL) { - restore_win_noblock(&switchwin, true); - if (try_end(err)) { - return result; - } - api_set_error(err, kErrorTypeException, "Problem while switching windows"); - return result; - } - } - result = access_option_value(key, numval, stringval, opt_flags, get, err); - if (need_switch) { - restore_win_noblock(&switchwin, true); - } + restore_win_noblock((switchwin_T *)ctx, true); break; case SREQ_BUF: - need_switch = (buf_T *)from != curbuf; - if (need_switch) { - aucmd_prepbuf(&aco, (buf_T *)from); - } - result = access_option_value(key, numval, stringval, opt_flags, get, err); - if (need_switch) { - aucmd_restbuf(&aco); - } + aucmd_restbuf((aco_save_T *)ctx); break; case SREQ_GLOBAL: - result = access_option_value(key, numval, stringval, opt_flags, get, err); break; + default: + abort(); // This should never happen. + } +} + +/// Get option value for buffer / window. +/// +/// @param[in] name Option name. +/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). +/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). +/// @param[out] hidden Whether option is hidden. +/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +/// +/// @return Option value. Must be freed by caller. +OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, bool *hidden, + const int opt_type, void *const from, Error *err) +{ + switchwin_T switchwin; + aco_save_T aco; + void *ctx = opt_type == SREQ_WIN ? (void *)&switchwin + : (opt_type == SREQ_BUF ? (void *)&aco : NULL); + + bool switched = switch_option_context(ctx, opt_type, from, err); + if (ERROR_SET(err)) { + return NIL_OPTVAL; + } + + OptVal retv = get_option_value(name, flagsp, scope, hidden); + + if (switched) { + restore_option_context(ctx, opt_type); } + return retv; +} + +/// Set option value for buffer / window. +/// +/// @param[in] name Option name. +/// @param[in] value Option value. +/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). +/// If OPT_CLEAR is set, the value of the option +/// is cleared (the exact semantics of this depend +/// on the option). +/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. +void set_option_value_for(const char *const name, OptVal value, const int opt_flags, + const int opt_type, void *const from, Error *err) +{ + switchwin_T switchwin; + aco_save_T aco; + void *ctx = opt_type == SREQ_WIN ? (void *)&switchwin + : (opt_type == SREQ_BUF ? (void *)&aco : NULL); + + bool switched = switch_option_context(ctx, opt_type, from, err); if (ERROR_SET(err)) { - return result; + return; } - try_end(err); + const char *const errmsg = set_option_value(name, value, opt_flags); + if (errmsg) { + api_set_error(err, kErrorTypeException, "%s", errmsg); + } - return result; + if (switched) { + restore_option_context(ctx, opt_type); + } } -- cgit From 0e0a166a0cc5a2dc199136e313e58c27bfb91977 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 7 Jun 2023 09:00:55 +0800 Subject: refactor(api): adjust errors for setting options (#23942) --- src/nvim/api/options.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index ed13e51e90..b9a41adc3b 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -151,24 +151,19 @@ static Object optval_as_object(OptVal o) } /// Consume an API Object and convert it to an OptVal. -static OptVal object_as_optval(Object o, Error *err) +static OptVal object_as_optval(Object o, bool *error) { switch (o.type) { case kObjectTypeNil: return NIL_OPTVAL; - break; case kObjectTypeBoolean: return BOOLEAN_OPTVAL(o.data.boolean); - break; case kObjectTypeInteger: return NUMBER_OPTVAL(o.data.integer); - break; case kObjectTypeString: return STRING_OPTVAL(o.data.string); - break; default: - // Some Object types don't have an OptVal equivalent. Error out in those cases. - api_set_error(err, kErrorTypeException, "Invalid option value"); + *error = true; return NIL_OPTVAL; } } @@ -281,13 +276,13 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( } } - OptVal optval = object_as_optval(value, err); + bool error = false; + OptVal optval = object_as_optval(value, &error); // Handle invalid option value type. - if (ERROR_SET(err)) { - api_clear_error(err); - - VALIDATE_EXP(false, name.data, "Integer/Boolean/String", api_typename(value.type), { + if (error) { + // Don't use `name` in the error message here, because `name` can be any String. + VALIDATE_EXP(false, "value", "Integer/Boolean/String", api_typename(value.type), { return; }); } -- cgit From 24e3ee9d07e1433cb13b4d96ec20999f5f02b204 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Sat, 22 Jul 2023 09:52:13 +0100 Subject: fix(api/options): validate buf and win Fixes #24398 --- src/nvim/api/options.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index b9a41adc3b..858a663b9f 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -23,8 +23,8 @@ # include "api/options.c.generated.h" #endif -static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from, - char **filetype, Error *err) +static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, int *opt_type, + void **from, char **filetype, Error *err) { if (HAS_KEY(opts->scope)) { VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { @@ -92,6 +92,24 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t return FAIL; }); + int flags = get_option_value_strict(name, NULL, NULL, 0, NULL); + if (flags == 0) { + // hidden or unknown option + api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name); + } else if (*opt_type & (SREQ_BUF | SREQ_WIN)) { + // if 'buf' or 'win' is passed, make sure the option supports it + int req_flags = *opt_type & SREQ_BUF ? SOPT_BUF : SOPT_WIN; + if (!(flags & req_flags)) { + char *tgt = *opt_type & SREQ_BUF ? "buf" : "win"; + char *global = flags & SOPT_GLOBAL ? "global ": ""; + char *req = flags & SOPT_BUF ? "buffer-local " : + flags & SOPT_WIN ? "window-local " : ""; + + api_set_error(err, kErrorTypeValidation, "'%s' cannot be passed for %s%soption '%s'", + tgt, global, req, name); + } + } + return OK; } @@ -197,7 +215,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) void *from = NULL; char *filetype = NULL; - if (!validate_option_value_args(opts, &scope, &opt_type, &from, &filetype, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, &filetype, err)) { goto err; } @@ -259,7 +277,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( int scope = 0; int opt_type = SREQ_GLOBAL; void *to = NULL; - if (!validate_option_value_args(opts, &scope, &opt_type, &to, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &to, NULL, err)) { return; } @@ -343,7 +361,7 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) int scope = 0; int opt_type = SREQ_GLOBAL; void *from = NULL; - if (!validate_option_value_args(opts, &scope, &opt_type, &from, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, NULL, err)) { return (Dictionary)ARRAY_DICT_INIT; } -- cgit From d2f81330247ee060d557330b2716ccea8f789a50 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 12 Jul 2023 19:27:14 +0200 Subject: docs: misc Co-authored-by: Kevin Pham --- src/nvim/api/options.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 858a663b9f..3d42f60940 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -315,6 +315,8 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( /// The dictionary has the full option names as keys and option metadata /// dictionaries as detailed at |nvim_get_option_info2()|. /// +/// @see |nvim_get_commands()| +/// /// @return dictionary of all options Dictionary nvim_get_all_options_info(Error *err) FUNC_API_SINCE(7) -- cgit From 7bc93e0e2f246dd78026a3472d929a0fe450f70d Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 1 Aug 2023 14:01:19 +0200 Subject: refactor(api): use typed keysets Initially this is just for geting rid of boilerplate, but eventually the types could get exposed as metadata --- src/nvim/api/options.c | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 3d42f60940..e33cb72e8d 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -8,6 +8,7 @@ #include "nvim/api/options.h" #include "nvim/api/private/defs.h" +#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/autocmd.h" @@ -26,14 +27,11 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, int *opt_type, void **from, char **filetype, Error *err) { - if (HAS_KEY(opts->scope)) { - VALIDATE_T("scope", kObjectTypeString, opts->scope.type, { - return FAIL; - }); - - if (!strcmp(opts->scope.data.string.data, "local")) { +#define HAS_KEY_X(d, v) HAS_KEY(d, option, v) + if (HAS_KEY_X(opts, scope)) { + if (!strcmp(opts->scope.data, "local")) { *scope = OPT_LOCAL; - } else if (!strcmp(opts->scope.data.string.data, "global")) { + } else if (!strcmp(opts->scope.data, "global")) { *scope = OPT_GLOBAL; } else { VALIDATE_EXP(false, "scope", "'local' or 'global'", NULL, { @@ -44,51 +42,40 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope *opt_type = SREQ_GLOBAL; - if (filetype != NULL && HAS_KEY(opts->filetype)) { - VALIDATE_T("scope", kObjectTypeString, opts->filetype.type, { - return FAIL; - }); - - *filetype = opts->filetype.data.string.data; + if (filetype != NULL && HAS_KEY_X(opts, filetype)) { + *filetype = opts->filetype.data; } - if (HAS_KEY(opts->win)) { - VALIDATE_T_HANDLE("win", kObjectTypeWindow, opts->win.type, { - return FAIL; - }); - + if (HAS_KEY_X(opts, win)) { *opt_type = SREQ_WIN; - *from = find_window_by_handle((int)opts->win.data.integer, err); + *from = find_window_by_handle(opts->win, err); if (ERROR_SET(err)) { return FAIL; } } - if (HAS_KEY(opts->buf)) { - VALIDATE_T_HANDLE("buf", kObjectTypeBuffer, opts->buf.type, { - return FAIL; - }); - + if (HAS_KEY_X(opts, buf)) { *scope = OPT_LOCAL; *opt_type = SREQ_BUF; - *from = find_buffer_by_handle((int)opts->buf.data.integer, err); + *from = find_buffer_by_handle(opts->buf, err); if (ERROR_SET(err)) { return FAIL; } } - VALIDATE((!HAS_KEY(opts->filetype) - || !(HAS_KEY(opts->buf) || HAS_KEY(opts->scope) || HAS_KEY(opts->win))), + VALIDATE((!HAS_KEY_X(opts, filetype) + || !(HAS_KEY_X(opts, buf) || HAS_KEY_X(opts, scope) || HAS_KEY_X(opts, win))), "%s", "cannot use 'filetype' with 'scope', 'buf' or 'win'", { return FAIL; }); - VALIDATE((!HAS_KEY(opts->scope) || !HAS_KEY(opts->buf)), "%s", + VALIDATE((!HAS_KEY_X(opts, scope) || !HAS_KEY_X(opts, buf)), "%s", "cannot use both 'scope' and 'buf'", { return FAIL; }); - VALIDATE((!HAS_KEY(opts->win) || !HAS_KEY(opts->buf)), "%s", "cannot use both 'buf' and 'win'", { + VALIDATE((!HAS_KEY_X(opts, win) || !HAS_KEY_X(opts, buf)), + "%s", "cannot use both 'buf' and 'win'", { return FAIL; }); @@ -111,6 +98,7 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope } return OK; +#undef HAS_KEY_X } /// Create a dummy buffer and run the FileType autocmd on it. -- cgit From 6a449a892bdc25f4984b1cd4dcbe4e7157142a46 Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 13 Jul 2023 15:53:07 +0100 Subject: refactor(option): remove OPT_CLEAR --- src/nvim/api/options.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index e33cb72e8d..eb80683365 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -465,9 +465,6 @@ OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, /// @param[in] name Option name. /// @param[in] value Option value. /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). -/// If OPT_CLEAR is set, the value of the option -/// is cleared (the exact semantics of this depend -/// on the option). /// @param[in] opt_type Option type. See SREQ_* in option_defs.h. /// @param[in] from Target buffer/window. /// @param[out] err Error message, if any. -- cgit From af7d317f3ff31d5ac5d8724b5057a422e1451b54 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 26 Sep 2023 22:36:08 +0200 Subject: refactor: remove long long is 32-bits even on 64-bit windows which makes the type suboptimal for a codebase meant to be cross-platform. --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index eb80683365..619e23affb 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -165,7 +165,7 @@ static OptVal object_as_optval(Object o, bool *error) case kObjectTypeBoolean: return BOOLEAN_OPTVAL(o.data.boolean); case kObjectTypeInteger: - return NUMBER_OPTVAL(o.data.integer); + return NUMBER_OPTVAL((OptInt)o.data.integer); case kObjectTypeString: return STRING_OPTVAL(o.data.string); default: -- cgit From cf8b2c0e74fd5e723b0c15c2ce84e6900fd322d3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 30 Sep 2023 12:05:28 +0800 Subject: build(iwyu): add a few more _defs.h mappings (#25435) --- src/nvim/api/options.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 619e23affb..5a75d10043 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -1,22 +1,24 @@ // This is an open source non-commercial project. Dear PVS-Studio, please check // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com +#include #include -#include #include +#include #include +#include "nvim/api/keysets.h" #include "nvim/api/options.h" #include "nvim/api/private/defs.h" -#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/autocmd.h" -#include "nvim/buffer_defs.h" +#include "nvim/buffer.h" #include "nvim/eval/window.h" #include "nvim/globals.h" #include "nvim/memory.h" #include "nvim/option.h" +#include "nvim/types.h" #include "nvim/vim.h" #include "nvim/window.h" -- cgit From 9ff6f73f838a1f90d09922448c434033ba5e094e Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Mon, 9 Oct 2023 00:36:48 +0600 Subject: refactor: allow not having a `default` case for enum Problem: The style guide states that all switch statements that are not conditional on an enum must have a `default` case, but does not give any explicit guideline for switch statements that are conditional on enums. As a result, a `default` case is added in many enum switch statements, even when the switch statement is exhaustive. This is not ideal because it removes the ability to have compiler errors to easily detect unchanged switch statements when a new possible value for an enum is added. Solution: Add explicit guidelines for switch statements that are conditional on an enum, clarifying that a `default` case is not necessary if the switch statement is exhaustive. Also refactor pre-existing code with unnecessary `default` cases. --- src/nvim/api/options.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 5a75d10043..867d1d5e5c 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -146,16 +146,14 @@ static Object optval_as_object(OptVal o) return BOOLEAN_OBJ(o.data.boolean); case kNone: return NIL; - default: - abort(); } + UNREACHABLE; case kOptValTypeNumber: return INTEGER_OBJ(o.data.number); case kOptValTypeString: return STRING_OBJ(o.data.string); - default: - abort(); } + UNREACHABLE; } /// Consume an API Object and convert it to an OptVal. -- cgit From 93b9c889465ee6a55e71c1fd681c1c6b1d5ed060 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 27 Sep 2023 23:30:17 +0600 Subject: refactor(options): unify set_num_option and set_bool_option --- src/nvim/api/options.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 867d1d5e5c..498638d606 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -133,47 +133,6 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) return ftbuf; } -/// Consume an OptVal and convert it to an API Object. -static Object optval_as_object(OptVal o) -{ - switch (o.type) { - case kOptValTypeNil: - return NIL; - case kOptValTypeBoolean: - switch (o.data.boolean) { - case kFalse: - case kTrue: - return BOOLEAN_OBJ(o.data.boolean); - case kNone: - return NIL; - } - UNREACHABLE; - case kOptValTypeNumber: - return INTEGER_OBJ(o.data.number); - case kOptValTypeString: - return STRING_OBJ(o.data.string); - } - UNREACHABLE; -} - -/// Consume an API Object and convert it to an OptVal. -static OptVal object_as_optval(Object o, bool *error) -{ - switch (o.type) { - case kObjectTypeNil: - return NIL_OPTVAL; - case kObjectTypeBoolean: - return BOOLEAN_OPTVAL(o.data.boolean); - case kObjectTypeInteger: - return NUMBER_OPTVAL((OptInt)o.data.integer); - case kObjectTypeString: - return STRING_OPTVAL(o.data.string); - default: - *error = true; - return NIL_OPTVAL; - } -} - /// Gets the value of an option. The behavior of this function matches that of /// |:set|: the local value of an option is returned if it exists; otherwise, /// the global value is returned. Local values always correspond to the current -- cgit From 6c87d3e0fbf88ae693be11a3ede3a1ec6ec0e30e Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 19 Oct 2023 20:09:02 +0600 Subject: refactor(options): `get_option_value_strict()` and `SREQ_*` `SREQ_*` values are now actual typedef'd enums. `get_option_value_strict()` has also been refactored and split into two functions, `get_option_attrs()` for getting the option attributes, and `get_option_value_strict()` for getting the actual value. Moreover, it now returns an `OptVal`. Other miscellaneous refactors have also been made. --- src/nvim/api/options.c | 264 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 196 insertions(+), 68 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 498638d606..5b1f61b9f6 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -26,8 +26,9 @@ # include "api/options.c.generated.h" #endif -static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, int *opt_type, - void **from, char **filetype, Error *err) +static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, + OptReqScope *req_scope, void **from, char **filetype, + Error *err) { #define HAS_KEY_X(d, v) HAS_KEY(d, option, v) if (HAS_KEY_X(opts, scope)) { @@ -42,14 +43,14 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope } } - *opt_type = SREQ_GLOBAL; + *req_scope = kOptReqGlobal; if (filetype != NULL && HAS_KEY_X(opts, filetype)) { *filetype = opts->filetype.data; } if (HAS_KEY_X(opts, win)) { - *opt_type = SREQ_WIN; + *req_scope = kOptReqWin; *from = find_window_by_handle(opts->win, err); if (ERROR_SET(err)) { return FAIL; @@ -58,7 +59,7 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope if (HAS_KEY_X(opts, buf)) { *scope = OPT_LOCAL; - *opt_type = SREQ_BUF; + *req_scope = kOptReqBuf; *from = find_buffer_by_handle(opts->buf, err); if (ERROR_SET(err)) { return FAIL; @@ -81,15 +82,15 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope return FAIL; }); - int flags = get_option_value_strict(name, NULL, NULL, 0, NULL); + int flags = get_option_attrs(name); if (flags == 0) { // hidden or unknown option api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name); - } else if (*opt_type & (SREQ_BUF | SREQ_WIN)) { + } else if (*req_scope == kOptReqBuf || *req_scope == kOptReqWin) { // if 'buf' or 'win' is passed, make sure the option supports it - int req_flags = *opt_type & SREQ_BUF ? SOPT_BUF : SOPT_WIN; + int req_flags = *req_scope == kOptReqBuf ? SOPT_BUF : SOPT_WIN; if (!(flags & req_flags)) { - char *tgt = *opt_type & SREQ_BUF ? "buf" : "win"; + char *tgt = *req_scope & kOptReqBuf ? "buf" : "win"; char *global = flags & SOPT_GLOBAL ? "global ": ""; char *req = flags & SOPT_BUF ? "buffer-local " : flags & SOPT_WIN ? "window-local " : ""; @@ -158,11 +159,11 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) OptVal value = NIL_OPTVAL; int scope = 0; - int opt_type = SREQ_GLOBAL; + OptReqScope req_scope = kOptReqGlobal; void *from = NULL; char *filetype = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, &filetype, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, &filetype, err)) { goto err; } @@ -179,7 +180,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) } bool hidden; - value = get_option_value_for(name.data, NULL, scope, &hidden, opt_type, from, err); + value = get_option_value_for(name.data, NULL, scope, &hidden, req_scope, from, err); if (ftbuf != NULL) { // restore curwin/curbuf and a few other things @@ -222,9 +223,9 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( FUNC_API_SINCE(9) { int scope = 0; - int opt_type = SREQ_GLOBAL; + OptReqScope req_scope = kOptReqGlobal; void *to = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &to, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &to, NULL, err)) { return; } @@ -234,8 +235,8 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( // - option is global or local to window (global-local) // // Then force scope to local since we don't want to change the global option - if (opt_type == SREQ_WIN && scope == 0) { - int flags = get_option_value_strict(name.data, NULL, NULL, opt_type, to); + if (req_scope == kOptReqWin && scope == 0) { + int flags = get_option_attrs(name.data); if (flags & SOPT_GLOBAL) { scope = OPT_LOCAL; } @@ -245,15 +246,15 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( OptVal optval = object_as_optval(value, &error); // Handle invalid option value type. - if (error) { - // Don't use `name` in the error message here, because `name` can be any String. - VALIDATE_EXP(false, "value", "Integer/Boolean/String", api_typename(value.type), { - return; - }); - } + // Don't use `name` in the error message here, because `name` can be any String. + // No need to check if value type actually matches the types for the option, as set_option_value() + // already handles that. + VALIDATE_EXP(!error, "value", "valid option type", api_typename(value.type), { + return; + }); WITH_SCRIPT_CONTEXT(channel_id, { - set_option_value_for(name.data, optval, scope, opt_type, to, err); + set_option_value_for(name.data, optval, scope, req_scope, to, err); }); } @@ -308,30 +309,31 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(11) { int scope = 0; - int opt_type = SREQ_GLOBAL; + OptReqScope req_scope = kOptReqGlobal; void *from = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, NULL, err)) { return (Dictionary)ARRAY_DICT_INIT; } - buf_T *buf = (opt_type == SREQ_BUF) ? (buf_T *)from : curbuf; - win_T *win = (opt_type == SREQ_WIN) ? (win_T *)from : curwin; + buf_T *buf = (req_scope == kOptReqBuf) ? (buf_T *)from : curbuf; + win_T *win = (req_scope == kOptReqWin) ? (win_T *)from : curwin; return get_vimoption(name, scope, buf, win, err); } /// Switch current context to get/set option value for window/buffer. /// -/// @param[out] ctx Current context. switchwin_T for window and aco_save_T for buffer. -/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. +/// @param[out] ctx Current context. switchwin_T for window and aco_save_T for buffer. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. /// /// @return true if context was switched, false otherwise. -static bool switch_option_context(void *const ctx, int opt_type, void *const from, Error *err) +static bool switch_option_context(void *const ctx, OptReqScope req_scope, void *const from, + Error *err) { - switch (opt_type) { - case SREQ_WIN: { + switch (req_scope) { + case kOptReqWin: { win_T *const win = (win_T *)from; switchwin_T *const switchwin = (switchwin_T *)ctx; @@ -351,7 +353,7 @@ static bool switch_option_context(void *const ctx, int opt_type, void *const fro } return true; } - case SREQ_BUF: { + case kOptReqBuf: { buf_T *const buf = (buf_T *)from; aco_save_T *const aco = (aco_save_T *)ctx; @@ -361,51 +363,177 @@ static bool switch_option_context(void *const ctx, int opt_type, void *const fro aucmd_prepbuf(aco, buf); return true; } - case SREQ_GLOBAL: + case kOptReqGlobal: return false; - default: - abort(); // This should never happen. } + UNREACHABLE; } /// Restore context after getting/setting option for window/buffer. See switch_option_context() for /// params. -static void restore_option_context(void *const ctx, const int opt_type) +static void restore_option_context(void *const ctx, OptReqScope req_scope) { - switch (opt_type) { - case SREQ_WIN: + switch (req_scope) { + case kOptReqWin: restore_win_noblock((switchwin_T *)ctx, true); break; - case SREQ_BUF: + case kOptReqBuf: aucmd_restbuf((aco_save_T *)ctx); break; - case SREQ_GLOBAL: + case kOptReqGlobal: break; - default: - abort(); // This should never happen. } } +/// Get attributes for an option. +/// +/// @param name Option name. +/// +/// @return Option attributes. +/// 0 for hidden or unknown option. +/// See SOPT_* in option_defs.h for other flags. +int get_option_attrs(char *name) +{ + int opt_idx = findoption(name); + + if (opt_idx < 0) { + return 0; + } + + vimoption_T *opt = get_option(opt_idx); + + if (is_tty_option(opt->fullname)) { + return SOPT_STRING | SOPT_GLOBAL; + } + + // Hidden option + if (opt->var == NULL) { + return 0; + } + + int attrs = 0; + + if (opt->flags & P_BOOL) { + attrs |= SOPT_BOOL; + } else if (opt->flags & P_NUM) { + attrs |= SOPT_NUM; + } else if (opt->flags & P_STRING) { + attrs |= SOPT_STRING; + } + + if (opt->indir == PV_NONE || (opt->indir & PV_BOTH)) { + attrs |= SOPT_GLOBAL; + } + if (opt->indir & PV_WIN) { + attrs |= SOPT_WIN; + } else if (opt->indir & PV_BUF) { + attrs |= SOPT_BUF; + } + + return attrs; +} + +/// Check if option has a value in the requested scope. +/// +/// @param name Option name. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// +/// @return true if option has a value in the requested scope, false otherwise. +static bool option_has_scope(char *name, OptReqScope req_scope) +{ + int opt_idx = findoption(name); + + if (opt_idx < 0) { + return false; + } + + vimoption_T *opt = get_option(opt_idx); + + // Hidden option. + if (opt->var == NULL) { + return false; + } + // TTY option. + if (is_tty_option(opt->fullname)) { + return req_scope == kOptReqGlobal; + } + + switch (req_scope) { + case kOptReqGlobal: + return opt->var != VAR_WIN; + case kOptReqBuf: + return opt->indir & PV_BUF; + case kOptReqWin: + return opt->indir & PV_WIN; + } + UNREACHABLE; +} + +/// Get the option value in the requested scope. +/// +/// @param name Option name. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Pointer to buffer or window for local option value. +/// @param[out] err Error message, if any. +/// +/// @return Option value in the requested scope. Returns a Nil option value if option is not found, +/// hidden or if it isn't present in the requested scope. (i.e. has no global, window-local or +/// buffer-local value depending on opt_scope). +OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Error *err) +{ + OptVal retv = NIL_OPTVAL; + + if (!option_has_scope(name, req_scope)) { + return retv; + } + if (get_tty_option(name, &retv.data.string.data)) { + retv.type = kOptValTypeString; + return retv; + } + + int opt_idx = findoption(name); + assert(opt_idx != 0); // option_has_scope() already verifies if option name is valid. + + vimoption_T *opt = get_option(opt_idx); + switchwin_T switchwin; + aco_save_T aco; + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); + bool switched = switch_option_context(ctx, req_scope, from, err); + if (ERROR_SET(err)) { + return retv; + } + + char *varp = get_varp_scope(opt, req_scope == kOptReqGlobal ? OPT_GLOBAL : OPT_LOCAL); + retv = optval_from_varp(opt_idx, varp); + + if (switched) { + restore_option_context(ctx, req_scope); + } + + return retv; +} + /// Get option value for buffer / window. /// -/// @param[in] name Option name. -/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). -/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). -/// @param[out] hidden Whether option is hidden. -/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. +/// @param[in] name Option name. +/// @param[out] flagsp Set to the option flags (P_xxxx) (if not NULL). +/// @param[in] scope Option scope (can be OPT_LOCAL, OPT_GLOBAL or a combination). +/// @param[out] hidden Whether option is hidden. +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. /// /// @return Option value. Must be freed by caller. OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, bool *hidden, - const int opt_type, void *const from, Error *err) + const OptReqScope req_scope, void *const from, Error *err) { switchwin_T switchwin; aco_save_T aco; - void *ctx = opt_type == SREQ_WIN ? (void *)&switchwin - : (opt_type == SREQ_BUF ? (void *)&aco : NULL); + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); - bool switched = switch_option_context(ctx, opt_type, from, err); + bool switched = switch_option_context(ctx, req_scope, from, err); if (ERROR_SET(err)) { return NIL_OPTVAL; } @@ -413,7 +541,7 @@ OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, OptVal retv = get_option_value(name, flagsp, scope, hidden); if (switched) { - restore_option_context(ctx, opt_type); + restore_option_context(ctx, req_scope); } return retv; @@ -421,21 +549,21 @@ OptVal get_option_value_for(const char *const name, uint32_t *flagsp, int scope, /// Set option value for buffer / window. /// -/// @param[in] name Option name. -/// @param[in] value Option value. -/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). -/// @param[in] opt_type Option type. See SREQ_* in option_defs.h. -/// @param[in] from Target buffer/window. -/// @param[out] err Error message, if any. +/// @param[in] name Option name. +/// @param[in] value Option value. +/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). +/// @param req_scope Requested option scope. See OptReqScope in option.h. +/// @param[in] from Target buffer/window. +/// @param[out] err Error message, if any. void set_option_value_for(const char *const name, OptVal value, const int opt_flags, - const int opt_type, void *const from, Error *err) + const OptReqScope req_scope, void *const from, Error *err) { switchwin_T switchwin; aco_save_T aco; - void *ctx = opt_type == SREQ_WIN ? (void *)&switchwin - : (opt_type == SREQ_BUF ? (void *)&aco : NULL); + void *ctx = req_scope == kOptReqWin ? (void *)&switchwin + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); - bool switched = switch_option_context(ctx, opt_type, from, err); + bool switched = switch_option_context(ctx, req_scope, from, err); if (ERROR_SET(err)) { return; } @@ -446,6 +574,6 @@ void set_option_value_for(const char *const name, OptVal value, const int opt_fl } if (switched) { - restore_option_context(ctx, opt_type); + restore_option_context(ctx, req_scope); } } -- cgit From 353a4be7e84fdc101318215bdcc8a7e780d737fe Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sun, 12 Nov 2023 13:13:58 +0100 Subject: build: remove PVS We already have an extensive suite of static analysis tools we use, which causes a fair bit of redundancy as we get duplicate warnings. PVS is also prone to give false warnings which creates a lot of work to identify and disable. --- src/nvim/api/options.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 5b1f61b9f6..61debb70fe 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -1,6 +1,3 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - #include #include #include -- cgit From bb4b4576e384c71890b4df4fa4f1ae76fad3a59d Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 16 Nov 2023 10:55:54 +0800 Subject: refactor: iwyu (#26062) --- src/nvim/api/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 61debb70fe..b0053dbb34 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "nvim/api/keysets.h" @@ -13,9 +12,10 @@ #include "nvim/buffer.h" #include "nvim/eval/window.h" #include "nvim/globals.h" +#include "nvim/macros.h" #include "nvim/memory.h" #include "nvim/option.h" -#include "nvim/types.h" +#include "nvim/option_vars.h" #include "nvim/vim.h" #include "nvim/window.h" -- cgit From a6e3d93421ba13c407a96fac9cc01fa41ec7ad98 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 16 Nov 2023 10:59:11 +0100 Subject: refactor: enable formatting for ternaries This requires removing the "Inner expression should be aligned" rule from clint as it prevents essentially any formatting regarding ternary operators. --- src/nvim/api/options.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index b0053dbb34..f1aa69f48b 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -88,9 +88,9 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope int req_flags = *req_scope == kOptReqBuf ? SOPT_BUF : SOPT_WIN; if (!(flags & req_flags)) { char *tgt = *req_scope & kOptReqBuf ? "buf" : "win"; - char *global = flags & SOPT_GLOBAL ? "global ": ""; - char *req = flags & SOPT_BUF ? "buffer-local " : - flags & SOPT_WIN ? "window-local " : ""; + char *global = flags & SOPT_GLOBAL ? "global " : ""; + char *req = flags & SOPT_BUF ? "buffer-local " + : flags & SOPT_WIN ? "window-local " : ""; api_set_error(err, kErrorTypeValidation, "'%s' cannot be passed for %s%soption '%s'", tgt, global, req, name); @@ -495,7 +495,7 @@ OptVal get_option_value_strict(char *name, OptReqScope req_scope, void *from, Er switchwin_T switchwin; aco_save_T aco; void *ctx = req_scope == kOptReqWin ? (void *)&switchwin - : (req_scope == kOptReqBuf ? (void *)&aco : NULL); + : (req_scope == kOptReqBuf ? (void *)&aco : NULL); bool switched = switch_option_context(ctx, req_scope, from, err); if (ERROR_SET(err)) { return retv; -- cgit From 574d25642fc9ca65b396633aeab6e2d32778b642 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 27 Nov 2023 17:21:58 +0800 Subject: refactor: move Arena and ArenaMem to memory_defs.h (#26240) --- src/nvim/api/options.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index f1aa69f48b..4cd5359cab 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -1,5 +1,4 @@ #include -#include #include #include -- cgit From 8b428ca8b79ebb7b36c3e403ff3bcb6924a635a6 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 16:00:21 +0100 Subject: build(IWYU): fix includes for func_attr.h --- src/nvim/api/options.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 4cd5359cab..f151a635ab 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -10,6 +10,7 @@ #include "nvim/autocmd.h" #include "nvim/buffer.h" #include "nvim/eval/window.h" +#include "nvim/func_attr.h" #include "nvim/globals.h" #include "nvim/macros.h" #include "nvim/memory.h" -- cgit From e38a05369293293b5b510b1b0014fcc2e7cb87f4 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 18:46:03 +0100 Subject: build(IWYU): export generated headers --- src/nvim/api/options.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index f151a635ab..6b9d3d1130 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -5,6 +5,7 @@ #include "nvim/api/keysets.h" #include "nvim/api/options.h" #include "nvim/api/private/defs.h" +#include "nvim/api/private/dispatch.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/validate.h" #include "nvim/autocmd.h" -- cgit From e3f735ef101d670555f44226614a5c3557053b1f Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 27 Nov 2023 20:13:32 +0100 Subject: refactor: fix includes for api/autocmd.h --- src/nvim/api/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 6b9d3d1130..d08a44b0ad 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -2,7 +2,7 @@ #include #include -#include "nvim/api/keysets.h" +#include "nvim/api/keysets_defs.h" #include "nvim/api/options.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/dispatch.h" -- cgit From 79b6ff28ad1204fbb4199b9092f5c578d88cb28e Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 28 Nov 2023 20:31:00 +0100 Subject: refactor: fix headers with IWYU --- src/nvim/api/options.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/api/options.c') diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index d08a44b0ad..c012a69c7b 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -13,11 +13,11 @@ #include "nvim/eval/window.h" #include "nvim/func_attr.h" #include "nvim/globals.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/memory.h" #include "nvim/option.h" #include "nvim/option_vars.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -- cgit