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 | |
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')
37 files changed, 330 insertions, 346 deletions
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 0cdce539eb..95ea55f36d 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -332,6 +332,7 @@ set(GENERATED_KEYSETS_DEFS ${GENERATED_DIR}/keysets_defs.generated.h) set(GENERATED_EVENTS_ENUM ${GENERATED_INCLUDES_DIR}/auevents_enum.generated.h) set(GENERATED_EVENTS_NAMES_MAP ${GENERATED_DIR}/auevents_name_map.generated.h) set(GENERATED_OPTIONS ${GENERATED_DIR}/options.generated.h) +set(GENERATED_OPTIONS_ENUM ${GENERATED_DIR}/options_enum.generated.h) set(EX_CMDS_GENERATOR ${GENERATOR_DIR}/gen_ex_cmds.lua) set(FUNCS_GENERATOR ${GENERATOR_DIR}/gen_eval.lua) set(EVENTS_GENERATOR ${GENERATOR_DIR}/gen_events.lua) @@ -676,8 +677,8 @@ add_custom_command(OUTPUT ${GENERATED_EVENTS_ENUM} ${GENERATED_EVENTS_NAMES_MAP} DEPENDS ${LUA_GEN_DEPS} ${EVENTS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/auevents.lua ) -add_custom_command(OUTPUT ${GENERATED_OPTIONS} - COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} +add_custom_command(OUTPUT ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} + COMMAND ${LUA_GEN} ${OPTIONS_GENERATOR} ${GENERATED_OPTIONS} ${GENERATED_OPTIONS_ENUM} DEPENDS ${LUA_GEN_DEPS} ${OPTIONS_GENERATOR} ${CMAKE_CURRENT_LIST_DIR}/options.lua ) diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index d6a76617a7..34bf029483 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -643,7 +643,7 @@ static Object get_option_from(void *from, OptReqScope req_scope, String name, Er return (Object)OBJECT_INIT; }); - OptVal value = get_option_value_strict(name.data, req_scope, from, err); + OptVal value = get_option_value_strict(findoption(name.data), req_scope, from, err); if (ERROR_SET(err)) { return (Object)OBJECT_INIT; } @@ -669,8 +669,8 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); - int flags = get_option_attrs(name.data); - VALIDATE_S(flags != 0, "option name", name.data, { + int opt_idx = findoption(name.data); + VALIDATE_S(opt_idx >= 0, "option name", name.data, { return; }); @@ -685,13 +685,14 @@ static void set_option_to(uint64_t channel_id, void *to, OptReqScope req_scope, return; }); + int attrs = get_option_attrs(opt_idx); // For global-win-local options -> setlocal // For win-local options -> setglobal and setlocal (opt_flags == 0) - const int opt_flags = (req_scope == kOptReqWin && !(flags & SOPT_GLOBAL)) + const int opt_flags = (req_scope == kOptReqWin && !(attrs & SOPT_GLOBAL)) ? 0 : (req_scope == kOptReqGlobal) ? OPT_GLOBAL : OPT_LOCAL; WITH_SCRIPT_CONTEXT(channel_id, { - set_option_value_for(name.data, optval, opt_flags, req_scope, to, err); + set_option_value_for(name.data, opt_idx, optval, opt_flags, req_scope, to, err); }); } 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); } diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 2c937113e3..a52d7493e3 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -948,8 +948,8 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err) buf_copy_options(buf, BCO_ENTER | BCO_NOHELP); if (scratch) { - set_string_option_direct_in_buf(buf, "bufhidden", -1, "hide", OPT_LOCAL, 0); - set_string_option_direct_in_buf(buf, "buftype", -1, "nofile", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBufhidden, "hide", OPT_LOCAL, 0); + set_string_option_direct_in_buf(buf, kOptBuftype, "nofile", OPT_LOCAL, 0); assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already buf->b_p_swf = false; buf->b_p_ml = false; @@ -2239,7 +2239,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error * buf, sizeof(buf), str.data, - NULL, + -1, 0, fillchar, maxwidth, diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c index 46a08c5706..72b0852d8d 100644 --- a/src/nvim/autocmd.c +++ b/src/nvim/autocmd.c @@ -704,7 +704,7 @@ char *au_event_disable(char *what) } else { STRCAT(new_ei, what); } - set_string_option_direct("ei", -1, new_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, new_ei, OPT_FREE, SID_NONE); xfree(new_ei); return save_ei; } @@ -712,7 +712,7 @@ char *au_event_disable(char *what) void au_event_restore(char *old_ei) { if (old_ei != NULL) { - set_string_option_direct("ei", -1, old_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, old_ei, OPT_FREE, SID_NONE); xfree(old_ei); } } diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index b5fac15af6..0392ff6ebd 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -3281,7 +3281,7 @@ void maketitle(void) if (*p_titlestring != NUL) { if (stl_syntax & STL_IN_TITLE) { build_stl_str_hl(curwin, buf, sizeof(buf), p_titlestring, - "titlestring", 0, 0, maxlen, NULL, NULL, NULL); + kOptTitlestring, 0, 0, maxlen, NULL, NULL, NULL); title_str = buf; } else { title_str = p_titlestring; @@ -3386,7 +3386,7 @@ void maketitle(void) if (*p_iconstring != NUL) { if (stl_syntax & STL_IN_ICON) { build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, - "iconstring", 0, 0, 0, NULL, NULL, NULL); + kOptIconstring, 0, 0, 0, NULL, NULL, NULL); } else { icon_str = p_iconstring; } @@ -4147,9 +4147,9 @@ int buf_open_scratch(handle_T bufnr, char *bufname) apply_autocmds(EVENT_BUFFILEPRE, NULL, NULL, false, curbuf); (void)setfname(curbuf, bufname, NULL, true); apply_autocmds(EVENT_BUFFILEPOST, NULL, NULL, false, curbuf); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); RESET_BINDING(curwin); return OK; } diff --git a/src/nvim/context.c b/src/nvim/context.c index 63c0f8c20c..dfb214d065 100644 --- a/src/nvim/context.c +++ b/src/nvim/context.c @@ -138,8 +138,8 @@ bool ctx_restore(Context *ctx, const int flags) free_ctx = true; } - OptVal op_shada = get_option_value(findoption("shada"), OPT_GLOBAL); - set_option_value("shada", STATIC_CSTR_AS_OPTVAL("!,'100,%"), OPT_GLOBAL); + OptVal op_shada = get_option_value(kOptShada, OPT_GLOBAL); + set_option_value(kOptShada, STATIC_CSTR_AS_OPTVAL("!,'100,%"), OPT_GLOBAL); if (flags & kCtxRegs) { ctx_restore_regs(ctx); @@ -165,7 +165,7 @@ bool ctx_restore(Context *ctx, const int flags) ctx_free(ctx); } - set_option_value("shada", op_shada, OPT_GLOBAL); + set_option_value(kOptShada, op_shada, OPT_GLOBAL); optval_free(op_shada); return true; diff --git a/src/nvim/diff.c b/src/nvim/diff.c index 6578a1121c..483182dc25 100644 --- a/src/nvim/diff.c +++ b/src/nvim/diff.c @@ -1389,7 +1389,7 @@ static void set_diff_option(win_T *wp, bool value) curwin = wp; curbuf = curwin->w_buffer; curbuf->b_ro_locked++; - set_option_value_give_err("diff", BOOLEAN_OPTVAL(value), OPT_LOCAL); + set_option_value_give_err(kOptDiff, BOOLEAN_OPTVAL(value), OPT_LOCAL); curbuf->b_ro_locked--; curwin = old_curwin; curbuf = curwin->w_buffer; @@ -1430,7 +1430,7 @@ void diff_win_options(win_T *wp, int addbuf) } wp->w_p_fdm_save = xstrdup(wp->w_p_fdm); } - set_string_option_direct_in_win(wp, "fdm", -1, "diff", OPT_LOCAL | OPT_FREE, 0); + set_string_option_direct_in_win(wp, kOptFoldmethod, "diff", OPT_LOCAL | OPT_FREE, 0); if (!wp->w_p_diff) { wp->w_p_fen_save = wp->w_p_fen; diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 2bbc8b58e7..1c30075991 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -681,7 +681,7 @@ int eval_charconvert(const char *const enc_from, const char *const enc_to, set_vim_var_string(VV_CC_TO, enc_to, -1); set_vim_var_string(VV_FNAME_IN, fname_from, -1); set_vim_var_string(VV_FNAME_OUT, fname_to, -1); - sctx_T *ctx = get_option_sctx("charconvert"); + sctx_T *ctx = get_option_sctx(kOptCharconvert); if (ctx != NULL) { current_sctx = *ctx; } @@ -710,7 +710,7 @@ void eval_diff(const char *const origfile, const char *const newfile, const char set_vim_var_string(VV_FNAME_NEW, newfile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - sctx_T *ctx = get_option_sctx("diffexpr"); + sctx_T *ctx = get_option_sctx(kOptDiffexpr); if (ctx != NULL) { current_sctx = *ctx; } @@ -732,7 +732,7 @@ void eval_patch(const char *const origfile, const char *const difffile, const ch set_vim_var_string(VV_FNAME_DIFF, difffile, -1); set_vim_var_string(VV_FNAME_OUT, outfile, -1); - sctx_T *ctx = get_option_sctx("patchexpr"); + sctx_T *ctx = get_option_sctx(kOptPatchexpr); if (ctx != NULL) { current_sctx = *ctx; } @@ -1134,7 +1134,7 @@ list_T *eval_spell_expr(char *badword, char *expr) if (p_verbose == 0) { emsg_off++; } - sctx_T *ctx = get_option_sctx("spellsuggest"); + sctx_T *ctx = get_option_sctx(kOptSpellsuggest); if (ctx != NULL) { current_sctx = *ctx; } @@ -1278,7 +1278,7 @@ void *call_func_retlist(const char *func, int argc, typval_T *argv) int eval_foldexpr(win_T *wp, int *cp) { const sctx_T saved_sctx = current_sctx; - const bool use_sandbox = was_set_insecurely(wp, "foldexpr", OPT_LOCAL); + const bool use_sandbox = was_set_insecurely(wp, kOptFoldexpr, OPT_LOCAL); char *arg = wp->w_p_fde; current_sctx = wp->w_p_script_ctx[WV_FDE].script_ctx; @@ -1326,7 +1326,7 @@ int eval_foldexpr(win_T *wp, int *cp) /// Evaluate 'foldtext', returning an Array or a String (NULL_STRING on failure). Object eval_foldtext(win_T *wp) { - const bool use_sandbox = was_set_insecurely(wp, "foldtext", OPT_LOCAL); + const bool use_sandbox = was_set_insecurely(wp, kOptFoldtext, OPT_LOCAL); char *arg = wp->w_p_fdt; funccal_entry_T funccal_entry; @@ -8715,7 +8715,7 @@ char *do_string_sub(char *str, char *pat, char *sub, typval_T *expr, const char // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } free_string_option(save_cpo); } diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b4f0be85e5..c35e0b2ada 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -7239,7 +7239,7 @@ int do_searchpair(const char *spat, const char *mpat, const char *epat, int dir, // If it's still empty it was changed and restored, need to restore in // the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } free_string_option(save_cpo); } diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 8864edbf69..9b7a61f969 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -834,7 +834,7 @@ static char *ex_let_option(char *arg, typval_T *const tv, const bool is_const, } } - const char *err = set_option_value(arg, newval, scope); + const char *err = set_option_value_handle_tty(arg, opt_idx, newval, scope); arg_end = p; if (err != NULL) { emsg(_(err)); @@ -1945,15 +1945,18 @@ static void set_option_from_tv(const char *varname, typval_T *varp) semsg(_(e_unknown_option2), varname); return; } - uint32_t opt_p_flags = get_option(opt_idx)->flags; bool error = false; + uint32_t opt_p_flags = get_option_flags(opt_idx); OptVal value = tv_to_optval(varp, varname, opt_p_flags, &error); if (!error) { - set_option_value_give_err(varname, value, OPT_LOCAL); - } + const char *errmsg = set_option_value_handle_tty(varname, opt_idx, value, OPT_LOCAL); + if (errmsg) { + emsg(errmsg); + } + } optval_free(value); } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 68c316fde0..786612070e 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -4265,7 +4265,7 @@ skip: // Show 'inccommand' preview if there are matched lines. if (cmdpreview_ns > 0 && !aborting()) { if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable. - set_string_option_direct("icm", -1, "", OPT_FREE, SID_NONE); + set_string_option_direct(kOptInccommand, "", OPT_FREE, SID_NONE); } else if (*p_icm != NUL && pat != NULL) { if (pre_hl_id == 0) { pre_hl_id = syn_check_group(S_LEN("Substitute")); @@ -4544,8 +4544,8 @@ bool prepare_tagpreview(bool undo_sync) curwin->w_p_wfh = true; RESET_BINDING(curwin); // don't take over 'scrollbind' and 'cursorbind' curwin->w_p_diff = false; // no 'diff' - set_string_option_direct("fdc", -1, // no 'foldcolumn' - "0", OPT_FREE, SID_NONE); + + set_string_option_direct(kOptFoldcolumn, "0", OPT_FREE, SID_NONE); // no 'foldcolumn' return true; } @@ -4564,7 +4564,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i buf_T *cmdpreview_buf = NULL; // disable file info message - set_string_option_direct("shm", -1, "F", OPT_FREE, SID_NONE); + set_string_option_direct(kOptShortmess, "F", OPT_FREE, SID_NONE); // Update the topline to ensure that main window is on the correct line update_topline(curwin); @@ -4665,7 +4665,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i xfree(str); - set_string_option_direct("shm", -1, save_shm_p, OPT_FREE, SID_NONE); + set_string_option_direct(kOptShortmess, save_shm_p, OPT_FREE, SID_NONE); xfree(save_shm_p); return preview ? 2 : 1; diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 90b816bb6f..ff80ee9e54 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2653,7 +2653,7 @@ static void apply_cmdmod(cmdmod_T *cmod) // Set 'eventignore' to "all". // First save the existing option value for restoring it later. cmod->cmod_save_ei = xstrdup(p_ei); - set_string_option_direct("ei", -1, "all", OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, "all", OPT_FREE, SID_NONE); } } @@ -2673,7 +2673,7 @@ void undo_cmdmod(cmdmod_T *cmod) if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct("ei", -1, cmod->cmod_save_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, OPT_FREE, SID_NONE); free_string_option(cmod->cmod_save_ei); cmod->cmod_save_ei = NULL; } @@ -7306,7 +7306,7 @@ static void ex_setfiletype(exarg_T *eap) arg += 9; } - set_option_value_give_err("filetype", CSTR_AS_OPTVAL(arg), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, CSTR_AS_OPTVAL(arg), OPT_LOCAL); if (arg != eap->arg) { did_filetype = false; } diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 14d230331a..afaf0a6e2b 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -905,7 +905,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear need_wait_return = false; } - set_string_option_direct("icm", -1, s->save_p_icm, OPT_FREE, SID_NONE); + set_string_option_direct(kOptInccommand, s->save_p_icm, OPT_FREE, SID_NONE); State = s->save_State; if (cmdpreview != save_cmdpreview) { cmdpreview = save_cmdpreview; // restore preview state @@ -4326,7 +4326,7 @@ static int open_cmdwin(void) return Ctrl_C; } // Command-line buffer has bufhidden=wipe, unlike a true "scratch" buffer. - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); curbuf->b_p_ma = true; curwin->w_p_fen = false; curwin->w_p_rl = cmdmsg_rl; @@ -4344,7 +4344,7 @@ static int open_cmdwin(void) add_map("<Tab>", "<C-X><C-V>", MODE_INSERT, true); add_map("<Tab>", "a<C-X><C-V>", MODE_NORMAL, true); } - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("vim"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("vim"), OPT_LOCAL); } curbuf->b_ro_locked--; diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 4fe5b1cd44..0e2959835b 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1617,7 +1617,7 @@ failed: save_file_ff(curbuf); // If editing a new file: set 'fenc' for the current buffer. // Also for ":read ++edit file". - set_string_option_direct("fenc", -1, fenc, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct(kOptFileencoding, fenc, OPT_FREE | OPT_LOCAL, 0); } if (fenc_alloced) { xfree(fenc); @@ -1965,7 +1965,7 @@ void set_forced_fenc(exarg_T *eap) } char *fenc = enc_canonize(eap->cmd + eap->force_enc); - set_string_option_direct("fenc", -1, fenc, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptFileencoding, fenc, OPT_FREE|OPT_LOCAL, 0); xfree(fenc); } diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 3a355634f3..2b17add7ba 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -1,4 +1,5 @@ local options_file = arg[1] +local options_enum_file = arg[2] local opt_fd = assert(io.open(options_file, 'w')) @@ -41,6 +42,12 @@ local list_flags = { flagscomma = 'P_COMMA|P_FLAGLIST', } +--- @param s string +--- @return string +local title_case = function(s) + return s:sub(1, 1):upper() .. s:sub(2):lower() +end + --- @param o vim.option_meta --- @return string local function get_flags(o) @@ -229,4 +236,14 @@ w('') for _, v in ipairs(defines) do w('#define ' .. v[1] .. ' ' .. v[2]) end + +-- Generate options enum file +opt_fd = assert(io.open(options_enum_file, 'w')) + +w('typedef enum {') +for i, o in ipairs(options.options) do + w((' kOpt%s = %u,'):format(title_case(o.full_name), i - 1)) +end +w('} OptIndex;') + opt_fd:close() diff --git a/src/nvim/help.c b/src/nvim/help.c index dc4f6c44ff..28b95b2346 100644 --- a/src/nvim/help.c +++ b/src/nvim/help.c @@ -608,7 +608,7 @@ void cleanup_help_tags(int num_file, char **file) void prepare_help_buffer(void) { curbuf->b_help = true; - set_string_option_direct("buftype", -1, "help", OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptBuftype, "help", OPT_FREE|OPT_LOCAL, 0); // Always set these options after jumping to a help tag, because the // user may have an autocommand that gets in the way. @@ -617,13 +617,13 @@ void prepare_help_buffer(void) // Only set it when needed, buf_init_chartab() is some work. char *p = "!-~,^*,^|,^\",192-255"; if (strcmp(curbuf->b_p_isk, p) != 0) { - set_string_option_direct("isk", -1, p, OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptIskeyword, p, OPT_FREE|OPT_LOCAL, 0); check_buf_options(curbuf); (void)buf_init_chartab(curbuf, false); } // Don't use the global foldmethod. - set_string_option_direct("fdm", -1, "manual", OPT_FREE|OPT_LOCAL, 0); + set_string_option_direct(kOptFoldmethod, "manual", OPT_FREE|OPT_LOCAL, 0); curbuf->b_p_ts = 8; // 'tabstop' is 8. curwin->w_p_list = false; // No list mode. @@ -649,7 +649,7 @@ void fix_help_buffer(void) // Set filetype to "help". if (strcmp(curbuf->b_p_ft, "help") != 0) { curbuf->b_ro_locked++; - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL); curbuf->b_ro_locked--; } diff --git a/src/nvim/highlight_group.c b/src/nvim/highlight_group.c index 3bd4aa4f64..4add1e3591 100644 --- a/src/nvim/highlight_group.c +++ b/src/nvim/highlight_group.c @@ -1337,9 +1337,10 @@ void do_highlight(const char *line, const bool forceit, const bool init) // wrong. if (dark != -1 && dark != (*p_bg == 'd') - && !option_was_set("bg")) { - set_option_value_give_err("bg", CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0); - reset_option_was_set("bg"); + && !option_was_set(kOptBackground)) { + set_option_value_give_err(kOptBackground, + CSTR_AS_OPTVAL(dark ? "dark" : "light"), 0); + reset_option_was_set(kOptBackground); } } } diff --git a/src/nvim/indent.c b/src/nvim/indent.c index 5dced37b40..925317e7cb 100644 --- a/src/nvim/indent.c +++ b/src/nvim/indent.c @@ -1091,7 +1091,7 @@ void ex_retab(exarg_T *eap) colnr_T *old_vts_ary = curbuf->b_p_vts_array; if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) { - set_string_option_direct("vts", -1, new_ts_str, OPT_FREE | OPT_LOCAL, 0); + set_string_option_direct(kOptVartabstop, new_ts_str, OPT_FREE | OPT_LOCAL, 0); curbuf->b_p_vts_array = new_vts_array; xfree(old_vts_ary); } else { @@ -1115,7 +1115,7 @@ int get_expr_indent(void) colnr_T save_curswant; int save_set_curswant; int save_State; - int use_sandbox = was_set_insecurely(curwin, "indentexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, kOptIndentexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Save and restore cursor position and curswant, in case it was changed diff --git a/src/nvim/main.c b/src/nvim/main.c index 216e39f3e8..521d67a638 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -1123,7 +1123,7 @@ static void command_line_scan(mparm_T *parmp) } else if (STRNICMP(argv[0] + argv_idx, "clean", 5) == 0) { parmp->use_vimrc = "NONE"; parmp->clean = true; - set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0); + set_option_value_give_err(kOptShadafile, STATIC_CSTR_AS_OPTVAL("NONE"), 0); } else if (STRNICMP(argv[0] + argv_idx, "luamod-dev", 9) == 0) { nlua_disable_preload = true; } else { @@ -1137,7 +1137,7 @@ static void command_line_scan(mparm_T *parmp) } break; case 'A': // "-A" start in Arabic mode. - set_option_value_give_err("arabic", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptArabic, BOOLEAN_OPTVAL(true), 0); break; case 'b': // "-b" binary mode. // Needs to be effective before expanding file names, because @@ -1167,8 +1167,8 @@ static void command_line_scan(mparm_T *parmp) usage(); os_exit(0); case 'H': // "-H" start in Hebrew mode: rl + keymap=hebrew set. - set_option_value_give_err("keymap", STATIC_CSTR_AS_OPTVAL("hebrew"), 0); - set_option_value_give_err("rl", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptKeymap, STATIC_CSTR_AS_OPTVAL("hebrew"), 0); + set_option_value_give_err(kOptRightleft, BOOLEAN_OPTVAL(true), 0); break; case 'M': // "-M" no changes or writing of files reset_modifiable(); @@ -1248,7 +1248,7 @@ static void command_line_scan(mparm_T *parmp) // default is 10: a little bit verbose p_verbose = get_number_arg(argv[0], &argv_idx, 10); if (argv[0][argv_idx] != NUL) { - set_option_value_give_err("verbosefile", CSTR_AS_OPTVAL(argv[0] + argv_idx), 0); + set_option_value_give_err(kOptVerbosefile, CSTR_AS_OPTVAL(argv[0] + argv_idx), 0); argv_idx = (int)strlen(argv[0]); } break; @@ -1256,7 +1256,7 @@ static void command_line_scan(mparm_T *parmp) // "-w {scriptout}" write to script if (ascii_isdigit((argv[0])[argv_idx])) { n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0); + set_option_value_give_err(kOptWindow, NUMBER_OPTVAL((OptInt)n), 0); break; } want_argument = true; @@ -1352,7 +1352,7 @@ static void command_line_scan(mparm_T *parmp) break; case 'i': // "-i {shada}" use for shada - set_option_value_give_err("shadafile", CSTR_AS_OPTVAL(argv[0]), 0); + set_option_value_give_err(kOptShadafile, CSTR_AS_OPTVAL(argv[0]), 0); break; case 'l': // "-l" Lua script: args after "-l". @@ -1362,7 +1362,7 @@ static void command_line_scan(mparm_T *parmp) parmp->no_swap_file = true; parmp->use_vimrc = parmp->use_vimrc ? parmp->use_vimrc : "NONE"; if (p_shadafile == NULL || *p_shadafile == NUL) { - set_option_value_give_err("shadafile", STATIC_CSTR_AS_OPTVAL("NONE"), 0); + set_option_value_give_err(kOptShadafile, STATIC_CSTR_AS_OPTVAL("NONE"), 0); } parmp->luaf = argv[0]; argc--; @@ -1398,7 +1398,7 @@ scripterror: if (ascii_isdigit(*(argv[0]))) { argv_idx = 0; n = get_number_arg(argv[0], &argv_idx, 10); - set_option_value_give_err("window", NUMBER_OPTVAL((OptInt)n), 0); + set_option_value_give_err(kOptWindow, NUMBER_OPTVAL((OptInt)n), 0); argv_idx = -1; break; } @@ -1549,7 +1549,7 @@ static void handle_quickfix(mparm_T *paramp) { if (paramp->edit_type == EDIT_QF) { if (paramp->use_ef != NULL) { - set_string_option_direct("ef", -1, paramp->use_ef, OPT_FREE, SID_CARG); + set_string_option_direct(kOptErrorfile, paramp->use_ef, OPT_FREE, SID_CARG); } vim_snprintf(IObuff, IOSIZE, "cfile %s", p_ef); if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) { @@ -1794,7 +1794,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd) p_shm_save = xstrdup(p_shm); snprintf(buf, sizeof(buf), "F%s", p_shm); - set_option_value_give_err("shm", CSTR_AS_OPTVAL(buf), 0); + set_option_value_give_err(kOptShortmess, CSTR_AS_OPTVAL(buf), 0); } } else { if (curwin->w_next == NULL) { // just checking @@ -1839,7 +1839,7 @@ static void edit_buffers(mparm_T *parmp, char *cwd) } if (p_shm_save != NULL) { - set_option_value_give_err("shm", CSTR_AS_OPTVAL(p_shm_save), 0); + set_option_value_give_err(kOptShortmess, CSTR_AS_OPTVAL(p_shm_save), 0); xfree(p_shm_save); } diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 5e768839ba..9dc2d929b2 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -974,7 +974,7 @@ void ml_recover(bool checkext) set_fileformat(b0_ff - 1, OPT_LOCAL); } if (b0_fenc != NULL) { - set_option_value_give_err("fenc", CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL); + set_option_value_give_err(kOptFileencoding, CSTR_AS_OPTVAL(b0_fenc), OPT_LOCAL); xfree(b0_fenc); } unchanged(curbuf, true, true); diff --git a/src/nvim/option.c b/src/nvim/option.c index b5291f616b..71d9a2800c 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -156,19 +156,19 @@ typedef enum { # include "options.generated.h" #endif -static char *(p_bin_dep_opts[]) = { - "textwidth", "wrapmargin", "modeline", "expandtab", NULL +static int p_bin_dep_opts[] = { + kOptTextwidth, kOptWrapmargin, kOptModeline, kOptExpandtab, -1 }; -static char *(p_paste_dep_opts[]) = { - "autoindent", "expandtab", "ruler", "showmatch", "smarttab", - "softtabstop", "textwidth", "wrapmargin", "revins", "varsofttabstop", NULL + +static int p_paste_dep_opts[] = { + kOptAutoindent, kOptExpandtab, kOptRuler, kOptShowmatch, kOptSmarttab, + kOptSofttabstop, kOptTextwidth, kOptWrapmargin, kOptRevins, kOptVarsofttabstop, -1 }; void set_init_tablocal(void) { // susy baka: cmdheight calls itself OPT_GLOBAL but is really tablocal! - int ch_idx = findoption("cmdheight"); - p_ch = (OptInt)(intptr_t)options[ch_idx].def_val; + p_ch = (OptInt)(intptr_t)options[kOptCmdheight].def_val; } /// Initialize the 'shell' option to a default value. @@ -182,9 +182,9 @@ static void set_init_default_shell(void) const size_t len = strlen(shell) + 3; // two quotes and a trailing NUL char *const cmd = xmalloc(len); snprintf(cmd, len, "\"%s\"", shell); - set_string_default("sh", cmd, true); + set_string_default(kOptShell, cmd, true); } else { - set_string_default("sh", (char *)shell, false); + set_string_default(kOptShell, (char *)shell, false); } } } @@ -199,7 +199,7 @@ static void set_init_default_backupskip(void) static char *(names[3]) = { "TMPDIR", "TEMP", "TMP" }; #endif garray_T ga; - int opt_idx = findoption("backupskip"); + int opt_idx = kOptBackupskip; ga_init(&ga, 1, 100); for (size_t n = 0; n < ARRAY_SIZE(names); n++) { @@ -243,7 +243,7 @@ static void set_init_default_backupskip(void) } } if (ga.ga_data != NULL) { - set_string_default("bsk", ga.ga_data, true); + set_string_default(kOptBackupskip, ga.ga_data, true); } } @@ -269,7 +269,7 @@ static void set_init_default_cdpath(void) } } buf[j] = NUL; - int opt_idx = findoption("cdpath"); + int opt_idx = kOptCdpath; if (opt_idx >= 0) { options[opt_idx].def_val = buf; options[opt_idx].flags |= P_DEF_ALLOCED; @@ -346,20 +346,20 @@ void set_init_1(bool clean_arg) backupdir = xrealloc(backupdir, backupdir_len + 3); memmove(backupdir + 2, backupdir, backupdir_len + 1); memmove(backupdir, ".,", 2); - set_string_default("backupdir", backupdir, true); - set_string_default("viewdir", stdpaths_user_state_subpath("view", 2, true), + set_string_default(kOptBackupdir, backupdir, true); + set_string_default(kOptViewdir, stdpaths_user_state_subpath("view", 2, true), true); - set_string_default("directory", stdpaths_user_state_subpath("swap", 2, true), + set_string_default(kOptDirectory, stdpaths_user_state_subpath("swap", 2, true), true); - set_string_default("undodir", stdpaths_user_state_subpath("undo", 2, true), + set_string_default(kOptUndodir, stdpaths_user_state_subpath("undo", 2, true), true); // Set default for &runtimepath. All necessary expansions are performed in // this function. char *rtp = runtimepath_default(clean_arg); if (rtp) { - set_string_default("runtimepath", rtp, true); + set_string_default(kOptRuntimepath, rtp, true); // Make a copy of 'rtp' for 'packpath' - set_string_default("packpath", rtp, false); + set_string_default(kOptPackpath, rtp, false); rtp = NULL; // ownership taken } @@ -398,7 +398,7 @@ void set_init_1(bool clean_arg) // NOTE: mlterm's author is being asked to 'set' a variable // instead of an environment variable due to inheritance. if (os_env_exists("MLTERM")) { - set_option_value_give_err("tbidi", BOOLEAN_OPTVAL(true), 0); + set_option_value_give_err(kOptTermbidi, BOOLEAN_OPTVAL(true), 0); } didset_options2(); @@ -430,10 +430,10 @@ static void set_option_default(const int opt_idx, int opt_flags) uint32_t flags = opt->flags; if (varp != NULL) { // skip hidden option, nothing to do for it if (flags & P_STRING) { - // Use set_string_option_direct() for local options to handle - // freeing and allocating the value. + // Use set_string_option_direct() for local options to handle freeing and allocating the + // value. if (opt->indir != PV_NONE) { - set_string_option_direct(NULL, opt_idx, opt->def_val, opt_flags, 0); + set_string_option_direct(opt_idx, opt->def_val, opt_flags, 0); } else { if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) { free_string_option(*(char **)(varp)); @@ -479,7 +479,7 @@ static void set_option_default(const int opt_idx, int opt_flags) *flagsp = *flagsp & ~P_INSECURE; } - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); + set_option_sctx(opt_idx, opt_flags, current_sctx); } /// Set all options (except terminal options) to their default value. @@ -504,22 +504,23 @@ static void set_options_default(int opt_flags) /// Set the Vi-default value of a string option. /// Used for 'sh', 'backupskip' and 'term'. /// -/// @param name The name of the option -/// @param val The value of the option -/// @param allocated If true, do not copy default as it was already allocated. -static void set_string_default(const char *name, char *val, bool allocated) +/// @param opt_idx Option index in options[] table. +/// @param val The value of the option. +/// @param allocated If true, do not copy default as it was already allocated. +static void set_string_default(int opt_idx, char *val, bool allocated) FUNC_ATTR_NONNULL_ALL { - int opt_idx = findoption(name); - if (opt_idx >= 0) { - vimoption_T *opt = &options[opt_idx]; - if (opt->flags & P_DEF_ALLOCED) { - xfree(opt->def_val); - } + if (opt_idx < 0) { + return; + } - opt->def_val = allocated ? val : xstrdup(val); - opt->flags |= P_DEF_ALLOCED; + vimoption_T *opt = &options[opt_idx]; + if (opt->flags & P_DEF_ALLOCED) { + xfree(opt->def_val); } + + opt->def_val = allocated ? val : xstrdup(val); + opt->flags |= P_DEF_ALLOCED; } /// For an option value that contains comma separated items, find "newval" in @@ -555,9 +556,8 @@ static char *find_dup_item(char *origval, const char *newval, uint32_t flags) /// Set the Vi-default value of a number option. /// Used for 'lines' and 'columns'. -void set_number_default(char *name, OptInt val) +void set_number_default(int opt_idx, OptInt val) { - int opt_idx = findoption(name); if (opt_idx >= 0) { options[opt_idx].def_val = (void *)(intptr_t)val; } @@ -597,18 +597,17 @@ void set_init_2(bool headless) // 'scroll' defaults to half the window height. The stored default is zero, // which results in the actual value computed from the window height. - int idx = findoption("scroll"); - if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) { - set_option_default(idx, OPT_LOCAL); + if (!(options[kOptScroll].flags & P_WAS_SET)) { + set_option_default(kOptScroll, OPT_LOCAL); } comp_col(); // 'window' is only for backwards compatibility with Vi. // Default is Rows - 1. - if (!option_was_set("window")) { + if (!option_was_set(kOptWindow)) { p_window = Rows - 1; } - set_number_default("window", Rows - 1); + set_number_default(kOptWindow, Rows - 1); } /// Initialize the options, part three: After reading the .vimrc @@ -619,14 +618,8 @@ void set_init_3(void) // Set 'shellpipe' and 'shellredir', depending on the 'shell' option. // This is done after other initializations, where 'shell' might have been // set, but only if they have not been set before. - int idx_srr = findoption("srr"); - int do_srr = (idx_srr < 0) - ? false - : !(options[idx_srr].flags & P_WAS_SET); - int idx_sp = findoption("sp"); - int do_sp = (idx_sp < 0) - ? false - : !(options[idx_sp].flags & P_WAS_SET); + int do_srr = !(options[kOptShellredir].flags & P_WAS_SET); + int do_sp = !(options[kOptShellpipe].flags & P_WAS_SET); size_t len = 0; char *p = (char *)invocation_path_tail(p_sh, &len); @@ -641,11 +634,11 @@ void set_init_3(void) || path_fnamecmp(p, "tcsh") == 0) { if (do_sp) { p_sp = "|& tee"; - options[idx_sp].def_val = p_sp; + options[kOptShellpipe].def_val = p_sp; } if (do_srr) { p_srr = ">&"; - options[idx_srr].def_val = p_srr; + options[kOptShellredir].def_val = p_srr; } } else if (path_fnamecmp(p, "sh") == 0 || path_fnamecmp(p, "ksh") == 0 @@ -660,11 +653,11 @@ void set_init_3(void) // Always use POSIX shell style redirection if we reach this if (do_sp) { p_sp = "2>&1| tee"; - options[idx_sp].def_val = p_sp; + options[kOptShellpipe].def_val = p_sp; } if (do_srr) { p_srr = ">%s 2>&1"; - options[idx_srr].def_val = p_srr; + options[kOptShellredir].def_val = p_srr; } } xfree(p); @@ -694,12 +687,11 @@ void set_helplang_default(const char *lang) if (lang_len < 2) { // safety check return; } - int idx = findoption("hlg"); - if (idx < 0 || (options[idx].flags & P_WAS_SET)) { + if (options[kOptHelplang].flags & P_WAS_SET) { return; } - if (options[idx].flags & P_ALLOCED) { + if (options[kOptHelplang].flags & P_ALLOCED) { free_string_option(p_hlg); } p_hlg = xmemdupz(lang, lang_len); @@ -713,7 +705,7 @@ void set_helplang_default(const char *lang) p_hlg[1] = 'n'; } p_hlg[2] = NUL; - options[idx].flags |= P_ALLOCED; + options[kOptHelplang].flags |= P_ALLOCED; } /// 'title' and 'icon' only default to true if they have not been set or reset @@ -726,14 +718,12 @@ void set_title_defaults(void) // If GUI is (going to be) used, we can always set the window title and // icon name. Saves a bit of time, because the X11 display server does // not need to be contacted. - int idx1 = findoption("title"); - if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val = 0; + if (!(options[kOptTitle].flags & P_WAS_SET)) { + options[kOptTitle].def_val = 0; p_title = 0; } - idx1 = findoption("icon"); - if (idx1 >= 0 && !(options[idx1].flags & P_WAS_SET)) { - options[idx1].def_val = 0; + if (!(options[kOptIcon].flags & P_WAS_SET)) { + options[kOptIcon].def_val = 0; p_icon = 0; } } @@ -775,8 +765,7 @@ static char *stropt_get_default_val(int opt_idx, uint64_t flags) } /// Copy the new string value into allocated memory for the option. -/// Can't use set_string_option_direct(), because we need to remove the -/// backslashes. +/// Can't use set_string_option_direct(), because we need to remove the backslashes. static char *stropt_copy_value(char *origval, char **argp, set_op_T op, uint32_t flags FUNC_ATTR_UNUSED) { @@ -1707,19 +1696,19 @@ void check_options(void) } } -/// Return true when option "opt" was set from a modeline or in secure mode. -/// Return false when it wasn't. -/// Return -1 for an unknown option. -int was_set_insecurely(win_T *const wp, char *opt, int opt_flags) +/// Check if option was set insecurely. +/// +/// @param wp Window. +/// @param opt_idx Option index in options[] table. +/// @param opt_flags Option flags. +/// +/// @return True if option was set from a modeline or in secure mode, false if it wasn't. +int was_set_insecurely(win_T *const wp, int opt_idx, int opt_flags) { - int idx = findoption(opt); + assert(opt_idx >= 0); - if (idx >= 0) { - uint32_t *flagp = insecure_flag(wp, idx, opt_flags); - return (*flagp & P_INSECURE) != 0; - } - internal_error("was_set_insecurely()"); - return -1; + uint32_t *flagp = insecure_flag(wp, opt_idx, opt_flags); + return (*flagp & P_INSECURE) != 0; } /// Get a pointer to the flags used for the P_INSECURE flag of option @@ -1829,21 +1818,16 @@ bool parse_winhl_opt(win_T *wp) return true; } -/// Get the script context of global option "name". -sctx_T *get_option_sctx(const char *const name) +/// Get the script context of global option at index opt_idx. +sctx_T *get_option_sctx(int opt_idx) { - int idx = findoption(name); - - if (idx >= 0) { - return &options[idx].last_set.script_ctx; - } - siemsg("no such option: %s", name); - return NULL; + assert(opt_idx >= 0); + return &options[opt_idx].last_set.script_ctx; } /// Set the script_ctx for an option, taking care of setting the buffer- or /// window-local value. -void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx) +void set_option_sctx(int opt_idx, int opt_flags, sctx_T script_ctx) { int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; int indir = (int)options[opt_idx].indir; @@ -1952,7 +1936,7 @@ static const char *did_set_arabic(optset_T *args) p_deco = true; // Force-set the necessary keymap for arabic. - errmsg = set_option_value("keymap", STATIC_CSTR_AS_OPTVAL("arabic"), OPT_LOCAL); + errmsg = set_option_value(kOptKeymap, STATIC_CSTR_AS_OPTVAL("arabic"), OPT_LOCAL); } else { // 'arabic' is reset, handle various sub-settings. if (!p_tbidi) { @@ -2809,7 +2793,7 @@ static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, char *e cmdline_row = new_row; } } - if (p_window >= Rows || !option_was_set("window")) { + if (p_window >= Rows || !option_was_set(kOptWindow)) { p_window = Rows - 1; } } @@ -3590,7 +3574,7 @@ static const char *did_set_option(int opt_idx, void *varp, OptVal old_value, Opt new_value = optval_from_varp(opt_idx, varp); // Remember where the option was set. - set_option_sctx_idx(opt_idx, opt_flags, current_sctx); + set_option_sctx(opt_idx, opt_flags, current_sctx); // Free options that are in allocated memory. // Use "free_oldval", because recursiveness may change the flags (esp. init_highlight()). if (free_oldval) { @@ -3810,29 +3794,20 @@ err: return errmsg; } -/// Set the value of an option +/// Set the value of an option. /// -/// @param[in] name Option name. +/// @param opt_idx Index in options[] table. Must be >= 0. /// @param[in] value Option value. If NIL_OPTVAL, the option value is cleared. /// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). /// /// @return NULL on success, an untranslated error message on error. -const char *set_option_value(const char *const name, const OptVal value, int opt_flags) - FUNC_ATTR_NONNULL_ARG(1) +const char *set_option_value(const int opt_idx, const OptVal value, int opt_flags) { - static char errbuf[IOSIZE]; - - if (is_tty_option(name)) { - return NULL; // Fail silently; many old vimrcs set t_xx options. - } - - int opt_idx = findoption(name); - if (opt_idx < 0) { - snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name); - return errbuf; - } + assert(opt_idx >= 0); + static char errbuf[IOSIZE]; uint32_t flags = options[opt_idx].flags; + // Disallow changing some options in the sandbox if (sandbox > 0 && (flags & P_SECURE)) { return _(e_sandbox); @@ -3844,31 +3819,51 @@ const char *set_option_value(const char *const name, const OptVal value, int opt return NULL; } - const char *errmsg = NULL; + return set_option(opt_idx, varp, optval_copy(value), opt_flags, true, errbuf, sizeof(errbuf)); +} - errmsg = set_option(opt_idx, varp, optval_copy(value), opt_flags, true, errbuf, sizeof(errbuf)); +/// Set the value of an option. Supports TTY options, unlike set_option_value(). +/// +/// @param name Option name. Used for error messages and for setting TTY options. +/// @param opt_idx Option indx in options[] table. If less than zero, `name` is used to +/// check if the option is a TTY option, and an error is shown if it's not. +/// If the option is a TTY option, the function fails silently. +/// @param value Option value. If NIL_OPTVAL, the option value is cleared. +/// @param[in] opt_flags Flags: OPT_LOCAL, OPT_GLOBAL, or 0 (both). +/// +/// @return NULL on success, an untranslated error message on error. +const char *set_option_value_handle_tty(const char *name, int opt_idx, const OptVal value, + int opt_flags) + FUNC_ATTR_NONNULL_ARG(1) +{ + static char errbuf[IOSIZE]; - return errmsg; + if (opt_idx < 0) { + if (is_tty_option(name)) { + return NULL; // Fail silently; many old vimrcs set t_xx options. + } + + snprintf(errbuf, sizeof(errbuf), _(e_unknown_option2), name); + return errbuf; + } + + return set_option_value(opt_idx, value, opt_flags); } -/// Call set_option_value() and when an error is returned report it. +/// Call set_option_value() and when an error is returned, report it. /// -/// @param opt_flags OPT_LOCAL or 0 (both) -void set_option_value_give_err(const char *name, OptVal value, int opt_flags) +/// @param opt_idx Option index in options[] table. +/// @param value Option value. If NIL_OPTVAL, the option value is cleared. +/// @param opt_flags OPT_LOCAL or 0 (both) +void set_option_value_give_err(const int opt_idx, OptVal value, int opt_flags) { - const char *errmsg = set_option_value(name, value, opt_flags); + const char *errmsg = set_option_value(opt_idx, value, opt_flags); if (errmsg != NULL) { emsg(_(errmsg)); } } -bool is_option_allocated(const char *name) -{ - int idx = findoption(name); - return idx >= 0 && (options[idx].flags & P_ALLOCED); -} - // Translate a string like "t_xx", "<t_xx>" or "<S-Tab>" to a key number. // When "has_lt" is true there is a '<' before "*arg_arg". // Returns 0 when the key is not recognized. @@ -5155,14 +5150,9 @@ void buf_copy_options(buf_T *buf, int flags) /// Reset the 'modifiable' option and its default value. void reset_modifiable(void) { - int opt_idx; - curbuf->b_p_ma = false; p_ma = false; - opt_idx = findoption("ma"); - if (opt_idx >= 0) { - options[opt_idx].def_val = false; - } + options[kOptModifiable].def_val = false; } /// Set the global value for 'iminsert' to the local value. @@ -5807,35 +5797,24 @@ void vimrc_found(char *fname, char *envname) } } -/// Check whether global option has been set +/// Check whether global option has been set. /// /// @param[in] name Option name. /// -/// @return True if it was set. -bool option_was_set(const char *name) +/// @return True if option was set. +bool option_was_set(int opt_idx) { - int idx; - - idx = findoption(name); - if (idx < 0) { // Unknown option. - return false; - } else if (options[idx].flags & P_WAS_SET) { - return true; - } - return false; + assert(opt_idx >= 0); + return options[opt_idx].flags & P_WAS_SET; } /// Reset the flag indicating option "name" was set. /// /// @param[in] name Option name. -void reset_option_was_set(const char *name) +void reset_option_was_set(int opt_idx) { - const int idx = findoption(name); - if (idx < 0) { - return; - } - - options[idx].flags &= ~P_WAS_SET; + assert(opt_idx >= 0); + options[opt_idx].flags &= ~P_WAS_SET; } /// fill_culopt_flags() -- called when 'culopt' changes value @@ -5934,17 +5913,14 @@ int option_set_callback_func(char *optval, Callback *optcb) return OK; } -static void didset_options_sctx(int opt_flags, char **buf) +static void didset_options_sctx(int opt_flags, int *buf) { for (int i = 0;; i++) { - if (buf[i] == NULL) { + if (buf[i] == -1) { break; } - int idx = findoption(buf[i]); - if (idx >= 0) { - set_option_sctx_idx(idx, opt_flags, current_sctx); - } + set_option_sctx(buf[i], opt_flags, current_sctx); } } @@ -6084,7 +6060,7 @@ void set_fileformat(int eol_style, int opt_flags) // p is NULL if "eol_style" is EOL_UNKNOWN. if (p != NULL) { - set_string_option_direct("ff", -1, p, OPT_FREE | opt_flags, 0); + set_string_option_direct(kOptFileformat, p, OPT_FREE | opt_flags, 0); } // This may cause the buffer to become (un)modified. diff --git a/src/nvim/option.h b/src/nvim/option.h index 780f359f5d..db438342ab 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -87,7 +87,7 @@ typedef enum { OPT_SKIPRTP = 0x100, ///< "skiprtp" in 'sessionoptions' } OptionFlags; -/// Return value from get_option_value_strict +/// Return value from get_option_attrs(). enum { SOPT_GLOBAL = 0x01, ///< Option has global value SOPT_WIN = 0x02, ///< Option has window-local value diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 6d0401f319..28718c6269 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -122,3 +122,8 @@ typedef enum { kOptReqWin = 1, ///< Request window-local option value kOptReqBuf = 2, ///< Request buffer-local option value } OptReqScope; + +#ifdef INCLUDE_GENERATED_DECLARATIONS +// Initialize the OptIndex enum. +# include "options_enum.generated.h" +#endif diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c index 64145ba6ac..adb120fc21 100644 --- a/src/nvim/optionstr.c +++ b/src/nvim/optionstr.c @@ -291,22 +291,9 @@ static void set_string_option_global(vimoption_T *opt, char **varp) /// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL. /// /// TODO(famiu): Remove this and its win/buf variants. -void set_string_option_direct(const char *name, int opt_idx, const char *val, int opt_flags, - int set_sid) +void set_string_option_direct(int opt_idx, const char *val, int opt_flags, int set_sid) { - int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; - int idx = opt_idx; - - if (idx == -1) { // Use name. - idx = findoption(name); - if (idx < 0) { // Not found (should not happen). - internal_error("set_string_option_direct()"); - siemsg(_("For option %s"), name); - return; - } - } - - vimoption_T *opt = get_option(idx); + vimoption_T *opt = get_option(opt_idx); if (opt->var == NULL) { // can't set hidden option return; @@ -314,53 +301,53 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in assert(opt->var != &p_shada); + int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0; char *s = xstrdup(val); - { - char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); - if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) { - free_string_option(*varp); - } - *varp = s; + char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags); - // For buffer/window local option may also set the global value. - if (both) { - set_string_option_global(opt, varp); - } + if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) { + free_string_option(*varp); + } + *varp = s; - opt->flags |= P_ALLOCED; + // For buffer/window local option may also set the global value. + if (both) { + set_string_option_global(opt, varp); + } - // When setting both values of a global option with a local value, - // make the local value empty, so that the global value is used. - if ((opt->indir & PV_BOTH) && both) { - free_string_option(*varp); - *varp = empty_string_option; - } - if (set_sid != SID_NONE) { - sctx_T script_ctx; + opt->flags |= P_ALLOCED; - if (set_sid == 0) { - script_ctx = current_sctx; - } else { - script_ctx.sc_sid = set_sid; - script_ctx.sc_seq = 0; - script_ctx.sc_lnum = 0; - } - set_option_sctx_idx(idx, opt_flags, script_ctx); + // When setting both values of a global option with a local value, + // make the local value empty, so that the global value is used. + if ((opt->indir & PV_BOTH) && both) { + free_string_option(*varp); + *varp = empty_string_option; + } + if (set_sid != SID_NONE) { + sctx_T script_ctx; + + if (set_sid == 0) { + script_ctx = current_sctx; + } else { + script_ctx.sc_sid = set_sid; + script_ctx.sc_seq = 0; + script_ctx.sc_lnum = 0; } + set_option_sctx(opt_idx, opt_flags, script_ctx); } } /// Like set_string_option_direct(), but for a window-local option in "wp". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, const char *val, - int opt_flags, int set_sid) +void set_string_option_direct_in_win(win_T *wp, int opt_idx, const char *val, int opt_flags, + int set_sid) { win_T *save_curwin = curwin; block_autocmds(); curwin = wp; curbuf = curwin->w_buffer; - set_string_option_direct(name, opt_idx, val, opt_flags, set_sid); + set_string_option_direct(opt_idx, val, opt_flags, set_sid); curwin = save_curwin; curbuf = curwin->w_buffer; unblock_autocmds(); @@ -368,14 +355,14 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c /// Like set_string_option_direct(), but for a buffer-local option in "buf". /// Blocks autocommands to avoid the old curwin becoming invalid. -void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx, const char *val, - int opt_flags, int set_sid) +void set_string_option_direct_in_buf(buf_T *buf, int opt_idx, const char *val, int opt_flags, + int set_sid) { buf_T *save_curbuf = curbuf; block_autocmds(); curbuf = buf; - set_string_option_direct(name, opt_idx, val, opt_flags, set_sid); + set_string_option_direct(opt_idx, val, opt_flags, set_sid); curbuf = save_curbuf; unblock_autocmds(); } diff --git a/src/nvim/path.c b/src/nvim/path.c index 28de003212..0fc461ae0f 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -1666,7 +1666,7 @@ static char *eval_includeexpr(const char *const ptr, const size_t len) current_sctx = curbuf->b_p_script_ctx[BV_INEX].script_ctx; char *res = eval_to_string_safe(curbuf->b_p_inex, - was_set_insecurely(curwin, "includeexpr", OPT_LOCAL)); + was_set_insecurely(curwin, kOptIncludeexpr, OPT_LOCAL)); set_vim_var_string(VV_FNAME, NULL, 0); current_sctx = save_sctx; diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c index f009722357..56fc16a82e 100644 --- a/src/nvim/popupmenu.c +++ b/src/nvim/popupmenu.c @@ -767,11 +767,11 @@ static bool pum_set_selected(int n, int repeat) if (res == OK) { // Edit a new, empty buffer. Set options for a "wipeout" // buffer. - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bl", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); - set_option_value_give_err("diff", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuflisted, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL); + set_option_value_give_err(kOptDiff, BOOLEAN_OPTVAL(false), OPT_LOCAL); } } diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 112f9aa35a..976b7e837d 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3645,12 +3645,12 @@ static int qf_goto_cwindow(const qf_info_T *qi, bool resize, int sz, bool vertsp static void qf_set_cwindow_options(void) { // switch off 'swapfile' - set_option_value_give_err("swf", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value_give_err("bt", STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); - set_option_value_give_err("bh", STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); + set_option_value_give_err(kOptSwapfile, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value_give_err(kOptBuftype, STATIC_CSTR_AS_OPTVAL("quickfix"), OPT_LOCAL); + set_option_value_give_err(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL); RESET_BINDING(curwin); curwin->w_p_diff = false; - set_option_value_give_err("fdm", STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); + set_option_value_give_err(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL); } // Open a new quickfix or location list window, load the quickfix buffer and @@ -4212,7 +4212,7 @@ static void qf_fill_buffer(qf_list_T *qfl, buf_T *buf, qfline_T *old_last, int q // resembles reading a file into a buffer, it's more logical when using // autocommands. curbuf->b_ro_locked++; - set_option_value_give_err("ft", STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, STATIC_CSTR_AS_OPTVAL("qf"), OPT_LOCAL); curbuf->b_p_ma = false; keep_filetype = true; // don't detect 'filetype' @@ -5090,7 +5090,7 @@ void ex_cfile(exarg_T *eap) } } if (*eap->arg != NUL) { - set_string_option_direct("ef", -1, eap->arg, OPT_FREE, 0); + set_string_option_direct(kOptErrorfile, eap->arg, OPT_FREE, 0); } char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc; @@ -7220,7 +7220,7 @@ void ex_helpgrep(exarg_T *eap) bool updated = false; // Make 'cpoptions' empty, the 'l' flag should not be used here. char *const save_cpo = p_cpo; - const bool save_cpo_allocated = is_option_allocated("cpo"); + const bool save_cpo_allocated = (get_option(kOptCpoptions)->flags & P_ALLOCED); p_cpo = empty_string_option; bool new_qi = false; @@ -7258,7 +7258,7 @@ void ex_helpgrep(exarg_T *eap) // Darn, some plugin changed the value. If it's still empty it was // changed and restored, need to restore in the complicated way. if (*p_cpo == NUL) { - set_option_value_give_err("cpo", CSTR_AS_OPTVAL(save_cpo), 0); + set_option_value_give_err(kOptCpoptions, CSTR_AS_OPTVAL(save_cpo), 0); } if (save_cpo_allocated) { free_string_option(save_cpo); diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 087c26a46f..d0305a1082 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -1061,7 +1061,7 @@ static int add_pack_dir_to_rtp(char *fname, bool is_pack) xstrlcat(new_rtp, afterdir, new_rtp_capacity); } - set_option_value_give_err("rtp", CSTR_AS_OPTVAL(new_rtp), 0); + set_option_value_give_err(kOptRuntimepath, CSTR_AS_OPTVAL(new_rtp), 0); xfree(new_rtp); retval = OK; diff --git a/src/nvim/spell.c b/src/nvim/spell.c index eb3bcec3ec..d20d113d9c 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3218,14 +3218,14 @@ void ex_spelldump(exarg_T *eap) if (no_spell_checking(curwin)) { return; } - OptVal spl = get_option_value(findoption("spl"), OPT_LOCAL); + OptVal spl = get_option_value(kOptSpelllang, OPT_LOCAL); // Create a new empty buffer in a new window. do_cmdline_cmd("new"); // enable spelling locally in the new window - set_option_value_give_err("spell", BOOLEAN_OPTVAL(true), OPT_LOCAL); - set_option_value_give_err("spl", spl, OPT_LOCAL); + set_option_value_give_err(kOptSpell, BOOLEAN_OPTVAL(true), OPT_LOCAL); + set_option_value_give_err(kOptSpelllang, spl, OPT_LOCAL); optval_free(spl); if (!buf_is_empty(curbuf)) { diff --git a/src/nvim/spellfile.c b/src/nvim/spellfile.c index 4aa0508329..027013c5f0 100644 --- a/src/nvim/spellfile.c +++ b/src/nvim/spellfile.c @@ -5600,7 +5600,7 @@ static void init_spellfile(void) && strstr(path_tail(fname), ".ascii.") != NULL) ? "ascii" : spell_enc())); - set_option_value_give_err("spellfile", CSTR_AS_OPTVAL(buf), OPT_LOCAL); + set_option_value_give_err(kOptSpellfile, CSTR_AS_OPTVAL(buf), OPT_LOCAL); break; } aspath = false; diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c index 4dac1b1451..87409bb5db 100644 --- a/src/nvim/statusline.c +++ b/src/nvim/statusline.c @@ -296,7 +296,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) char buf[MAXPATHL]; char transbuf[MAXPATHL]; char *stl; - char *opt_name; + int opt_idx = -1; int opt_scope = 0; stl_hlrec_t *hltab; StlClickRecord *tabtab; @@ -320,9 +320,9 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) fillchar = ' '; attr = HL_ATTR(HLF_TPF); maxwidth = Columns; - opt_name = "tabline"; + opt_idx = kOptTabline; } else if (draw_winbar) { - opt_name = "winbar"; + opt_idx = kOptWinbar; stl = ((*wp->w_p_wbr != NUL) ? wp->w_p_wbr : p_wbr); opt_scope = ((*wp->w_p_wbr != NUL) ? OPT_LOCAL : 0); row = -1; // row zero is first row of text @@ -351,7 +351,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) if (draw_ruler) { stl = p_ruf; - opt_name = "rulerformat"; + opt_idx = kOptRulerformat; // advance past any leading group spec - implicit in ru_col if (*stl == '%') { if (*++stl == '-') { @@ -379,7 +379,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) attr = HL_ATTR(HLF_MSG); } } else { - opt_name = "statusline"; + opt_idx = kOptStatusline; stl = ((*wp->w_p_stl != NUL) ? wp->w_p_stl : p_stl); opt_scope = ((*wp->w_p_stl != NUL) ? OPT_LOCAL : 0); } @@ -402,7 +402,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler) // Make a copy, because the statusline may include a function call that // might change the option value and free the memory. stl = xstrdup(stl); - build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_name, opt_scope, + build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_idx, opt_scope, fillchar, maxwidth, &hltab, &tabtab, NULL); xfree(stl); @@ -881,7 +881,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * StlClickRecord *clickrec; char *stc = xstrdup(wp->w_p_stc); - int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, "statuscolumn", OPT_LOCAL, ' ', + int width = build_stl_str_hl(wp, stcp->text, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, ' ', stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp); xfree(stc); @@ -913,8 +913,8 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * /// Note: This should not be NameBuff /// @param outlen The length of the output buffer /// @param fmt The statusline format string -/// @param opt_name The option name corresponding to "fmt" -/// @param opt_scope The scope corresponding to "opt_name" +/// @param opt_idx Index of the option corresponding to "fmt" +/// @param opt_scope The scope corresponding to "opt_idx" /// @param fillchar Character to use when filling empty space in the statusline /// @param maxwidth The maximum width to make the statusline /// @param hltab HL attributes (can be NULL) @@ -922,7 +922,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, statuscol_T * /// @param stcp Status column attributes (can be NULL) /// /// @return The final width of the statusline -int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_name, int opt_scope, +int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, int opt_idx, int opt_scope, int fillchar, int maxwidth, stl_hlrec_t **hltab, StlClickRecord **tabtab, statuscol_T *stcp) { @@ -957,10 +957,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n stl_separator_locations = xmalloc(sizeof(int) * stl_items_len); } - // if "fmt" was set insecurely it needs to be evaluated in the sandbox - // "opt_name" will be NULL when caller is nvim_eval_statusline() - const int use_sandbox = opt_name ? was_set_insecurely(wp, opt_name, opt_scope) - : false; + // If "fmt" was set insecurely it needs to be evaluated in the sandbox. + // "opt_idx" will be -1 when caller is nvim_eval_statusline(). + const int use_sandbox = (opt_idx != -1) ? was_set_insecurely(wp, opt_idx, opt_scope) : false; // When the format starts with "%!" then evaluate it as an expression and // use the result as the actual format string. @@ -1545,7 +1544,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n break; case STL_SHOWCMD: - if (p_sc && (opt_name == NULL || strcmp(opt_name, p_sloc) == 0)) { + if (p_sc && (opt_idx == -1 || findoption(p_sloc) == opt_idx)) { str = showcmd_buf; } break; @@ -2177,8 +2176,8 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, char *opt_n // TODO(Bram): find out why using called_emsg_before makes tests fail, does it // matter? // if (called_emsg > called_emsg_before) - if (opt_name && did_emsg > did_emsg_before) { - set_string_option_direct(opt_name, -1, "", OPT_FREE | opt_scope, SID_ERROR); + if (opt_idx != -1 && did_emsg > did_emsg_before) { + set_string_option_direct(opt_idx, "", OPT_FREE | opt_scope, SID_ERROR); } // A user function may reset KeyTyped, restore it. diff --git a/src/nvim/statusline.h b/src/nvim/statusline.h index eab7c1aa47..59a900d566 100644 --- a/src/nvim/statusline.h +++ b/src/nvim/statusline.h @@ -4,6 +4,7 @@ #include "nvim/buffer_defs.h" // IWYU pragma: keep #include "nvim/macros_defs.h" +#include "nvim/option_defs.h" #include "nvim/statusline_defs.h" // IWYU pragma: export /// Array defining what should be done when tabline is clicked diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index fda6aa41e8..af9693c4b0 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -233,7 +233,7 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) aucmd_prepbuf(&aco, buf); refresh_screen(rv, buf); - set_option_value("buftype", STATIC_CSTR_AS_OPTVAL("terminal"), OPT_LOCAL); + set_option_value(kOptBuftype, STATIC_CSTR_AS_OPTVAL("terminal"), OPT_LOCAL); // Default settings for terminal buffers buf->b_p_ma = false; // 'nomodifiable' @@ -241,8 +241,8 @@ void terminal_open(Terminal **termpp, buf_T *buf, TerminalOptions opts) buf->b_p_scbk = // 'scrollback' (initialize local from global) (p_scbk < 0) ? 10000 : MAX(1, p_scbk); buf->b_p_tw = 0; // 'textwidth' - set_option_value("wrap", BOOLEAN_OPTVAL(false), OPT_LOCAL); - set_option_value("list", BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptWrap, BOOLEAN_OPTVAL(false), OPT_LOCAL); + set_option_value(kOptList, BOOLEAN_OPTVAL(false), OPT_LOCAL); if (buf->b_ffname != NULL) { buf_set_term_title(buf, buf->b_ffname, strlen(buf->b_ffname)); } diff --git a/src/nvim/textformat.c b/src/nvim/textformat.c index 8e52ad660b..3484d104fd 100644 --- a/src/nvim/textformat.c +++ b/src/nvim/textformat.c @@ -870,7 +870,7 @@ void op_formatexpr(oparg_T *oap) /// @param c character to be inserted int fex_format(linenr_T lnum, long count, int c) { - int use_sandbox = was_set_insecurely(curwin, "formatexpr", OPT_LOCAL); + int use_sandbox = was_set_insecurely(curwin, kOptFormatexpr, OPT_LOCAL); const sctx_T save_sctx = current_sctx; // Set v:lnum to the first line number and v:count to the number of lines. diff --git a/src/nvim/ui.c b/src/nvim/ui.c index a78a5b077f..0fc0c5bf86 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -235,7 +235,7 @@ void ui_refresh(void) p_lz = save_p_lz; if (ext_widgets[kUIMessages]) { - set_option_value("cmdheight", NUMBER_OPTVAL(0), 0); + set_option_value(kOptCmdheight, NUMBER_OPTVAL(0), 0); command_height(); } ui_mode_info_set(); diff --git a/src/nvim/window.c b/src/nvim/window.c index ef1ef89d95..98c62d6f44 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -5183,7 +5183,7 @@ void win_new_screensize(void) if (old_Rows != Rows) { // If 'window' uses the whole screen, keep it using that. // Don't change it when set with "-w size" on the command line. - if (p_window == old_Rows - 1 || (old_Rows == 0 && !option_was_set("window"))) { + if (p_window == old_Rows - 1 || (old_Rows == 0 && !option_was_set(kOptWindow))) { p_window = Rows - 1; } old_Rows = Rows; |