summaryrefslogtreecommitdiffstatshomepage
path: root/test/functional/api
AgeCommit message (Collapse)AuthorFiles
2026-04-24fix(api): leak preview callback LuaRef in nvim_create_user_command #39357Barrett Ruth1
Problem: Invalid `nvim_create_user_command` calls can leak the `preview` callback reference after Neovim has taken ownership of it. 1. build with {a,l}san 2. run: ```sh <path/to/nvim> --headless -u NONE --clean +'lua for i = 1, 100 do pcall(vim.api.nvim_create_user_command, "some very epic stuff" .. i, {}, -- NOTE: this is INVALID (not a function or string) { preview = function() end }) end vim.cmd("qa!") ' +qa ``` 3. see: ``` 100 lua references were leaked! ``` Solution: Clear `preview_luaref` in `err:`.
2026-04-24fix(api): LuaRef leak in nvim_set_keymap on LHS too long (>=66 bytes) #39351Barrett Ruth1
Problem: `nvim_set_keymap` leaks the `callback` `LuaRef` when the LHS is too long. Solution: Make `set_maparg_lhs_rhs` transfer `rhs_lua` to `MapArguments` up front so the caller always owns the ref.
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-20refactor(test): drop deprecated exc_exec #39242Justin M. Keyes1
2026-04-20fix(api): expose fg_indexed/bg_indexed in nvim_get_hl #39210glepnir1
Problem: fg_indexed/bg_indexed were dropped from nvim_get_hl output due to a wrong short_keys guard. HL_FG_INDEXED also wasn't cleared in hl_blend_attrs, and HLATTRS_DICT_SIZE was too small. Solution: Remove the short_keys guard, clear HL_FG_INDEXED in hl_blend_attrs, bump HLATTRS_DICT_SIZE to 24, and clarify docs that these flags mean rgb is an approximation of the cterm palette index.
2026-04-19feat(options): add 'winpinned' to pin a window #39157luukvbaal1
Problem: - Unable to "pin" a window to prevent closing without specifically being targeted. - :fclose closes hidden windows (even before visible windows). Solution: - Add 'winpinned' window-local option. When set, window is skipped by :fclose and :only. Pin the ui2 cmdline window (which should always be visible), so that it is not closed by :only/fclose. - Skip over hidden (and pinned) windows with :fclose. Co-authored-by: glepnir <glephunter@gmail.com>
2026-04-18fix(marks): adjust marks when unloading "nofile" buffer #39118luukvbaal1
Problem: Marks are not adjusted unloading a buffer that doesn't exist on disk. E.g. extmarks are still valid (and will be beyond the end of the buffer if the buffer is reloaded), even though the text is lost. Solution: Adjust marks for a cleared buffer when unloading a buffer that doesn't exist on disk.
2026-04-17fix(lsp): limit number of created highlight groups (#39133)Evgeni Chasnovski1
* fix(api): allow silencing "Too many highlight groups" error Problem: Using Lua's `vim.api.nvim_set_hl(0, 'New', {...})` can fail if there are too many existing highlight groups. However, this error can not be silenced with `pcall`. Solution: Make it possible to silence in `nvim_set_hl` and `nvim_get_hl_id_by_name`. * fix(lsp): limit number of groups created by `document_color()` Problem: A file can contain many string colors that would be highlighted by an LSP server. If this number crosses 19999 (maximum number of allowed highlight groups), there are general issues with creating other highlight groups, which can break functionality outside of `vim.lsp.document_color`. Solution: Limit number of highlight groups that are created by `vim.lsp.document_color` to 10000 (half of allowed maximum). This is not a 100% solution (since there can exist more than 10000 other highlight groups), but explicitly checking number of groups is slow and 10000 should (hopefully) be enough for most use cases.
2026-04-18fix(terminal): forward streamed bracketed paste properly (#39152)zeertzjq1
2026-04-13feat(api): rename buffer to buf in retval #38900Justin M. Keyes3
In 3a4a66017b74192caaf9af9af172bdc08e0c1608, 4d3a67cd620152d11ab9b5f5bdd973f84cc2d44b we renamed "buffer" to "buf" in dict parameters. This commit also renames such keys in dict return-values.
2026-04-12feat(api): nvim_set_hl can set "font" #37668glepnir1
Problem: Cannot set highlight group fonts via API, only via :highlight command. Solution: Add font parameter in nvim_set_hl().
2026-04-12fix(api): nvim_get_hl drops groups defined with link_global #38492glepnir1
Problem: hlgroup2dict passes &ns_id to ns_get_hl twice. The first call (link=true) sets *ns_hl = 0 when link_global is set, so the second call and the sg_cleared guard both see ns_id == 0 and bail out. The group is silently dropped from the result. Solution: use a temporary copy of ns_id for each ns_get_hl call so the original value is preserved.
2026-04-11fix(highlight): preserve inherited colors when update=true breaks links #38750glepnir1
Problem: Breaking a link with update=true loses colors inherited from the linked group. Solution: Copy color indices from the linked group so inherited colors remain visible in :hi output.
2026-04-08feat(api): rename buffer to buf #35330Jordan1
Problem: `:help dev-name-common` states that "buf" should be used instead of "buffer" but there are cases where buffer is mentioned in the lua API. Solution: - Rename occurrences of "buffer" to "buf" for consistency with the documentation. - Support (but deprecate) "buffer" for backwards compatibility. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-04-08fix(api)!: nvim_clear_autocmds() "event" handlingSean Dewar1
Problem: nvim_clear_autocmds() does not type check "event" correctly, and also treats an empty array "event" like nil. Solution: fix type checking. Treat empty array "event" as a no-op, like nvim_exec_autocmds(). Add some extra tests. Likewise the nil handling change may be considered breaking if anyone (unintentionally) relied on that. It was also true that integer, function, etc. "event"s would also be treated like nil! Note that an empty string "event" is still an error, as that's must be an exact match on an event name.
2026-04-08docs(api): nvim_exec_autocmds() default "pattern"Sean Dewar1
Problem: nvim_exec_autocmds() documentation incorrectly describes the default for "pattern" as *, when it's actually the current file name (like :doautocmd). Solution: correct it. Add a test.
2026-04-08fix(api)!: empty non-nil autocmd "pattern" handlingSean Dewar1
Problem: in autocmd APIs, a non-nil "pattern" containing only empty 'sub'-patterns is silently treated as nil, causing the fallback value to be unexpectedly used instead. Solution: for nvim_create_autocmd(), raise a validation error (as no autocmds would be created). For nvim_{exec,clear}_autocmds(), make it a no-op (as matching no autocmds is not an error).
2026-04-08fix(rpc): trigger UILeave earlier on channel close (#38846)zeertzjq1
Problem: On exit, rpc_free() is called when processing main_loop.events after libuv calls close callbacks of the channel's stream. However, when there are no child processes, these libuv callbacks are called in loop_close() instead of proc_teardown(), and main_loop.events isn't processed after loop_close(). As a result, calling remote_ui_disconnect() in rpc_free() causes UILeave to depend on the presence of child processes. Solution: Always call remote_ui_disconnect() in rpc_close_event(), and remove the call in rpc_free().
2026-04-01fix(api): avoid error when parsing invalid expr after :echo (#38695)zeertzjq1
Problem: Parsing :echo followed by invalid expression leads to error. Solution: Suppress error when skipping over expression.
2026-03-28docs: news #38464Justin M. Keyes1
2026-03-28fix(api): nvim_set_hl boolean false corrupts underline styles (#38504)glepnir1
Problem: setting one underline style to false clears bits belonging to another style. `{underdouble = true, underdashed = false}` results in undercurl because CHECK_FLAG_WITH_KEY does `m &= ~flag` which doesn't work for multi-bit encoded values sharing HL_UNDERLINE_MASK. Solution: use a local variable to derive the correct clear mask from the flag. Clear the whole HL_UNDERLINE_MASK field instead of individual bits, and only clear on false when the current style actually matches.
2026-03-25feat(api): nvim_set_hl{update:boolean} #37546glepnir1
Problem: nvim_set_hl always replaces all attributes. Solution: Add update field. When true, merge with existing attributes instead of replacing. Unspecified attributes are preserved. If highlight group doesn't exist, falls back to reset mode.
2026-03-19fix(terminal): don't refresh for sync flush when exiting (#38363)zeertzjq1
Fixes the following error log: ERR 2026-03-18T20:17:36.920 T281.9357.0 buf_updates_send_changes:258: Disabling buffer updates for dead channel 1
2026-03-18fix(messages): disallow user-defined integer message-id #38359Justin M. Keyes1
Problem: `nvim_echo(…, {id=…})` accepts user-defined id as a string or integer. Generated ids are always higher than last highest msg-id used. Thus plugins may accidentally advance the integer id "address space", which, at minimum, could lead to confusion when troubleshooting, or in the worst case, could overflow or "exhaust" the id address space. There's no use-case for it, and it could be the mildly confusing, so we should just disallow it. Solution: Disallow *integer* user-defined message-id. Only allow *string* user-defined message-id.
2026-03-18fix(api): nvim_get_option_value FileType autocmd handling #37414Sean Dewar1
Problem: nvim_get_option_value with "filetype" set silently returns incorrect defaults if autocommands are blocked, like when they're already running. Solution: Allow its FileType autocommands to nest: `do_filetype_autocmd(force=true)`. Also error if executing them fails, rather than silently return wrong defaults. Endless nesting from misbehaving scripts should be prevented by the recursion limit in apply_autocmds_group, which is 10.
2026-03-17docs: api, lsp, messages, intro #38327Justin M. Keyes1
2026-03-16fix(api): use standard error messagesJustin M. Keyes7
2026-03-16fix(api): nvim_open_tabpage positional "enter"Sean Dewar1
Problem: nvim_open_tabpage's "enter" argument is optional, which is inconsistent with nvim_open_win. Solution: make it a (non-optional) positional argument, like nvim_open_win. Also change "enter"'s description to be more like nvim_open_win's doc.
2026-03-16fix(api): nvim_open_tabpage "after" like :[count]tabSean Dewar1
Problem: "after" in nvim_open_tabpage is inconsistent with how a count works with :tab, :tabnew, etc. Plus, the name "after" implies it's inserted after that number. Solution: internally offset by 1. Allow negative numbers to mean after current. Hmm, should we even reserve sentinels for after current? Callers can probably just use nil...
2026-03-16fix: nvim_open_tabpage cleanup, fixes, more testsSean Dewar1
- Cleanup, remove redundant comments, add more tests. - Enhance win_new_tabpage rather than create a new function for !enter, and use a different approach that minimizes side-effects. Return the tabpage_T * and first win_T * it allocated. - Disallow during textlock, like other APIs that open windows. - Remove existing win_alloc_firstwin error handling from win_new_tabpage; it's not needed, and looks incorrect. (enter_tabpage is called for curtab, which is not the old tabpage! Plus newtp is not freed) - Fix checks after creating the tabpage: - Don't fail if buf wasn't set successfully; the tab page may still be valid regardless. Set buffer like nvim_open_win, possibly blocking Enter/Leave events. (except BufWinEnter) - tp_curwin may not be the initial window opened by win_new_tabpage. Use the win_T * it returns instead, which is the real first window it allocated, regardless of autocmd shenanigans. - Properly check whether tab page was freed; it may have also been freed before win_set_buf. Plus, it may not be safe to read its handle!
2026-03-16feat(api): add nvim_open_tabpageWill Hopkins1
Problem: no API function for opening a new tab page and returning its handle, or to open without entering. Solution: add nvim_open_tabpage.
2026-03-14fix(api): improve external window validationSean Dewar1
Problem: "win" is allowed in external window configs in some cases. External window converted to normal float can't move tabpages in one nvim_win_set_config call. External window can't be turned into a normal split. Solution: disallow setting "win" for external windows. Allow external window to move tabpages, which turns it non-external. Allow external window to be turned into a (non-external) split. parse_win_config has more validation issues from not considering the window's existing config enough (not from this PR). For example, zindex can be set for an existing split if "split"/"vertical" isn't given, despite intending for that to be an error. Plus the logic is confusing. It could do with a refactor at some point...
2026-03-14fix(api): disallow moving window between tabpages in more casesSean Dewar1
Problem: more cases where it may not be safe to move a window between tabpages. Solution: check them. Rather speculative... I haven't spend much time looking, but I didn't find existing code that sets these locks to skip checking win_valid. (what I did find called it anyway, like in win_close) Still, I think it's a good precaution for what future code might do. If the fact that nvim_win_set_config *actually* moves windows between tabpages causes unforeseen issues, "faking" it like ":wincmd T" may be an alternative: split a new window, close the old one, but instead also block autocmds, copy the old window's config, and give it its handle?
2026-03-14feat(api): nvim_win_set_config can move split to other tp as floatwinSean Dewar1
Problem: not possible for nvim_win_set_config to convert a split to a floatwin, then move it to another tabpage in one call. Solution: allow it.
2026-03-14fix(winfloat): last_status when changing split to floatwinSean Dewar1
Problem: converting a split to a floatwin may not remove the last statusline when needed. (e.g: 'ls' is 1) Solution: call last_status/win_comp_pos in win_new_float, after win_remove. Also fix float_pos formatting for screen snapshots so it doesn't give a nil error for external windows. Not an issue from this PR.
2026-03-14fix(api): relax config validation for "win"Sean Dewar1
Problem: only possible to move floats between tabpages if relative=win, which has the restrictive effect of also anchoring it to the target window. Solution: allow "win" without "relative" or "split"/"vertical". Only assume missing "win" is 0 if relative=win is given to maintain that behaviour. (or when configuring a new window) Also add an error when attempting to change a split into a float that's in another tabpage, as this isn't actually supported yet. (until the next commit) Maybe this could do with some bikeshedding. Unclear if "win" should require "relative" to be given, like with "row"/"col"; this can be annoying though as specifying "relative" requires other fields to be given too.
2026-03-14refactor(api): cleanup, more comments, more tests, newsSean Dewar1
- Factor out logic to keep nvim_win_set_config clean. - Clean up a few things, remove redundant logic, reflow some lines. - Add some more comments where appropriate. - Don't consider negative "win", as that's only relevant for splits. - Add more test coverage. - Add news.txt entry.
2026-03-14feat(api): nvim_win_set_config can move floatwin to another tabpageglepnir1
Problem: nvim_win_set_config can't move floating windows to different tab pages. Solution: allow it. Co-authored-by: Sean Dewar <6256228+seandewar@users.noreply.github.com>
2026-03-14fix(messages): allocate message history kind string #38292luukvbaal1
Problem: nvim_echo()->kind memory may be used after it is freed with :messages. Solution: Copy and free message kind string in message history.
2026-03-14fix(window): don't leak fold memory with style=minimal #38287Sean Dewar1
Problem: discarding saved option values in the WinInfo of closed style=minimal windows leaks memory. Solution: also free the nested folds.
2026-03-13docs: miscJustin M. Keyes1
2026-03-13fix(api): nvim_parse_cmd on range-only, modifier-only commands #36665glepnir1
Problem: nvim_parse_cmd rejects valid commands like `:1` (range-only) or `aboveleft` (modifier-only). Solution: allow empty command when range or modifiers exist, and handle execution using existing range command logic.
2026-03-12docs: use "ev" convention in event-handlersJustin M. Keyes1
Problem: In autocmd examples, using "args" as the event-object name is vague and may be confused with a user-command. Solution: Use "ev" as the conventional event-object name.
2026-03-12fix(process): wrong exit code for SIGHUP on Windows (#38242)zeertzjq1
Problem: When stopping a PTY process on Windows, the exit code indicates that the process is stopped by SIGTERM even when closing all streams is enough to terminate the process. This is inconsistent with other platforms. Solution: Set exit_signal to SIGHUP instead of SIGTERM when using SIGHUP.
2026-03-11docs: deprecate hit-enterJustin M. Keyes1
2026-03-11test(api/vim_spec): fix flaky test (#38227)zeertzjq1
Problem: Exit code in :terminal channel test depends on whether the shell or Nvim TUI in the terminal has registered its SIGHUP handler when jobstop() is called. Solution: Don't use a shell as shells on different systems may handle SIGHUP differently. Add a screen:expect() to wait for the TUI to start.
2026-03-10fix(message): concatenate multi-chunk nvim_echo({err}) for exception message ↵luukvbaal1
#38131 Problem: Exception error message only prints the first chunk of a multi-chunk nvim_echo() message. Solution: Concatenate consecutive message chunks in the exception message list.
2026-03-10feat(terminal): surface exit code via virttext + nvim_get_chan_info #37987Ayaan1
Problem: When a terminal process exits, "[Process Exited]" text is added to the buffer contents. Solution: - Return `exitcode` field from `nvim_get_chan_info`. - Show it in the default 'statusline'. - Show exitcode as virtual text in the terminal buffer.
2026-03-09feat(extmark): support end_col=-1 if strict=false #28169Stefan Novaković1
Problem: There is an inconsistency between extmarks/highlights regarding the `end_col` param. Solution: Allow end_col=-1 to mean "end of line" (if strict=false). Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-03-09Merge #38206 nvim_win_set_configJustin M. Keyes1