summaryrefslogtreecommitdiffstatshomepage
path: root/src/nvim/eval
AgeCommit message (Collapse)AuthorFiles
2026-04-24fix(path): normalize path slashes on Windows #37729tao1
Problem: On Windows, path separators may become inconsistent for various reasons, which makes normalization quite painful. Solution: Normalize paths to `/` at the entry boundaries and always use it internally, converting back only in rare cases where `\` is really needed (e.g. cmd.exe/bat scripts?). This is the first commit in a series of incremental steps. Note: * some funcs won't respect shellslash. e.g. `expand/fnamemodify` * some funcs still respect shellslash, but will be updated in a follow PR. e.g. `ex_pwd/f_chdir/f_getcwd` * uv's built-in funcs always return `\`. e.g. `uv.cwd/uv.exepath` Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-22feat(:restart): v:starttime, v:exitreason #39282Justin M. Keyes2
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`
2026-04-22feat(eval): treat Lua string as "blob" in writefile() #39098Barrett Ruth1
Problem: vim.fn.writefile() treats Lua strings as Vimscript strings instead of a "binary clean" string. Solution: Treat Lua-originated strings as blob data.
2026-04-20Merge #39194 from justinmk/luavimfnJustin M. Keyes1
2026-04-20vim-patch:partial:9.2.0368: too many strlen() calls when adding strings to ↵zeertzjq1
dicts (#39237) Problem: too many strlen() calls when adding strings to dicts Solution: Refactor code to use string_T, use dict_add_string_len() instead of dict_add_string() (John Marriott) Additionally: - In textprop.c, in function prop_fill_dict() use a string_T to store local variable text_align. - In popupwin.c, use a string_T to store struct member pp_name in struct poppos_entry_T. - In mark.c, refactor function add_mark() to pass in the length of argument mname. - In insexpand.c: ->Use a string_T to store the elements of static array ctrl_x_mode_names. ->Refactor function trigger_complete_done_event(): ->->change type of argument char_u *word to string_T *word. ->->make one access of array ctrl_x_mode_names instead of two. ->Refactor function ins_compl_mode() to accept a string_T to return the resulting string. - In fileio.c: ->Refactor function getftypewfd() to accept a string_T to return the resulting string. ->In function create_readdirex_item() use a string_T to store local variable q. - In cmdexpand.c, store global cmdline_orig as a string_T. - In autocmd.c, in function f_autocmd_get() use a string_T to store local variables event_name and group_name. Measure their lengths once when they are assigned so they are not remeasured on each call to dict_add_string() in the subsequent for loop. - In channel.c, in function channel_part_info() drop local variable status and use s instead. Make s a string_T. closes: vim/vim#19999 https://github.com/vim/vim/commit/c13232699db413e735f30b5649c78a7f38a9a069 Co-authored-by: John Marriott <basilisk@internode.on.net>
2026-04-20vim-patch:8.2.4912: using execute() to define a lambda doesn't work (#39229)Jan Edmund Lazo1
Problem: Using execute() to define a lambda doesn't work. (Ernie Rael) Solution: Put the getline function in evalarg. (closes vim/vim#10375) https://github.com/vim/vim/commit/a7583c42cd6b64fd276a5d7bb0db5ce7bfafa730 Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-04-20fix(jobstart): use uv_os_environ directlyJustin M. Keyes1
2026-04-18vim-patch:8.2.2245: Vim9: return value of winrestcmd() cannot be executedJan Edmund Lazo1
Problem: Vim9: return value of winrestcmd() cannot be executed. Solution: Put colons before each range. (closes vim/vim#7571) https://github.com/vim/vim/commit/285b15fce164ade8b1537b884cc15aebaa60e9ef Co-authored-by: Bram Moolenaar <Bram@vim.org>
2026-04-18fix(eval): crash on some NULL ptr deref #39182phanium3
Crash on ``` let busy=$FOO call prompt_setcallback(bufnr('%'), $FOO) call chanclose(1, $FOO) ``` Co-authored-by: zeertzjq <zeertzjq@outlook.com>
2026-04-18refactor(vimfn): full-Lua impl of vim.fn.environ()Justin M. Keyes1
2026-04-18feat(vimfn): use Lua for more excmds/vimfnsJustin M. Keyes2
Problem: Too much boilerplate needed to use Lua to impl an excmd or f_xx function. Solution: - Add `nlua_call_vimfn` which takes the args typval, executes Lua, and returns a typval. - refactor(excmd): lua impl for :log, :lsp
2026-04-17perf(vim.fn): call Lua-implemented vim.fn.xx() directly #39166Justin M. Keyes1
Problem: - Builtin "Vimscript" functions (f_xx) are mostly implemented in C. Partly that's because there is some boilerplate required to call out to Lua. - Calls to `vim.fn.foo()` always marshall over the Lua <=> Vimscript ("typval") bridge, even if `fn.foo()` is implemented entirely in Lua: ``` Lua => typval => Object => Lua => Object => typval => Lua. ``` Solution: Functions declared in eval.lua with `func_lua` are implemented in entirely in Lua (`_core/vimfn.lua`). - `gen_eval.lua` wires `func_lua` entries to `lua_wrapper`, which handles the typval conversion for Vimscript callers (slow path). - `nlua_call()` detects `func_lua` functions and calls the Lua implementation directly. This eliminates all conversion overhead for Lua callers (fast path). - Validate at build-time that `func`, `func_float`, and `func_lua` are mutually exclusive. - Migrate `hostname()` as a toy example, to show the idea.
2026-04-16vim-patch:9.2.0351: repeat_string() can be improved (#39101)zeertzjq1
Problem: repeat_string() can be improved Solution: Replace the for() loop by an exponential growing while loop (Yasuhiro Matsumoto) closes: vim/vim#19977 https://github.com/vim/vim/commit/bfa46a52f6a93cb99ec55d56ad43493d875c6dc2 Cherry-pick f_repeat() refactor from patch 9.1.1232. Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-04-15refactor: move e_invalwindow to errors.h (#39067)glepnir2
Problem: e_invalwindow was a static local, inconsistent with other error strings. Solution: Convert it to EXTERN/INIT style and move it to errors.h.
2026-04-14build: update clang v21, fix warningsdundargoc4
- `src/nvim/ex_cmds_defs.h`: use "U" instead of "u" per `readability-uppercase-literal-suffix`
2026-04-09feat(logs)!: move logs to `stdpath("state")/logs`Olivia Kinnear1
2026-04-06refactor(typval.c): fix wrong argument to macro (#38813)nameearly1
2026-04-04vim-patch:9.2.0289: 'linebreak' may lead to wrong Visual block highlighting ↵zeertzjq1
(#38749) Problem: 'linebreak' may lead to wrong Visual block highlighting when end char occupies multiple cells (after 7.4.467). Solution: Exclude 'linebreak' from the ending column instead of setting 'virtualedit' temporarily (zeertzjq). fixes: vim/vim#19898 closes: vim/vim#19900 https://github.com/vim/vim/commit/23be1889d1a1212445ca8bb9cd378484d3755f79
2026-03-28fix(:restart): formalize restart event #35223Sathya Pramodh1
Problem: The "restart" event has some problems: - all UI clients must implement a somewhat complex set of setups - UI must be on the same machine as the server - only works for the "current" UI - race/edge case: If the user config has errors / waiting for input, are all UIs able to attach while Nvim is waiting for input? Solution: - Perform the restart on the server, not the client. - Pass listen address (instead of CLI args) in the UI event. - Simplifies UI logic: they only need to attach to new address. - Opens the door for more enhancements in the future, such as allowing all UIs to reattach instead of only the "current" UI. Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-03-28vim-patch:9.2.0265: unnecessary restrictions for defining dictionary ↵zeertzjq1
function names (#38524) Problem: unnecessary restrictions for defining dictionary function names Solution: Allow defining dict function with bracket key that is not a valid identifier (thinca) In Vim script, "function obj.func()" and "function obj['func']()" both define a dictionary function. However, the bracket form required the key to match function naming rules (eval_isnamec), so "function obj['foo-bar']()" failed with E475. Assigning and calling already work: "let obj['foo-bar'] = obj.func" and "call obj['foo-bar']()" are valid. Only the definition was incorrectly restricted. Skip the identifier check when the name comes from fd_newkey (i.e. the key was given in bracket notation). Dictionary keys may be any string. Supported by AI closes: vim/vim#19833 https://github.com/vim/vim/commit/f89662722d3c4b97d55f32ca88a895f246405059 Co-authored-by: thinca <thinca@gmail.com>
2026-03-27feat(prompt): prompt_appendbuf() appends to prompt buffer #37763Shadman1
Problem: Currently, we recommend always inserting text above prompt-line in prompt-buffer. This can be done using the `:` mark. However, although we recommend it this way it can sometimes get confusing how to do it best. Solution: Provide an api to append text to prompt buffer. This is a common use-case for things using prompt-buffer.
2026-03-16feat(vimscript): scripts can detect 'android', 'termux' #38218TomIO1
Problem: The 'android' and 'termux' feature flags have been shipped in the downstream neovim/neovim-nightly package for 5+ years but were never properly documented in the downstream patch. Solution: Upstream the 'android' and 'termux' feature flags into Neovim as decoupled feature flags, this enables the 'android' feature in particular to be available independently of the 'termux' feature for builds of Neovim against the Android NDK, but not including the Termux NDK patchset. Co-authored-by: Lethal Lisa <43791059+lethal-lisa@users.noreply.github.com> Co-authored-by: shadmansaleh <13149513+shadmansaleh@users.noreply.github.com>
2026-03-14vim-patch:9.2.0155: filetype: ObjectScript are not recognized (#38288)zeertzjq1
Problem: filetype: ObjectScript are not recognized Solution: Add ObjectScript filetype detection for *.cls files (Hannah Kimura)). Reference: https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_intro closes: vim/vim#19668 https://github.com/vim/vim/commit/b11c8efbe6981076194e00323737780330cfd0a1 Co-authored-by: Hannah <hannah.kimura@intersystems.com>
2026-03-14vim-patch:9.2.0152: concatenating strings is slow (#38286)zeertzjq1
Problem: concatenating strings is slow Solution: Use grow_string_tv() to grow the existing string buffer in place when possible (Yasuhiro Matsumoto). closes: vim/vim#19642 https://github.com/vim/vim/commit/16d421a4d95b45ebbcf47ab60173cdb1b87ce419 Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-03-12vim-patch:9.2.0147: blob: concatenation can be improved (#38276)zeertzjq1
Problem: blob: concatenation can be improved Solution: Use ga_grow() to allocate space once and mch_memmove() to copy the blob data as a single block and fall back to the previous byte by byte append (Yasuhiro Matsumoto). closes: vim/vim#19645 https://github.com/vim/vim/commit/67deae3b7796341ec2ab42faf492f13daea41007 Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-03-10vim-patch:partial:9.2.0126: String handling can be improved (#38214)zeertzjq1
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>
2026-03-09vim-patch:9.2.0121: patch memory leak in list_extend_func() in list.c (#38205)zeertzjq1
Problem: memory leak in list_extend_func() in list.c Solution: Free l1 on early return (Huihui Huang) closes: vim/vim#19572 https://github.com/vim/vim/commit/7ed37dc53409331cd9e7e0e10238651f7bca2672 Co-authored-by: Huihui Huang <625173@qq.com>
2026-03-03vim-patch:partial:9.2.0096: has() function is slow due to linear feature ↵zeertzjq1
scan (#38135) Problem: The has() function is slow because it performs a linear scan of the feature list for every call. Solution: Move common runtime checks and the patch-version parser to the beginning of the f_has() function (Yasuhiro Matsumoto). closes: vim/vim#19550 https://github.com/vim/vim/commit/327e0e34c907abafbf356700705a3676c036ca65 Co-authored-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
2026-02-27vim-patch:partial:9.2.0068: Inefficient use of list_append_string() (#38083)zeertzjq3
Problem: Inefficient use of list_append_string() Solution: Pass string length to list_append_string() where it is known (John Marriott). closes: vim/vim#19491 https://github.com/vim/vim/commit/455d62e38a75572bccc43e42d20b5db3c4b22ec3 N/A patches: vim-patch:9.2.0063: memory leak in type_name_list_or_dict() vim-patch:9.2.0065: memory leak in invoke_sync_listeners() vim-patch:9.2.0066: memory leak in build_drop_cmd() vim-patch:9.2.0067: memory leak in dict_extend_func() Co-authored-by: John Marriott <basilisk@internode.on.net>
2026-02-25feat(startup): provide v:argf for file arguments #35889Sanzhar Kuandyk1
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']
2026-02-22vim-patch:9.2.0031: Inefficient use of ga_concat()zeertzjq3
Problem: Inefficient use of ga_concat() Solution: Use ga_concat_len() when the length is already known to avoid use of strlen() (John Marriott). closes: vim/vim#19422 https://github.com/vim/vim/commit/ed202035b1904c84d92adb76d7e1a95b7540e048 Co-authored-by: John Marriott <basilisk@internode.on.net> Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
2026-02-20feat(highlight): support more SGR attributes #37901Riccardo Mazzarini1
Problem: TUI does not support several standard SGR text attributes: - dim/faint (SGR 2) - blink (SGR 5) - conceal (SGR 8) - overline (SGR 53) This means that when a program running in the embedded terminal emits one of these escape codes, we drop it and don't surface it to the outer terminal. Solution: - Add support for those attributes. - Also add corresponding flags to `nvim_set_hl` opts, so users can set these attributes in highlight groups. - refactor(highlight): widen `HlAttrFlags` from `int16_t` to `int32_t` Widen the `rgb_ae_attr` and `cterm_ae_attr` fields in HlAttrs from int16_t to int32_t to make room for new highlight attribute flags, since there was only one spare bit left. - The C flag is named HL_CONCEALED to avoid colliding with the existing HL_CONCEAL in syntax.h (which is a syntax group flag, not an SGR attribute). - Also note that libvterm doesn't currently support the dim and overline attributes, so e.g. `printf '\e[2mThis should be dim\n'` and `printf '\e[53mThis should have an overline\n'` are still not rendered correctly when run from the embedded terminal.
2026-02-19fix(memfile): avoid potential crash on OOM (#37946)zeertzjq1
When running out of memory in a libuv callback, try_to_free_memory() will call mf_release_all(). In this case, mf_sync() cannot call os_breakcheck() as it'll run the libuv loop recursively, so check main_loop.recursive to prevent that. Also fix another possible problem that a terminal buffer may have a swapfile when encountering an OOM in e.g. terminal_alloc().
2026-02-17fix(prompt): clear undo when changing/appending promptSean Dewar1
Problem: undoing after the prompt is changed breaks it (and causes init_prompt to abort it and append a new one), as the undo history contains the old prompt. Solution: like submitting, clear the undo buffer. Don't do it in init_prompt if the line was empty; that may not result in a new prompt, and causes commands like "S" to lose the history. As u_save, etc. wasn't being called by prompt_setprompt, undoing after it fixes the prompt usually gave undesirable results anyway. Remove the added undo_spec.lua test, as its approach no longer works as a repro, and finding a new one seems fiddly.
2026-02-17fix(prompt): prompt_setprompt cursor col adjustmentSean Dewar1
Problem: prompt_setprompt adjusted cursor col may be negative (<=0 when 1-based), and doesn't check the col of ': Solution: avoid negative col and adjust correctly if ': col differs from old prompt's length.
2026-02-17fix(prompt): prompt_setprompt with unloaded buffer, ': with lnum 0Sean Dewar1
Problem: prompt_setprompt memory leak/other issues when fixing prompt line for unloaded buffer, or when ': line number is zero. Solution: don't fix prompt line for unloaded buffer. Clamp ': lnum above zero.
2026-02-16Merge #37875 prompt-buffer fixesJustin M. Keyes1
2026-02-16fix(terminal): handle opening terminal on unloaded buffer (#37894)zeertzjq1
Problem: Strange behavior when opening terminal on unloaded buffer. Solution: For nvim_open_term() ensure the buffer is loaded as it needs to be read into the terminal. For jobstart() just open the memfile as the file content isn't needed. Not going to make nvim_open_term() pass stdin to the terminal when stdin isn't read into a buffer yet, as other APIs don't read stdin on unloaded buffer either. There are also other problems with loading buffer before reading stdin, so it's better to address those in another PR.
2026-02-16vim-patch:9.1.1954: Setting a byte in a blob, accepts values outside 0-255zeertzjq1
Problem: Setting a byte in a blob, accepts values outside 0-255 Solution: When setting a byte in a blob, check for valid values (Yegappan Lakshmanan) closes: vim/vim#18870 https://github.com/vim/vim/commit/f4a299700e211a728f0f7398eb8fceaf44165711 Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2026-02-16vim-patch:partial:9.1.1668: items() does not work for Blobszeertzjq1
Problem: items() does not work for Blobs Solution: Extend items() to support Blob (Yegappan Lakshmanan). closes: vim/vim#18080 https://github.com/vim/vim/commit/da34f84847d40dc5b1eaad477440e513968047dc Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2026-02-16vim-patch:8.2.3841: Vim9: outdated TODO items, disabled tests that work (#37900)zeertzjq3
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>
2026-02-15fix(prompt): prompt_setprompt does not adjust extmarks, no on_bytesSean Dewar1
Problem: prompt_setprompt does not adjust extmarks or trigger on_bytes buffer-updates when fixing the prompt line. Solution: adjust them, trigger on_bytes. Notably, hides extmarks when replacing the entire line (and clearing user input). Otherwise, when just replacing the prompt text, hides extmarks there, but moves those after (in the user input area) to the correct spot.
2026-02-15fix(prompt): wrong cursor col after prompt_setprompt, no on_linesSean Dewar1
Problem: prompt_setprompt calls coladvance with a byte column, but it expects a screen column. on_lines buffer-updates aren't fired when fixing the prompt line. Solution: don't use coladvance. Call changed_lines, which also simplifies the redraw logic. (and calls changed_cline_bef_curs if needed; added test checks this) Unlike https://github.com/neovim/neovim/pull/37743/changes#r2775398744, this means &modified is set by prompt_setprompt if it fixes the prompt line. Not setting &modified is inconsistent anyway -- even init_prompt sets it if it fixes the prompt line.
2026-02-15fix(prompt): prompt_setprompt sets cursor col unnecessarilySean Dewar1
Problem: prompt_setprompt adjusts the cursor's column number even when it's not on the prompt's line. Solution: only adjust when on the prompt's line.
2026-02-15fix(prompt): heap-buffer-overflows with invalid ': colSean Dewar1
Problem: heap-buffer-overflow in init_prompt and prompt_setprompt if ': mark has an invalid column number. Solution: consider an out-of-bounds column number as a missing prompt. Remove the check for NULL for old_line, as ml_get_buf can't return NULL.
2026-02-15fix(prompt): heap-buffer-overflow in prompt_setpromptSean Dewar1
Problem: prompt_setprompt may check the wrong buffer, which can lead to a heap-buffer-overflow. Solution: don't use curbuf. Also replace all kCallbackNone initializers with CALLBACK_INIT.
2026-02-14feat(prompt): plugins can update prompt during user input #37743Shadman1
Problem: Currently, if prompt gets changed during user-input with prompt_setprompt() it only gets reflected in next prompt. And that behavior is not also consistent. If user re-enters insert mode then the user input gets discarded and a new prompt gets created with the new prompt. Solution: Handle prompt_setprompt eagerly. Update the prompt display, preserve user input.
2026-02-14fix(restart): append `-c <cmd>` at end, drop `-- [files…]` #37846Justin M. Keyes1
Problem: - `:restart <cmd>` prepends `-c <cmd>` before the original `-c` args (if any). So the original `-c` args may "override" it, which is surprising. - Confusing logic: `v:argv` is partially prepared in `ex_docmd.c`, and then later `ui.c` skips other parts of it. Current behavior is nonsense, for example this sequence: :restart echo "Hello" :restart +qall echo "Hello" | echo "World" results in this v:argv: [ 'nvim' '-c' 'echo "Hello" | echo "World"' '--embed' '-c' 'echo "Hello"' ... ] Whereas after this commit, v:argv is: [ 'nvim' '--embed' ... '-c' 'echo "Hello" | echo "World"' ] Solution: - Append `-c <cmd>` at the _end_ of `v:argv`, not the start. - Use a dummy placeholder `+:::` to mark where the "restart command" appears in `v:argv`. - Do all `v:argv` preparation in `ex_docmd.c`. This simplifies `ui.c`. - Drop `-- [files…]` from `v:argv` since it is probably more annoying than useful. (Users can use sessions to restore files on restart.)
2026-02-13fix: wait() checks condition twice on each interval (#37837)zeertzjq1
Problem: wait() checks condition twice on each interval. Solution: Don't schedule the due callback. Also fix memory leak when Nvim exits while waiting. No test that the condition isn't checked twice, as testing for that can be flaky when there are libuv events from other sources.
2026-02-08fix(messages): unwanted newlines with ext_messages #37733luukvbaal1
Problem: Newlines intended to write messages below the cmdline or to mark the start of a new message on message grid are emitted through ext_messages. This results in unnecessary newlines for a UI that has decoupled its message area from the cmdline. msg_col is set directly in some places which is not transmitted to msg_show events. Various missing message kind for list commands. Trailing newlines on various list commands. Solution: Only emit such newlines without ext_messages enabled. Use msg_advance() instead of setting msg_col directly. Assign them the "list_cmd" kind. Ensure no trailing newline is printed.