diff options
author | Famiu Haque <famiuhaque@proton.me> | 2023-12-07 23:46:57 +0600 |
---|---|---|
committer | Famiu Haque <famiuhaque@proton.me> | 2023-12-09 17:54:43 +0600 |
commit | 6346987601a28b00564295ee8be0a8b00d9ff911 (patch) | |
tree | b50f5f4f41a7262434d1c223c97e309eea243ff1 /src/nvim/api/options.c | |
parent | 29aa4dd10af74d29891cb293dc9ff393e9dba11f (diff) | |
download | rneovim-6346987601a28b00564295ee8be0a8b00d9ff911.tar.gz rneovim-6346987601a28b00564295ee8be0a8b00d9ff911.tar.bz2 rneovim-6346987601a28b00564295ee8be0a8b00d9ff911.zip |
refactor(options): reduce `findoption()` usage
Problem: Many places in the code use `findoption()` to access an option using its name, even if the option index is available. This is very slow because it requires looping through the options array over and over.
Solution: Use option index instead of name wherever possible. Also introduce an `OptIndex` enum which contains the index for every option as enum constants, this eliminates the need to pass static option names as strings.
Diffstat (limited to 'src/nvim/api/options.c')
-rw-r--r-- | src/nvim/api/options.c | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c index 53fd8af8b5..0d18c7871c 100644 --- a/src/nvim/api/options.c +++ b/src/nvim/api/options.c @@ -23,7 +23,7 @@ # include "api/options.c.generated.h" #endif -static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, +static int validate_option_value_args(Dict(option) *opts, char *name, int *opt_idx, int *scope, OptReqScope *req_scope, void **from, char **filetype, Error *err) { @@ -79,7 +79,8 @@ static int validate_option_value_args(Dict(option) *opts, char *name, int *scope return FAIL; }); - int flags = get_option_attrs(name); + *opt_idx = findoption(name); + int flags = get_option_attrs(*opt_idx); if (flags == 0) { // hidden or unknown option api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name); @@ -119,10 +120,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", 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' + set_option_value(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptModeline, BOOLEAN_OPTVAL(false), OPT_LOCAL); // 'nomodeline' ftbuf->b_p_ft = xstrdup(filetype); do_filetype_autocmd(ftbuf, false); @@ -152,12 +153,14 @@ static buf_T *do_ft_buf(char *filetype, aco_save_T *aco, Error *err) Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(9) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; char *filetype = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, &filetype, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &from, &filetype, + err)) { return (Object)OBJECT_INIT; } @@ -173,7 +176,6 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err) from = ftbuf; } - int opt_idx = findoption(name.data); OptVal value = get_option_value_for(opt_idx, scope, req_scope, from, err); bool hidden = is_option_hidden(opt_idx); @@ -217,10 +219,11 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( Error *err) FUNC_API_SINCE(9) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *to = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &to, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &to, NULL, err)) { return; } @@ -231,7 +234,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( // // Then force scope to local since we don't want to change the global option if (req_scope == kOptReqWin && scope == 0) { - int flags = get_option_attrs(name.data); + int flags = get_option_attrs(opt_idx); if (flags & SOPT_GLOBAL) { scope = OPT_LOCAL; } @@ -249,7 +252,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict( }); WITH_SCRIPT_CONTEXT(channel_id, { - set_option_value_for(name.data, optval, scope, req_scope, to, err); + set_option_value_for(name.data, opt_idx, optval, scope, req_scope, to, err); }); } @@ -303,10 +306,12 @@ Dictionary nvim_get_all_options_info(Error *err) Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err) FUNC_API_SINCE(11) { + int opt_idx = 0; int scope = 0; OptReqScope req_scope = kOptReqGlobal; void *from = NULL; - if (!validate_option_value_args(opts, name.data, &scope, &req_scope, &from, NULL, err)) { + if (!validate_option_value_args(opts, name.data, &opt_idx, &scope, &req_scope, &from, NULL, + err)) { return (Dictionary)ARRAY_DICT_INIT; } @@ -382,19 +387,13 @@ static void restore_option_context(void *const ctx, OptReqScope req_scope) /// Get attributes for an option. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// /// @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 get_option_attrs(int opt_idx) { - if (is_tty_option(name)) { - return SOPT_GLOBAL; - } - - int opt_idx = findoption(name); - if (opt_idx < 0) { return 0; } @@ -422,14 +421,12 @@ int get_option_attrs(char *name) /// Check if option has a value in the requested scope. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @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) +static bool option_has_scope(int opt_idx, OptReqScope req_scope) { - int opt_idx = findoption(name); - if (opt_idx < 0) { return false; } @@ -458,7 +455,7 @@ static bool option_has_scope(char *name, OptReqScope req_scope) /// Get the option value in the requested scope. /// -/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @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. @@ -466,17 +463,11 @@ static bool option_has_scope(char *name, OptReqScope req_scope) /// @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 get_option_value_strict(int opt_idx, OptReqScope req_scope, void *from, Error *err) { - if (!option_has_scope(name, req_scope)) { + if (opt_idx < 0 || !option_has_scope(opt_idx, req_scope)) { return NIL_OPTVAL; } - if (is_tty_option(name)) { - return get_tty_option(name); - } - - 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; @@ -533,14 +524,16 @@ OptVal get_option_value_for(int opt_idx, int scope, const OptReqScope req_scope, /// Set option value for buffer / window. /// -/// @param[in] name Option name. +/// @param name Option name. +/// @param opt_idx Option index in options[] table. /// @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, +void set_option_value_for(const char *name, int opt_idx, OptVal value, const int opt_flags, const OptReqScope req_scope, void *const from, Error *err) + FUNC_ATTR_NONNULL_ARG(1) { switchwin_T switchwin; aco_save_T aco; @@ -552,7 +545,7 @@ void set_option_value_for(const char *const name, OptVal value, const int opt_fl return; } - const char *const errmsg = set_option_value(name, value, opt_flags); + const char *const errmsg = set_option_value_handle_tty(name, opt_idx, value, opt_flags); if (errmsg) { api_set_error(err, kErrorTypeException, "%s", errmsg); } |