aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/vim_spec.lua
Commit message (Collapse)AuthorAge
* fix(lua): str_byteindex() can return an index past the end #41766Qatadaha Bin Matloob2026-09-27
| | | | | | | | | | | | | | | | Problem: For an incomplete sequence at the end of the string, utf_ptr2len_len() reports more bytes than are there, and mb_utf_index_to_bytes() returns that position unclamped: vim.str_byteindex('ab\xf0\x9f', 'utf-16', 3, false) --> 6 on a 4 byte string. LSP callers use the result as a column, so nvim_buf_set_extmark() then fails with "Invalid 'col': out of range". Solution: Clamp the returned byte index to the length of the string. AI-assisted
* test: fix wrong order of args to eq(), neq() #41499zeertzjq2026-08-26
|
* fix(ui2): ui2 misinterprets getchar() input as pager_char (CR) #41465Justin M. Keyes2026-08-24
| | | | | | | | | | Problem: `vim.on_key()` callbacks are invoked for keys that `getchar()` consumes, which never reach the main loop, and there is no way to tell such a key apart. With ui2 the `on_key` handler activated after interactive cmdline, handles it as `pager_char` (thus enters the ui2 pager). Solution: Skip `vim.on_key()` callbacks during `getchar()`/`getcharstr()`.
* fix(lua): don't limit indexed vim.cmd positional argument count (#41317)zeertzjq2026-08-16
|
* fix(lua): vim.regex():match_str abort in Luv callback #41008Justin M. Keyes2026-07-27
|
* fix(api): add `lhs` option for keymap deletionBarrett Ruth2026-07-25
|
* test(harness): migrate away from magic globalsJustin M. Keyes2026-07-21
| | | | | | | | | | | | | | | | | | | | | Problem: The magic globals `it`, `describe`, etc., are more trouble than they are worth. - Hooking into `after_each` requires `getfenv()` hacks. - They confuse luals/emmylua, because the top-level `.luarc.json` isn't merged with `test/.luarc.json` (apparently a luals limitation?) - They totally defeat discoverability because the user just has to "know" about the various magic symbols. So they harm DX, which means they serve no purpose at all. Solution: - Expose the test API from `testutil`, so tests can call `t.it()`, `t.describe()`, etc., in the conventional way. - Drop `getfenv()` hacks. - Drop the `setfenv()` injection in `load_chunk`. - Drop `test/_meta.lua`.
* vim-patch:9.2.0769 conversion to utf-16be using iconv is inconsistent #40567Manoj Panda2026-07-04
| | | | | | | | | | | | | | | | | | | | fix(iconv): conversion to utf-16be using iconv is inconsistent vim-patch:9.2.0769 Problem: enc_canonize function changes utf-16be to utf-16 but in linux type utf-16 defaults to utf-16le. Solution: Creating a separate entry for utf-16be in enc_canon_table. Note: the effect is only visible on iconv implementations that treat "utf-16" and "utf-16be" differently, so the test does not necessarily fail on an unpatched Vim. But the bug is visible in vim.iconv. (Manoj Panda) from: vim/vim@2a63f74 closes: neovim#40262 Signed-off-by: Manoj Panda <manojpandawork@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
* feat(lua): support table `lhs` in vim.keymap.set()/del() #39948Olivia Kinnear2026-05-29
| | | | | | | | | | | | | | | | | Problem: It is repetitive to map multiple keymaps to do the same thing. Here are some cases where being able to do this would be useful: -- Visual movement for both j/k and down/up: vim.keymap.set({ 'n', 'x' }, { 'j', '<Down>' }, 'v:count == 0 ? "gj" : "j"', { expr = true }) vim.keymap.set({ 'n', 'x' }, { 'k', '<Up>' }, 'v:count == 0 ? "gk" : "k"', { expr = true }) -- Map multiple keys to `<Nop>` concisely: vim.keymap.set({ 'n', 'x' }, { '<Leader>', '<Localleader>', '<CR>' }, '<Nop>') -- Remove multiple keymaps at once: vim.keymap.del('n', { 'gri', 'grn', 'grr' }) Solution: Support the `lhs` of `vim.keymap.set()` and `vim.keymap.del()` being a table, in the same way that `modes` can be.
* refactor: group nvim_buf_call, nvim_win_call tests #39828Justin M. Keyes2026-05-17
|
* Merge #39730 from ofseed/lsp-remove-deprecatedJustin M. Keyes2026-05-11
|\
| * refactor!: remove deprecated APIsYi Ming2026-05-11
| |
* | fix(lua): vim.wait(0) does not call loop_poll #39679Justin M. Keyes2026-05-10
|/ | | | | | | | | | | Problem: Regression from c822a2657c78: `vim.wait(0)` does not call `loop_poll`, so `vim.wait(1)` is needed to "yield" from Lua. Solution: - Ensure that `vim._core.loop_poll()` is always called, even when `time=0`. - Document how to interrupt Lua code (ctrl-c). ref https://github.com/neovim/neovim/issues/6800
* feat(lua)!: vim.isnil, vim.nonnil, deprecate vim.F #39495Olivia Kinnear2026-05-06
|
* fix(lua): avoid `__index` when deciding if a table is a list #39556Yi Ming2026-05-05
| | | | | | | Problem: When a table has `__index`, `vim.islist` is unreliable. Solution: Index using `rawget`.
* refactor(lua): move vim.wait into runtime LuaLewis Russell2026-04-27
| | | | | | | | | | | | | | Move vim.wait into runtime/lua/vim/_core/editor.lua and replace the C entrypoint with narrow vim._core helpers for polling, UI flushing, and interrupt checks. Keep the existing interval semantics by retaining the dummy timer that wakes the loop while it is otherwise idle. Update the docs to describe the success return values correctly, and adjust the test expectation for the new vim.validate() callback error. AI-assisted: Codex
* perf(vim.fn): call Lua-implemented vim.fn.xx() directly #39166Justin M. Keyes2026-04-17
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* test: replace busted with local harnessLewis Russell2026-04-15
| | | | | | | | | | | | | | | | | | | 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
* fix(lua): make vim.deep_equal cycle-safeLewis Russell2026-04-15
| | | | AI-assisted: Codex
* fix(messages): truncate warning messages only in display (#38901)zeertzjq2026-04-09
| | | | For now, add a private "_truncate" flag to nvim_echo, using a truncation method similar to showmode().
* fix(lua): drop support for boolean `buf` in `vim.keymap` #38432skewb1k2026-03-23
| | | | | | | | | | | 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.
* feat(lua): replace `buffer` with `buf` in vim.keymap.set/del #38360skewb1k2026-03-21
| | | | | | 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`.
* fix: wait() checks condition twice on each interval (#37837)zeertzjq2026-02-13
| | | | | | | | 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.
* fix(lua): close vim.defer_fn() timer if vim.schedule() failed (#37647)zeertzjq2026-02-01
| | | | | | | | 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.
* build: move shared.lua to _core/Justin M. Keyes2025-12-30
|
* docs(lua): iInconsistent vim.keymap param name #37026Bryan Turns2025-12-20
| | | | | | | | 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'.
* fix(lua): relax `vim.wait()` timeout validation #36900skewb1k2025-12-10
| | | | | | | | | 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.
* fix(lua): vim.wait(math.huge) fails #36885skewb1k2025-12-09
| | | | | | | | | | 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`.
* fix(input): discard following keys when discarding <Cmd>/K_LUA (#36498)zeertzjq2025-11-20
| | | | | | | | | | | 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.
* feat(vimscript): log function name in "fast" message #32616Matthieu Coudron2025-10-21
|
* feat(lua): vim.wait() returns callback results #35588Justin M. Keyes2025-09-01
| | | | | | | | | | | | | | | | | | 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)
* feat(lua): vim.list.bisect() #35108Yi Ming2025-08-03
|
* feat(lua): add vim.list.unique()Lewis Russell2025-07-28
| | | | | | | | Problem: No way to deduplicate values in a list in-place Solution: Add `vim.list.unique()`
* test: move lua option/variable tests to a separate fileLewis Russell2025-07-03
|
* refactor: option testsLewis Russell2025-07-03
|
* perf(runtime): vim.trim for long only whitespace stringsmonkoose2025-05-26
|
* vim-patch:9.1.1407: Can't use getpos('v') in OptionSet when using ↵zeertzjq2025-05-25
| | | | | | | | | | | 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
* fix(lua): vim.validate `message` param #33675Justin M. Keyes2025-05-04
| | | | | | | Problem: vim.validate does not handle `message` param. Solution: Add the missing logic.
* refactor(lua): swap value params in `tbl_extend` behavior callback #33847Maria José Solano2025-05-04
|
* feat(messages): cleanup Lua error messagesJustin M. Keyes2025-05-04
| | | | | "Error" in error messages is redundant. Just provide the context, don't say "Error ...".
* feat(lua): function `behavior` for tbl_extend, tbl_deep_extend #33819Maria José Solano2025-05-03
|
* feat(build): build.zig MVP: build and run functionaltests on linuxbfredl2025-05-02
| | | | | | | | | | | | | | | | | | | | | 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
* feat(options): default statusline expression #33036Shadman2025-04-21
| | | | | | | | | | 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.
* vim-patch:8.2.4603: sourcing buffer lines is too complicatedzeertzjq2025-02-28
| | | | | | | | | | | | | | | | | | | | | | | | 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>
* fix(lua): vim.tbl_get({}, nil, 1) should return nil #32218phanium2025-02-09
| | | | | | | | | | | | | | | 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.
* docs: misc #31867Justin M. Keyes2025-01-09
|
* fix(api): generic error messages, not using TRY_WRAP #31596Justin M. Keyes2024-12-16
| | | | | | | | | | | 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.
* fix(messages)!: vim.ui_attach message callbacks are unsafeLuuk van Baal2024-11-14
| | | | | | | | 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.
* fix(tests): needing two calls to setup a screen is cringebfredl2024-11-14
| | | | | | | | | | 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.
* fix(lua): show stacktrace for error in vim.on_key() callback (#31021)zeertzjq2024-11-02
|