aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval/vars.c
Commit message (Collapse)AuthorAge
* multicursor: v:cascading #42289Evgeni Chasnovski9 days
| | | | | Problem: No way to check if cascade is in action. Solution: Add `v:cascading` variable.
* fix(api): preserve option trust during mergesLewis Russell2026-09-22
| | | | | | | | | | | | | Problem: API append, prepend, and remove operations reach the option setter as full replacements. This can clear an expression's untrusted flag and allow it to write files, unlike equivalent :set operations. Solution: Pass replacement status through the option setters so merges preserve the existing value's trust restrictions. AI-assisted
* refactor(option): simplify error buffer handlingLewis Russell2026-09-21
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Option validators and setters repeatedly pass error buffers and their sizes separately. Some setters return messages in static storage. Solution: - Add CharBuf for borrowed writable storage, with its length including space for a terminating NUL. - Move option error buffers to the callers that report errors. Preserve existing buffer sizes, truncation, and calls that do not need a message. - Consolidate option error formatting and the duplicated code that lists valid option values. - Return error messages directly from do_one_set_option(). - Remove unused arguments from get_option_newval() and set_option_value_for(). - Handle legacy TTY assignments in the existing callers and remove the redundant compatibility wrapper. - Reuse CharBuf for Tree-sitter query errors. - Pass CharBuf through the statusline and statuscolumn builders, retaining the buffer sizes provided by their callers, including title formatting. AI-assisted
* fix(options): crash on ":let &l:autoread = v:true" #41158Justin M. Keyes2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Assigning to the local value of a global-local boolean option ('autoread', 'autocomplete', 'fsync') aborts: Assertion failed: (curval.type == newval.type), function ex_let_option, file vars.c, line 1408. ex_let_one ex_let_vars ex_let execute_cmd0 do_cmdline call_user_func ... eval_map_expr vgetorpeek vgetc state_enter main A global-local option may have local value `kObjectTypeUnset`, but `ex_let_option()` guards only `kObjectTypeNil`. Solution: When curval is Unset, resolve it to the inherited global value.
* fix(options): crash on ":let &t_Co = v:true" #41152Justin M. Keyes2026-08-04
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Assigning a Boolean or special value (v:true/v:false/v:null/v:none) to a TTY option aborts: Assertion failed: (curval.type == newval.type), function ex_let_option, file vars.c, line 1408. 3 libsystem_c.dylib __assert_rtn + 284 4 nvim ex_let_one + 3308 5 nvim ex_let_vars + 112 6 nvim ex_let + 2356 7 nvim execute_cmd0 + 252 8 nvim do_cmdline + 9076 9 nvim call_user_func + 3320 10 nvim call_func + 2076 11 nvim get_func_tv + 696 12 nvim eval_func + 380 20 nvim eval_to_string_eap + 276 21 nvim eval_map_expr + 444 22 nvim vgetorpeek + 3172 23 nvim vgetc + 764 Solution: Apply the string-type check to TTY options too, so a Boolean/special value gives "E928: String required" instead of aborting. Valid string/number assignments to `t_*` pseudo-options still silently no-op.
* fix(options): ":set foo?" for Lua callbacks #41100Justin M. Keyes2026-08-01
| | | | | | | | | | | | | | | | | Problem: `:set foo=<tab>` and `:set foo?` for func/expr options set to a Lua function, always displays "v:lua". The existing "<Lua N: file:line>" form was avoided because the ref id N changes on every read of the same option. Solution: - Don't attempt to tab-complete Lua functions. - Show "<Lua file:line>" (or "<Lua>" if source file is unknown). Example: :set operatorfunc? operatorfunc=<Lua ~/.config/nvim/init.lua:42>
* refactor(options): simplify "unset" logicJustin M. Keyes2026-07-31
|
* refactor(options): memory managementJustin M. Keyes2026-07-31
| | | | | | | | | | | | | | | | Problem: Numerous callers have to manually check optval ownership (i.e. whether, and how, to release) via `is_callback_option`, `option_is_global_local`, etc. This is fragile, hard to use correctly; and if we introduce another optval variant in the future, we'll have to redo all of these careful checks and boilerplate again. Solution: Provide a unified system and use it everywhere: optval_free_owned optval_is_owned optval_own
* feat(options): lua closure/function optionsJustin M. Keyes2026-07-31
| | | | | | | | | | | | | | | Problem: Cannot assign Lua functions/closures to "func" ('completefunc', 'tagfun', …) or "expr" ('foldexpr', 'indentexpr', …) options. Solution: - Store "func"/"expr" options as `Callback` instead of string. - Delete oceans of copy-pasted code. - BREAKING: LuaRef returned via RPC/Vimscript is now represented as `"<Lua N: file:line>"` (like what `:map` shows) instead of `nil`. - Note: `man.vim` still uses `v:lua` string, bc it's a vimscript ftplugin. Helped-by: Lewis Russell <lewis6991@gmail.com>
* refactor(options): drop OptVal, use ObjectJustin M. Keyes2026-07-29
| | | | | | | | | | | | | Problem: The object subsystem has an intermediate representation for no real reason. Besides the code cost, this also adds an extra (api <=> OptVal) conversion step, which is a (small) perf cost. Solution: We already have `Object`, so use it instead. - drop `OptVal`, `OptValData`, `OptValType`, and related boilerplate. - add `kObjectTypeUnset`.
* refactor(options): store dict options in :set-string formJustin M. Keyes2026-07-24
| | | | | | | | | | The parent commit made a valiant effort to store "dict options" in their reified form, but this is more trouble than it's worth: - inconsistent model for developers to understand. - string lifetime issues (the "varp" convention is to pass around an aliased, long-lived option value). - lots of extra plumbing to deal with the 2 different option-storage paradigms.
* feat(options): schema, "dict" options, messagesJustin M. Keyes2026-07-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Options parsing is still painful for dict-style options. Solution: schema-maxxing => better `opt:get()` (will be the basis for `vim.o()`), unified (and more-detailed) err msgs. - Drop bespoke structure-builder in `_core/options.lua`. - Define `schema` for all non-primitive options (except 'guicursor' and statusline-style options); generate reified keysets `OptKeyDict`). - Generate 'fillchars' => `fcs_tab`, 'listchars' => `lcs_tab`. - `nvim_set_option_value`: - Return the improved structures. Also from `vim.opt.x:get()`. - Eliminate api <=> lua roundtrip, centralize option structure handling. - Improve/unify errors. - Bump ERR_BUFLEN 80 → 256 so the "one of" list isn't truncated. - Eliminate old 'diffopt' order-dependence (`iwhiteall` before `iwhite`) Error samples: Typed-key path (opt_strings_check → diffopt/mousescroll/breakindentopt): E474: Unknown item 'foo' E474: 'context' requires a number E474: 'ver' number is out of range E474: 'algorithm' must be one of: myers, minimal, patience, histogram E474: 'filler' does not take a value Related: - #31084 - #34661 - #31820 - #14739 - #20107 - fix #18875 - :get() returns `{ sbr = true, shift = '3' }` (reified-keyset) instead of `{'sbr', 'shift:3'}` - Setting via table now works too. `object_as_optval_for` `is_map` now recognizes struct options. - fix #30296 - instead of `E474: Invalid argument`, errors now look like: ``` E474: Invalid value 'x', expected one of: single, double: ambiwidth=x E474: Unknown item 'foo': diffopt=foo E474: 'context' requires a number: diffopt=context:x ``` simplify `win_float_parse_option` from #26799.
* refactor(search): SearchStateJustin M. Keyes2026-07-16
|
* refactor(globals): group search state into SearchState structcarladams1299-lab2026-07-16
|
* refactor(ctx): drop switch_win/restore_win #40693Justin M. Keyes2026-07-11
|
* refactor(ctx): drop aucmd_prepbuf/aucmd_restbuf #40692Justin M. Keyes2026-07-11
|
* feat(:restart)!: ":restart" (no bang) saves/restores session #40321Nathan Zeng2026-06-29
| | | | | | | | | | | Problem: `:restart` does not preserve window layout, etc. Solution: - Change `:restart` to save/restore a session automatically. - Introduce "bang" variant `:restart!` to restart *without* session save/restore. - Introduce `v:startreason`. - `ZR` maps to `:restart!`.
* feat(:restart): v:startreason #40186Nathan Zeng2026-06-18
| | | | | | | | Problem: It's clumsy for scripts to handle a "restart", without custom mappings or global vars. Solution: Introduce `v:startreason`
* refactor: simplify aucmd_restbuf usage #39879Justin M. Keyes2026-05-19
| | | | | | | | Problem: `aucmd_restbuf` must be guarded in case `aucmd_prepbuf` wasn't called. Solution: Update `aucmd_restbuf` to be a no-op if `aucmd_prepbuf` wasn't called. This requires `aco` to be zero-initialized.
* vim-patch:9.2.0471: vimvars di_key initialized at runtime (#39747)zeertzjq2026-05-11
| | | | | | | | | | | | | | | Problem: evalvars_init() copies each vimvar's name into di_key at startup and runtime-checks that the name fits in DICTITEM16_KEY_LEN, even though all names are known at compile time. Solution: Embed the name in di_key via the VV_NAME macro so the initialization happens at compile time. Drop the runtime length check and the STRCPY loop (John Marriott). closes: vim/vim#20185 https://github.com/vim/vim/commit/1b65cfbac5c5bbad108548908e77697111ad4a3f Co-authored-by: John Marriott <basilisk@internode.on.net>
* fix(style): some clang-tidy 22 fixesbfredl2026-05-11
| | | | | | | | | | | | | | | | | | | | | | CI currently uses clang-tidy 20, but this affects local builds and CI is going to be upgraded sooner or later. Some remaining systematic issues: - clang-tidy warns agains any atoi() or atol() usage (because of no error handling) - functions which takes (char *fmt, char *only_string_arg) and expect fmt to contain exactly one "%s" usage. - error: initializing non-local variable with non-const expression depending on uninitialized non-local variable (cppcoreguidelines-interfaces-global-init) This is a much worse problem in C++ (hence C++ core guidelines) where initialization is intermingled with arbitrary code execution. I "think" in plain C, the linker will either resolve all these deterministically or barf an error. But with some restructuring we could make all static initialization actually static..
* feat(server): add v:useractive, use it in serverlist(info=true) #39423Szymon Wilczek2026-05-07
| | | | | | | | | | | | Problem: When showing the :connect menu, it is useful to know which servers are most-recently active. But we don't have a good way to detect that. Solution: - Introduce `v:useractive`. - Include this timestamp in `serverlist({info=true})`. Co-authored-by: Justin M. Keyes <justinkz@gmail.com> Signed-off-by: Szymon Wilczek <swilczek.lx@gmail.com>
* feat(:restart): v:starttime, v:exitreason #39282Justin M. Keyes2026-04-22
| | | | | | | | | | | | Problem: - The `ZR` feature makes it more obvious that we need some sort of flag so that an `ExitPre` / `QuitPre` / `VimLeave` handler can handle restarts differently than a normal exit. For example, it's common that users want `:mksession` on restart, but perhaps not on a normal exit. - Nvim has no way to report its "uptime". Solution: - Introduce `v:starttime` - Introduce `v:exitreason`
* fix(eval): crash on some NULL ptr deref #39182phanium2026-04-18
| | | | | | | | | | Crash on ``` let busy=$FOO call prompt_setcallback(bufnr('%'), $FOO) call chanclose(1, $FOO) ``` Co-authored-by: zeertzjq <zeertzjq@outlook.com>
* build: update clang v21, fix warningsdundargoc2026-04-14
| | | | | - `src/nvim/ex_cmds_defs.h`: use "U" instead of "u" per `readability-uppercase-literal-suffix`
* vim-patch:partial:9.2.0126: String handling can be improved (#38214)zeertzjq2026-03-10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: String handling can be improved Solution: Pass string length where it is known to avoid strlen() calls, do a few minor refactors (John Marriott). This commit changes some calls to function `set_vim_var_string()` to pass the string length where it is known or can be easily calculated. In addition: In `evalvars.c`: * In function `set_reg_var()` turn variable `regname` into a C string because that is how it used. * Small cosmetics. In `option.c`: * Slightly refactor function `apply_optionset_autocmd()` to move some variables closer to where they are used. In `getchar.c`: * Slightly refactor function `do_key_input_pre()`: -> change call to `dict_add_string()` to `dict_add_string_len()` and pass it the length of `buf`. -> only call `get_vim_var_string()` once. In `message.c`: * Use a `string_T` to store local variable `p`. In `normal.c`: * Move some variables closer to where they are used. closes: vim/vim#19618 https://github.com/vim/vim/commit/727f6e2686fb1d06b9591e6de689763a479cc664 Co-authored-by: John Marriott <basilisk@internode.on.net>
* feat(startup): provide v:argf for file arguments #35889Sanzhar Kuandyk2026-02-25
| | | | | | | | | | | | | | | | | | Problem: - `:args` and `argv()` can change after startup. - `v:arg` includes options/commands, not just files. - Plugins (e.g. Oil) may rewrite directory args. Solution: - New read-only var `v:argf`: snapshot of file/dir args at startup. - Unaffected by `:args` or plugins. - Unlike `v:argv`, excludes options/commands. - Paths are resolved to absolute paths when possible Example: nvim file1.txt dir1 file2.txt :echo v:argf " ['/home/user/project/file1.txt', '/home/user/project/dir1', '/home/user/project/file2.txt']
* vim-patch:8.2.3841: Vim9: outdated TODO items, disabled tests that work (#37900)zeertzjq2026-02-16
| | | | | | | | | Problem: Vim9: outdated TODO items, disabled tests that work. Solution: Remove TODO items, run tests that work now. Check that a dict item isn't locked. https://github.com/vim/vim/commit/71b768509250b12696e8cc90e5902029f1b5433d Co-authored-by: Bram Moolenaar <Bram@vim.org>
* refactor: fix using `%*s` instead of `%.*s` (#37290)zeertzjq2026-01-08
| | | | `%*s` specifies the width limit, not the number of bytes. In these places it doesn't matter as they are ASCII-only.
* Merge #36585 feat: has() can check multiple Vim versionsJustin M. Keyes2025-12-03
|\
| * feat(version): support multiple Vim versionsJan Edmund Lazo2025-12-01
| | | | | | | | | | | | | | | | | | | | Group up to 15 vimpatch numbers in 1 line to guard against 'make formatc'. 1-liner for vim_versions, num_patches. Automate '*Version' to remove version.h macros. '-V1 -v' lists merged Vim versions.
* | fix(eval): fix crash with :breakadd expr when calling user funczeertzjq2025-12-02
|/
* vim-patch:9.1.1923: wrong error when assigning to read-only register (#36644)zeertzjq2025-11-21
| | | | | | | | | | | | | | | | | | | Problem: When assigning to @. in a :let command an incorrect "E15" error is emitted. Solution: Emit the correct "E354" error. (Doug Kearns). An incorrect "E488" error was also emitted in Vim9 script assignments. It appears that the code deleted in this commit was added to work around a limitation in the returned value from find_name_end() that no longer exists. See commit 76b92b2830841fd4e05006cc3cad1d8f0bc8101b (tag: v7.0b). closes: vim/vim#18757 https://github.com/vim/vim/commit/2447131e00c40dbc4726308c937a5437668493c6 Co-authored-by: Doug Kearns <dougkearns@gmail.com>
* vim-patch:9.1.1913: Error message with :unlet! and non-existing dictionary ↵zeertzjq2025-11-13
| | | | | | | | | | | | | | item (#36549) Problem: Error message with :unlet! and non-existing dictionary item (Coacher) Solution: Set GLV_QUIET when using unlet with bang attribute fixes: vim/vim#18516 closes: vim/vim#18734 https://github.com/vim/vim/commit/b8119920eb8dbfed39af88f66d85c65ea4fd8ecf Co-authored-by: Christian Brabandt <cb@256bit.org>
* vim-patch:9.1.1892: Not possible to know once Vim is done with sourcing ↵zeertzjq2025-11-02
| | | | | | | | | | | | | | | | | | vimrc (#36429) Problem: A plugin does not know when startup scripts were already triggered. This is useful to determine if a function is called inside vimrc or after (like when sourcing 'plugin/' files). Solution: Add the v:vim_did_init variable (Evgeni Chasnovski) closes: vim/vim#18668 https://github.com/vim/vim/commit/294bce21ee837aab209a1008d0efc3e305cf188f Nvim has two more steps between sourcing startup scripts and loading plugins. Set this variable after these two steps. Co-authored-by: Evgeni Chasnovski <evgeni.chasnovski@gmail.com>
* vim-patch:8.1.1939: code for handling v: variables in generic eval file (#36312)Jan Edmund Lazo2025-10-26
| | | | | | | | | | | | Problem: Code for handling v: variables in generic eval file. Solution: Move v: variables to evalvars.c. (Yegappan Lakshmanan, closes vim/vim#4872) https://github.com/vim/vim/commit/e5cdf153bcb348c68011b308c8988cea42d6ddeb Cherry-pick get_vim_var_name() from 8.2.0149. Cherry-pick evalvars.c changes from 8.2.1788. Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:8.2.3968: build failureJan Edmund Lazo2025-10-12
| | | | | | | | | Problem: Build failure. Solution: Add missing changes. https://github.com/vim/vim/commit/e70cec976026ce72d09b6589ebba4677581063ac Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:8.2.5017: gcc 12.1 warns for uninitialized variableJan Edmund Lazo2025-10-10
| | | | | | | | | Problem: Gcc 12.1 warns for uninitialized variable. Solution: Initialize the variable. (closes vim/vim#10476) https://github.com/vim/vim/commit/8be36eecdc6728021f9c384c2305f114e671ec32 Co-authored-by: mityu <mityu.mail@gmail.com>
* vim-patch:8.2.0200: Vim9 script commands not sufficiently testedJan Edmund Lazo2025-10-05
| | | | | | | | | | | | | | | Problem: Vim9 script commands not sufficiently tested. Solution: Add more tests. Fix storing global variable. Make script variables work. https://github.com/vim/vim/commit/b283a8a6802ef8a46b17cb439f9514840c03698f Vim9 is N/A. Skip. "set_vim_var_tv()" does not throw E1063 on type mismatch. See https://github.com/neovim/neovim/pull/25394 . Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:8.1.1957: more code can be moved to evalvars.cJan Edmund Lazo2025-10-05
| | | | | | | | | | Problem: More code can be moved to evalvars.c. Solution: Move code to where it fits better. (Yegappan Lakshmanan, closes vim/vim#4883) https://github.com/vim/vim/commit/da6c03342117fb7f4a8110bd9e8627b612a05a64 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:partial:8.1.1939: code for handling v: variables in generic eval ↵Jan Edmund Lazo2025-10-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | file (#35968) Problem: Code for handling v: variables in generic eval file. Solution: Move v: variables to evalvars.c. (Yegappan Lakshmanan, closes vim/vim#4872) https://github.com/vim/vim/commit/e5cdf153bcb348c68011b308c8988cea42d6ddeb Remove direct reference to "vimvars" for following functions: - assert_error() - get_vim_var_nr() - get_vim_var_list() - get_vim_var_dict() - get_vim_var_str() - set_cmdarg() - set_reg_var() - set_vcount() - set_vexception() - set_vthrowpoint() - set_vim_var_bool() - set_vim_var_dict() - set_vim_var_list() - set_vim_var_nr() - set_vim_var_special() - set_vim_var_string() - set_vim_var_type() Reorder functions based on v8.2.4930 for eval_one_expr_in_str() and eval_all_expr_in_str(). Co-authored-by: Bram Moolenaar <Bram@vim.org>
* vim-patch:8.1.2077: the ops.c file is too bigJan Edmund Lazo2025-09-26
| | | | | | | | | | Problem: The ops.c file is too big. Solution: Move code for dealing with registers to a new file. (Yegappan Lakshmanan, closes vim/vim#4982) https://github.com/vim/vim/commit/4aea03eb875613e3eae2125b84f02b7cd898b2f8 Co-authored-by: Bram Moolenaar <Bram@vim.org>
* refactor(build): remove INCLUDE_GENERATED_DECLARATIONS guardsbfredl2025-08-14
| | | | | | | | | These are not needed after #35129 but making uncrustify still play nice with them was a bit tricky. Unfortunately `uncrustify --update-config-with-doc` breaks strings with backslashes. This issue has been reported upstream, and in the meanwhile auto-update on every single run has been disabled.
* feat(ui): emit "msg_clear" event after clearing the screen (#34035)luukvbaal2025-06-26
| | | | | | | | Problem: ext_messages cannot tell when the screen was cleared, which is needed to clear visible messages. An empty message is also never emitted, but clears messages from the message grid. Solution: Repurpose the "msg_clear" event to be emitted when the screen was cleared. Emit an empty message with the `empty` kind to hint to a UI to clear the cmdline area.
* refactor(options): remove code for multitype optionsFamiu Haque2025-01-14
| | | | | | Problem: It was decided on Matrix chat that multitype options won't be necessary for Neovim options, and that options should only have a single canonical type. Therefore the code for supporting multitype options is unnecessary. Solution: Remove the additional code that's used to provide multitype option support.
* refactor(options): use `const` in more places (#31791)Famiu Haque2025-01-01
|
* refactor: iwyu #31637Justin M. Keyes2024-12-23
| | | Result of `make iwyu` (after some "fixups").
* refactor(options): fix confusing naming of `scope` and `req_scope` (#31317)Famiu Haque2024-11-25
| | | | | | | | | | Problem: The name `scope` is often used to refer to option flags because `OPT_LOCAL` and `OPT_GLOBAL` are often used to determine the option scope. This leads to the name `req_scope` being used for actual option scopes instead. Solution: Since the end-goal is to remove `OPT_LOCAL` and `OPT_GLOBAL` entirely and replace them with `OptScope`, rename `OptScope` variables to `scope` and the old scope flag variables to `opt_flags`.
* fix(messages): more ext_messages kinds #31279luukvbaal2024-11-20
| | | | Add kinds for various commands that output a list, the 'wildmode' list, and for number prompts.
* refactor(message): propagate highlight id instead of attrsLuuk van Baal2024-11-08
| | | | | | | Problem: Highlight group id is not propagated to the end of the message call stack, where ext_messages are emitted. Solution: Refactor message functions to pass along highlight group id instead of attr id.