summaryrefslogtreecommitdiffstatshomepage
path: root/test/functional/lua/vim_spec.lua
AgeCommit message (Collapse)AuthorFiles
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-15test: replace busted with local harnessLewis Russell1
Replace the busted-based Lua test runner with a repo-local harness. The new harness runs spec files directly under `nvim -ll`, ships its own reporter and lightweight `luassert` shim, and keeps the helper/preload flow used by the functional and unit test suites. Keep the file boundary model shallow and busted-like by restoring `_G`, `package.loaded`, `package.preload`, `arg`, and the process environment between files, without carrying extra reset APIs or custom assertion machinery. Update the build and test entrypoints to use the new runner, add black-box coverage for the harness itself, and drop the bundled busted/luacheck dependency path. AI-assisted: Codex
2026-04-15fix(lua): make vim.deep_equal cycle-safeLewis Russell1
AI-assisted: Codex
2026-04-09fix(messages): truncate warning messages only in display (#38901)zeertzjq1
For now, add a private "_truncate" flag to nvim_echo, using a truncation method similar to showmode().
2026-03-23fix(lua): drop support for boolean `buf` in `vim.keymap` #38432skewb1k1
Problem: `vim.keymap.*.Opts.buf` allows `boolean` aliases for more widely used `integer?` values, `true` -> `0` and `false` -> `nil`. This conversion is unnecessary and can be handled at call sites. Solution: As a follow-up to deprecating the `buffer` option, drop support for boolean values for the new `buf` option. The deprecated `buffer` continues to support booleans for backward compatibility.
2026-03-21feat(lua): replace `buffer` with `buf` in vim.keymap.set/del #38360skewb1k1
The `buffer` option remains functional but is now undocumented. Providing both will raise an error. Since providing `buf` was disallowed before, there is no code that will break due to using `buffer` alongside `buf`.
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-01fix(lua): close vim.defer_fn() timer if vim.schedule() failed (#37647)zeertzjq1
Problem: Using vim.defer_fn() just before Nvim exit leaks luv handles. Solution: Make vim.schedule() return an error message if scheduling failed. Make vim.defer_fn() close timer if vim.schedule() failed.
2025-12-30build: move shared.lua to _core/Justin M. Keyes1
2025-12-20docs(lua): iInconsistent vim.keymap param name #37026Bryan Turns1
Problem: vim.keymap.del has 'modes' as it's first argument while vim.keymap.set has 'mode' as it's first argument despite both 'mode' and 'modes' taking in the same type input of String or String[]. Solution: Updated vim.keymap.set docs to refer to it's first argument as 'modes'.
2025-12-10fix(lua): relax `vim.wait()` timeout validation #36900skewb1k1
Problem: After bc0635a9fc9c15a2423d4eb35f627d127d00fa46 `vim.wait()` rejects floats and NaN values. Solution: Restore the prior behavior, while still supporting `math.huge`. Update tests to cover float case.
2025-12-09fix(lua): vim.wait(math.huge) fails #36885skewb1k1
Problem: `nlua_wait()` uses `luaL_checkinteger()` which doesn't support `math.huge` since it's double type. On PUC Lua this fails with 'number has no integer representation' error and on LuaJIT this overflows int. Solution: Use `luaL_checknumber()` and handle `math.huge`.
2025-11-20fix(input): discard following keys when discarding <Cmd>/K_LUA (#36498)zeertzjq1
Technically the current behavior does match documentation. However, the keys following <Cmd>/K_LUA aren't normally received by vim.on_key() callbacks either, so it does makes sense to discard them along with the preceding key. One may also argue that vim.on_key() callbacks should instead receive the following keys together with the <Cmd>/K_LUA, but doing that may cause some performance problems, and even in that case the keys should still be discarded together.
2025-10-21feat(vimscript): log function name in "fast" message #32616Matthieu Coudron1
2025-09-01feat(lua): vim.wait() returns callback results #35588Justin M. Keyes1
Problem: The callback passed to `vim.wait` cannot return results directly, it must set upvalues or globals. local rv1, rv2, rv3 local ok = vim.wait(200, function() rv1, rv2, rv3 = 'a', 42, { ok = { 'yes' } } return true end) Solution: Let the callback return values after the first "status" result. local ok, rv1, rv2, rv3 = vim.wait(200, function() return true, 'a', 42, { ok = { 'yes' } } end)
2025-08-03feat(lua): vim.list.bisect() #35108Yi Ming1
2025-07-28feat(lua): add vim.list.unique()Lewis Russell1
Problem: No way to deduplicate values in a list in-place Solution: Add `vim.list.unique()`
2025-07-03test: move lua option/variable tests to a separate fileLewis Russell1
2025-07-03refactor: option testsLewis Russell1
2025-05-26perf(runtime): vim.trim for long only whitespace stringsmonkoose1
2025-05-25vim-patch:9.1.1407: Can't use getpos('v') in OptionSet when using ↵zeertzjq1
setbufvar() (#34177) Problem: Can't use getpos('v') in OptionSet when using setbufvar(). Solution: Don't reset Visual selection when switching to the same buffer (zeertzjq). closes: vim/vim#17373 https://github.com/vim/vim/commit/5717ee33db0048a496e8bed0b0cb20133b3f76ca
2025-05-04fix(lua): vim.validate `message` param #33675Justin M. Keyes1
Problem: vim.validate does not handle `message` param. Solution: Add the missing logic.
2025-05-04refactor(lua): swap value params in `tbl_extend` behavior callback #33847Maria José Solano1
2025-05-04feat(messages): cleanup Lua error messagesJustin M. Keyes1
"Error" in error messages is redundant. Just provide the context, don't say "Error ...".
2025-05-03feat(lua): function `behavior` for tbl_extend, tbl_deep_extend #33819Maria José Solano1
2025-05-02feat(build): build.zig MVP: build and run functionaltests on linuxbfredl1
NEW BUILD SYSTEM! This is a MVP implementation which supports building the "nvim" binary, including cross-compilation for some targets. As an example, you can build a aarch64-macos binary from an x86-64-linux-gnu host, or vice versa Add CI target for build.zig currently for functionaltests on linux x86_64 only Follow up items: - praxis for version and dependency bumping - windows 💀 - full integration of libintl and gettext (or a desicion not to) - update help and API metadata files - installation into a $PREFIX - more tests and linters
2025-04-21feat(options): default statusline expression #33036Shadman1
Problem: Default 'statusline' is implemented in C and not representable as a statusline expression. This makes it hard for user configs/plugins to extend it. Solution: - Change the default 'statusline' slightly to a statusline expression. - Remove the C implementation.
2025-02-28vim-patch:8.2.4603: sourcing buffer lines is too complicatedzeertzjq1
Problem: Sourcing buffer lines is too complicated. Solution: Simplify the code. Make it possible to source Vim9 script lines. (Yegappan Lakshmanan, closes vim/vim#9974) https://github.com/vim/vim/commit/85b43c6cb7d56919e245622f4e42db6d8bee4194 This commit changes the behavior of sourcing buffer lines to always have a script ID, although sourcing the same buffer always produces the same script ID. vim-patch:9.1.0372: Calling CLEAR_FIELD() on the same struct twice Problem: Calling CLEAR_FIELD() on the same struct twice. Solution: Remove the second CLEAR_FIELD(). Move the assignment of cookie.sourceing_lnum (zeertzjq). closes: vim/vim#14627 https://github.com/vim/vim/commit/f68517c1671dfedcc1555da50bc0b3de6d2842f6 Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
2025-02-09fix(lua): vim.tbl_get({}, nil, 1) should return nil #32218phanium1
Problem: `vim.tbl_get(tbl, nil, 1)` returns `tbl` itself. In this case, `keys` is not empty, but `ipairs` skips the iteration: local keys = { nil, 1 } assert(#keys == 2) for i, k in ipairs(keys) do assert(false, 'unreachable') end Solution: Use `select("#", ...)` and `select(i, ...)` to ensure consistency for count and iteration.
2025-01-09docs: misc #31867Justin M. Keyes1
2024-12-16fix(api): generic error messages, not using TRY_WRAP #31596Justin M. Keyes1
Problem: - API functions using `try_start` directly, do not surface the underlying error message, and instead show generic messages. - Error-handling code is duplicated in the API impl. - Failure modes are not tested. Solution: - Use `TRY_WRAP`. - Add tests.
2024-11-14fix(messages)!: vim.ui_attach message callbacks are unsafeLuuk van Baal1
Problem: Lua callbacks for "msg_show" events with vim.ui_attach() are executed when it is not safe. Solution: Disallow non-fast API calls for "msg_show" event callbacks. Automatically detach callback after excessive errors. Make sure fast APIs do not modify Nvim state.
2024-11-14fix(tests): needing two calls to setup a screen is cringebfredl1
Before calling "attach" a screen object is just a dummy container for (row, col) values whose purpose is to be sent as part of the "attach" function call anyway. Just create the screen in an attached state directly. Keep the complete (row, col, options) config together. It is still completely valid to later detach and re-attach as needed, including to another session.
2024-11-02fix(lua): show stacktrace for error in vim.on_key() callback (#31021)zeertzjq1
2024-11-01feat(lua): allow vim.on_key() callback to consume the key (#30939)errael1
2024-10-23feat(stdlib): overload vim.str_byteindex, vim.str_utfindex #30735Tristan Knight1
PROBLEM: There are several limitations to vim.str_byteindex, vim.str_utfindex: 1. They throw given out-of-range indexes. An invalid (often user/lsp-provided) index doesn't feel exceptional and should be handled by the caller. `:help dev-error-patterns` suggests that `retval, errmsg` is the preferred way to handle this kind of failure. 2. They cannot accept an encoding. So LSP needs wrapper functions. #25272 3. The current signatures are not extensible. * Calling: The function currently uses a fairly opaque boolean value to indicate to identify the encoding. * Returns: The fact it can throw requires wrapping in pcall. 4. The current name doesn't follow suggestions in `:h dev-naming` and I think `get` would be suitable. SOLUTION: - Because these are performance-sensitive, don't introduce `opts`. - Introduce an "overload" that accepts `encoding:string` and `strict_indexing:bool` params. ```lua local col = vim.str_utfindex(line, encoding, [index, [no_out_of_range]]) ``` Support the old versions by dispatching on the type of argument 2, and deprecate that form. ```lua vim.str_utfindex(line) -- (utf-32 length, utf-16 length), deprecated vim.str_utfindex(line, index) -- (utf-32 index, utf-16 index), deprecated vim.str_utfindex(line, 'utf-16') -- utf-16 length vim.str_utfindex(line, 'utf-16', index) -- utf-16 index vim.str_utfindex(line, 'utf-16', math.huge) -- error: index out of range vim.str_utfindex(line, 'utf-16', math.huge, false) -- utf-16 length ```
2024-10-21feat(vim.validate): improve fast form and deprecate spec formLewis Russell1
Problem: `vim.validate()` takes two forms when it only needs one. Solution: - Teach the fast form all the features of the spec form. - Deprecate the spec form. - General optimizations for both forms. - Add a `message` argument which can be used alongside or in place of the `optional` argument.
2024-10-21test(rpc): retry flaky 'vim.rpcrequest and vim.rpcnotify' testChristian Clason1
Problem: 'vim.rpcrequest and vim.rpcnotify' is flaky on Windows. Solution: retry it.
2024-10-21fix(lua): vim.deprecate does not support major>0Justin M. Keyes1
2024-10-12fix(lua): avoid recursive vim.on_key() callback (#30753)zeertzjq1
2024-09-25refactor(lua): vim.keymap.set tests, docs #30511Justin M. Keyes1
2024-09-23refactor(api)!: rename Dictionary => DictJustin M. Keyes1
In the api_info() output: :new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val') ... {'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1} The `ArrayOf(Integer, 2)` return type didn't break clients when we added it, which is evidence that clients don't use the `return_type` field, thus renaming Dictionary => Dict in api_info() is not (in practice) a breaking change.
2024-09-08fix(lua): revert vim.tbl_extend behavior change and document itChristian Clason1
Problem: vim.tbl_deep_extend had an undocumented feature where arrays (integer-indexed tables) were not merged but compared literally (used for merging default and user config, where one list should overwrite the other completely). Turns out this behavior was relied on in quite a number of plugins (even though it wasn't a robust solution even for that use case, since lists of tables (e.g., plugin specs) can be array-like as well). Solution: Revert the removal of this special feature. Check for list-like (contiguous integer indices) instead, as this is closer to the intent. Document this behavior.
2024-09-07test(lua): tbl_deep_extend "after second argument" #30297Justin M. Keyes1
2024-09-04fix(lua): allows tables with integer keys to be merged in tbl_deep_extendLewis Russell1
- The exclusion of lists was never justified in the commit history and is the wrong thing to do for a function that deals with tables. - Move the error checks out of the recursive path. Fixes #23654
2024-09-01docs: misc #28970Justin M. Keyes1
2024-08-14refactor(tests): again yet more global highlight definitionsbfredl1
2024-07-13fix(lua)!: do not use typed table for empty dictAmit Singh1
Problem: Empty dictionaries are converted into typed tables of the form `{ [true] = 6}` instead of an empty dictionary representation `{}`. This leads to incorrect table representation, along with failure in JSON encoding of such tables as currently tables with only string and number type keys can be encoded. Solution: The typed table logic has been removed from `nlua_push_Dictionary`. The typed table logic is required only for float value conversions which is already handled in `nlua_push_Float`. So, it is(was) no longer required here. Fixes neovim/neovim#29218
2024-07-04fix(lua): use rawget() to get __call in vim.is_callable() (#29536)Tyler Miller1
Lua 5.1 uses a "raw get" to retrieve `__call` from a metatable to determine if a table is callable. Mirror this behavior in `vim.is_callable()`.
2024-06-12test: fix vim.deprecate testsLewis Russell1