aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
Commit message (Collapse)AuthorAge
...
* feat(vim.net): request() accepts more http methods #39406Ellison2026-05-01
|
* fix(help): fix CTRL character issue for :help {subject} #39537Yochem van Rosmalen2026-05-01
| | | | | | | | | | | | | Problem: The argument to `:help` is normalized to fit the general tag format. I.e. i^U-default, iCTRL-U-default and i_CTRL_U-default should all point to the i_CTRL_U-default tag. Our normalization adds an underscore around the CTRL keycode, e.g. iCTRL-GCTRL-J becomes i_CTRL-G_CTRL-J. That's not necessary if the following part starts with a dash, like the case of iCTRL-U-default. Solution: Do not insert an underscore if the following character is a dash/minus (-).
* docs: Update instructions for debugging LSP (#39527)Matthew Hughes2026-04-30
| | | | | | | | | | | | | | | | | | | | | docs: update instructions for debugging LSP Previously, it was suggested to set: vim.lsp.log.set_format_func(vim.inspect) This made sense before f72c13341afb3e2459202d3f6e57cd00614c2ab5, when `format_func` was called once per argument being logged, but since that commit it's called with the log level followed by the other args, so the suggested setting would call `vim.inspect(log_level, ....)` which would just print the human readable name of the current log level and no other details, for example with this set I saw in my logs: "DEBUG""DEBUG""DEBUG""DEBUG" Instead just rely on the default formatter, which will: > ... log the level, date, source and line number of the caller, followed by the arguments.
* fix(ui): z=, tselect with async vim.ui.selectJustin M. Keyes2026-04-30
| | | | | | | | | | | Problem: After 55ceb31, z= and tselect don't work if `vim.ui.select` is an async provider (especially terminal buffers). Solution: Drop the `vim.wait()` approach, use an async approach. fix #39506
* feat(ui): use vim.ui.select for :oldfiles, :recoverJustin M. Keyes2026-04-30
| | | | | | | | | | | | Problem: followup to 55ceb314ca96 #39478 `:oldfiles` and swapfile `:recover` do not delegate to `vim.ui.select`. Solution: - Delegate to `vim.ui.select`. - Fix a long-standing `recover_names` bug where `concat_fnames(dir_name, files[i], true)` produced malformed `<dir>//<dir>/<file>` paths (also fixes `swapfilelist()`).
* fix(env): force uppercase environ() keys on Windows #39523Justin M. Keyes2026-04-30
|
* Merge pull request #39469 from bfredl/systempipabfredl2026-04-30
|\ | | | | fix(vim.system): use REAL PIPES for vim.system, similar to jobs
| * fix(vim.system): use REAL PIPES for vim.system, similar to jobsbfredl2026-04-30
| | | | | | | | | | This is essentially the #35991 fix for the #35984 issue, but applied to vim.system().
* | refactor(tty): tty.request() #39489Justin M. Keyes2026-04-30
| | | | | | | | | | | | | | | | Problem: - Various `TermRequest` handlers which all do similar things. - `tty.query` is specific to `XTGETTCAP DCS`, can't be reused for other kinds of terminal queries. Solution: Provide `tty.request()`.
* | vim-patch:9.2.0417: completion: no support for "noinsert" with 'wildmode' ↵glepnir2026-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | (#39516) Problem: completion: no support for "noinsert" with 'wildmode' and commandline completion Solution: Add "noinsert" value to the 'wildmode' option, mirroring 'completeopt' "noinsert" behaviour (glepnir). fixes: vim/vim#16551 closes: vim/vim#20080 https://github.com/vim/vim/commit/af494af5ff188d976073cbc049249614edffa4bf
* | build(lint): allow "bufnr" as positional param #39515Justin M. Keyes2026-04-30
| | | | | | | | | | Allow `bufnr` as a positional param name because it is very common. However as a field name, or part of a function name, it is usually a mistake.
* | fix(lsp): send didClose, didOpen when languageId changes #39499phanium2026-04-30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: If a buffer's filetype changes after the LSP client has already attached (e.g. from json to jsonc via a modeline), but the client supports both filetypes, it stays attached. It does not notify the server of the new languageId, causing the server to incorrectly process the file using the old languageId. Solution: Save the languageId used during textDocument/didOpen, and send textDocument/didClose + textDocument/didOpen when buffer's languageId changed. Lsp spec: https://github.com/microsoft/language-server-protocol/blob/0003fb53f18dc7a4ac7e51d0eb518deeea90fde5/_specifications/lsp/3.18/textDocument/didOpen.md#L5 > If the language id of a document changes, the client > needs to send a textDocument/didClose to the server followed by a > textDocument/didOpen with the new language id if the server handles > the new language id as well. AI-assisted: Gemini 3.1 Pro
* | docs: misc #39511Justin M. Keyes2026-04-29
| |
* | fix(lsp): fix threshold to compute contrast color #39504Ayose C.2026-04-29
| | | | | | | | | | | | | | | | Problem: The threshold to consider a color as bright is too high, and for some colors the foreground is set to white when it should be black. Solution: Change the threshold to 0.179. This value is taken from pastel-textcolor.
* | feat(img): vim.ui.img.del(math.huge) clears all images #39484Chip Senkbeil2026-04-29
| | | | | | | | | | | | | | | | | | | | | | | | Problem: Similar to clearmatches(), it's always necessary to provide a fallback that allows the user to do a "global reset" when something goes wrong. Solution: vim.img.del(math.huge) clears all images. Use kitty's d=A command to clear all placements in a single escape sequence rather than N individual deletes, also freeing stored image data not referenced by the scrollback buffer.
* | fix(lsp): util.lua attempt to concatenate userdata #39225Olivia Kinnear2026-04-28
| | | | | | | | | | | | | | | | | | Problem: Error when querying document symbols using python-lsp-server: lsp/util.lua:1955: attempt to concatenate field 'containerName' (a userdata value) Solution: Check for `vim.NIL`.
* | feat(ui): use vim.ui.select for :tselect, z= #39478Justin M. Keyes2026-04-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: `:tselect` and `z=` (spell suggest) have their own bespoke select menus. Solution: - Delegate to `vim.ui.select` instead. - Bonus: - `:tselect` gains mouse support. `print_tag_list` didn't suport mouseclick. This causes some minor regressions, which are not blockers: - `z=` no longer draws the list right-left if 'rightleft' is set. - TODO: can/should `vim.ui.select` / `vim.fn.inputlist()` handle that? - `:tselect` - No "column" headings (`# pri kind tag file`). - No highlighting: (HLF_T: tag name, HLF_D: file, HLF_CM: extra fields). - TODO: can `vim.ui.select()` support highlighted chunks (`[[text, hl_id], ...]`) ? fix https://github.com/neovim/neovim/issues/25814 fix https://github.com/neovim/neovim/issues/31987
* | perf(treesitter): reuse edited tree ranges for callbacksLewis Russell2026-04-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | After an edit, LanguageTree:_edit() updates the current trees. When the LanguageTree manages explicit regions, _edit() also refreshes _regions from tree:included_ranges(true), so those regions have the edited byte offsets. A later injection pass may call set_included_regions() with a different number of child regions. That path discards the old trees and emits changedtree callbacks for them. invalidate(true) does the same when a buffer is reloaded. Before this change, both discard paths called tree:included_ranges(true) for every old tree, even if _edit() had just collected those exact ranges. That duplicate range extraction is expensive with many injection trees. Realistic shapes include generated C files with many macro bodies parsed by the C preproc_arg injection, Markdown documents with many fenced blocks of the same language, and template files with many embedded-language islands. The stock highlighter registers recursive changedtree callbacks, so this is on the normal highlighting edit path. Track whether _regions currently came from tree:included_ranges(true) with _regions_from_tree_ranges. _do_changedtree_callbacks() reuses _regions only in that state; otherwise it falls back to calling tree:included_ranges(true). Clear the marker when regions are replaced by injection ranges, when a tree is reparsed, or when trees are discarded. This avoids keeping a second copy of the ranges while preserving callback precision: changedtree still receives tree:included_ranges(true) for the old tree, not the broader managed region. Benchmark on 100k C macro injections, one-line edit, recursive changedtree callback: - HEAD median: edited parse 84.2 ms, child region replacement 58.7 ms - This change: edited parse 34.6 ms, child region replacement 8.5 ms That is about 2.4x faster for the edit parse and 6.9x faster for child region replacement in this workload. Add a regression test that replacing injection regions still fires changedtree and still reports the old tree's exact included ranges. AI-assisted: Codex
* | fix(lsp): show meaningful error on invalid completion response #39445glepnir2026-04-28
| | | | | | | | | | | | | | | | | | Problem: vim.NIL is truthy in Lua, so `#(result.items or result)` crashes on `#vim.NIL` when servers return null. Solution: skip spec-allowed result=null silently, raise an error on items=null with the server name. https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
* | feat(health): vim.ui.img healthcheck #39449Chip Senkbeil2026-04-28
|/
* fix(excmd): use realtime for v:starttime, :uptime #39425Till Bungert2026-04-27
| | | | | | | | | | | Problem: `v:starttime`, `:uptime` use a monotonic high-resolution timer. This only works as long as the timer keeps running (if the computer is suspended the timer is paused). This is somewhat unintuitive, and doesn't match the behavior of the `uptime` shell command. Solution: Implement `os_realtime` to get the real time since the epoch in nanoseconds.
* perf(vim.pos): use numeric index internally #39447Yi Ming2026-04-27
|
* 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
* feat(events)!: support `Optionset modified`, drop BufModifiedSet #35610glepnir2026-04-27
| | | | | | | | | Problem: BufModifiedSet autocmd only triggered for current buffer during redraw, causing delayed events when :wa writes non-current buffers. Solution: - Use the aucmd_defer approach to implement `Optionset modified`. - Drop BufModifiedSet.
* feat(doc): document Lua alternative for vim.fnLewis Russell2026-04-27
| | | | AI-assisted: Codex
* vim-patch:3cc7d50: runtime(algol68): Add new syntax file, ftplugin and ↵zeertzjq2026-04-27
| | | | | | | | | | | | | | | | | | | | | | | | | filetype detection - Add a syntax file update to Neville Dempsey's long-serving version - Add a new rudimentary ftplugin - Add filetype detection Changes to the syntax file include: - improved prelude, number and symbol highlighting - prelude highlighting tests - updated boiler plate Note that these runtime files currently target Algol 68 Genie employing the default UPPER stropping regime. Support for GNU Algol 68 should also be usable with the UPPER stropping regime, although somewhat less complete. Full support for the SUPPER stropping regime in GNU Algol 68 is also planned. closes: vim/vim#19818 https://github.com/vim/vim/commit/3cc7d5071619f30bba2ae4ccfa992dccb8fd5e51 Co-authored-by: Doug Kearns <dougkearns@gmail.com>
* feat(ui): vim.ui.img api #37914Chip Senkbeil2026-04-26
| | | | | | | Problem: No builtin api to load and display images. Solution: Introduce vim.ui.img. Only supports kitty graphics protocol, currently.
* fix(lsp): handle relative='editor' in make_floating_popup_options() #39320Daigo Yamashita2026-04-26
| | | | | | | | | | | | | | | | | | Problem: With `vim.g.health = { style = 'float' }`, running `:checkhealth` from a `:help` buffer placed the float in the top-left corner instead of centered. make_floating_popup_options() picks the NW/NE/SW/SE anchor and the available height from cursor-relative metrics (winline(), wincol(), winheight()). When the caller passes relative='editor', those metrics are meaningless, so the function could flip to an 'E' anchor and clamp the float off-screen. Solution: When relative='editor', treat the whole editor area as available space (lines_above=0, lines_below=&lines, wincol=0). This makes the NW anchor the natural choice and keeps the float position stable regardless of where the cursor is in the current window. AI-assisted: Claude Code
* docs: sort quasi-keysetsJustin M. Keyes2026-04-26
|
* docs: vim.ui.select, miscJustin M. Keyes2026-04-26
|
* docs: lsp.CodeActionContext, nested `@inlinedoc`Justin M. Keyes2026-04-26
| | | | | - fix https://github.com/neovim/neovim/issues/39208 - fix generation of neste `@inlinedoc` classes
* fix(vim.range): validate arguments on all cases #39415Luis Calle2026-04-26
|
* feat(vim.pos): accept buf=0 for current buf #39414Luis Calle2026-04-26
|
* Merge #39350 from echasnovski/pack-confirm-gxJustin M. Keyes2026-04-25
|\
| * fix(util): add and use forge link computationEvgeni Chasnovski2026-04-25
| | | | | | | | | | | | | | | | Problem: There are many Git forges each with a different way of constructing permanent links to like commits and tags. Solution: Add a private utility function that computes these special links on the best effort basis.
| * feat(pack): support `textDocument/documentLink` in confirmation bufferEvgeni Chasnovski2026-04-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: In `vim.pack.update()` confirmation buffer it might be useful to be able to use `gx` (open link at cursor) when cursor is on something like commit or tag. Solution: Add `textDocument/documentLink` method support for the in-process LSP. This may be used by LSP clients and makes `gx` automatically work. The shortcoming is that this requires tracking how to construct a URL from source and commit/tag. Currently only GitHub hosted repositories are supported.
* | docs(vim.ui): "preview" interface for vim.ui.select() #37360Evgeni Chasnovski2026-04-25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Plugins may want to have a way to show more details about items when using `vim.ui.select`. This is a fairly common problem that prompts plugin authors to implement dedicated sources/pickers for fuzzy picker plugins that are popular at the moment. Solution: Document a way for `vim.ui.select` to provide preview: - `vim.ui.select` users can provide `opts.preview_item` function that creates/uses a buffer and its contents at certain position to show more details about an item. - `vim.ui.select` implementations may use `opts.preview_item` in the way they see fit (like show the buffer in a separate/same window interactively/on-demand or do nothing) if they have a way to show more information about an item.
* | fix(lsp): check window is still valid after async request #39396Yi Ming2026-04-25
| | | | | | | | | | | | | | Problem: Since `foldclose` is async, it must wait for the request to return before actually executing, at which point the original window may no longer be valid. Solution: Check whether the window is valid before actually performing `foldclose`.
* | feat(treesitter/extmark): support removing a conceal highlight #35087Peter Cardenas2026-04-25
| | | | | | | | | | | | | | | | | | Problem: Cannot remove a `@conceal` highlight when defined in highlights.scm. Solution: Support a `@noconceal` highlight that works similarly to `@nospell` where it overrides the conceal set on the range to remove it. Additionally, can set the conceal metadata field to false for the same behavior.
* | docs: misc #39256Justin M. Keyes2026-04-25
| |
* | perf(lsp): avoid unnecessary string allocations when parsing content-lengthYi Ming2026-04-25
| |
* | refactor: support `buf:ref()` in stringbuffer shimYi Ming2026-04-25
|/
* fix(lsp): handle self-mapped methods in supports_method #39383Tristan Knight2026-04-24
| | | | | | | | | | | | | | | Problem: The LSP client incorrectly checks for server capabilities when determining support for self-mapped methods (e.g., 'shutdown'), which do not have corresponding capabilities in the server's response. This leads to false negatives when checking if such methods are supported. This was handled correctly for dynamic registrations, but not for static. Methods such as 'shutdown', do not have a related server capability and should be assumed to be supported. Solution: Update the `supports_method` logic to always return true for self-mapped methods.
* feat(tui): restore 'ttyfast' to control tty requests #38699Kyle2026-04-24
| | | | | | | | | | | | Problem: When running nvim on a remote machine over SSH, if there is high ping, then bg detection may not complete in time. This results in a warning every time nvim is started. #38648 Solution: Restore 'ttyfast' option and allow it to control whether or not bg detection is performed. Because this is during startup and before any user config or commands, we use the environment variable `NVIM_NOTTYFAST` to allow disabling `ttyfast` during initialization.
* feat(api): nvim_echo(percent=nil) means "unknown" progress #39029Peter Cardenas2026-04-24
| | | | | | | Problem: No way to signal "unknown" or "indeterminate" progress percentage. Solution: Treat percent=nil as "indeterminate" percent.
* fix(lsp): more info in error msg, deduplicate test #39359Justin M. Keyes2026-04-24
|
* fix(trust): always use "/" slashes in filepaths #39355Justin M. Keyes2026-04-24
| | | | | | | | Problem: We should not use "\" (backslashes) except where absolutely required. See references in https://github.com/neovim/neovim/pull/37729 Solution: There is no reason to use "\" slashes in the trust db, so don't.
* vim-patch:9.2.0390: filetype: some Beancount files are not recognized (#39360)zeertzjq2026-04-24
| | | | | | | | | | | Problem: filetype: some Beancount files are not recognized Solution: Detect *.bean files as beancount filetype (Bruno Belanyi) closes: vim/vim#20037 https://github.com/vim/vim/commit/521eac1877355d408c8c57bc31947cc86f31f41d Co-authored-by: Bruno Belanyi <bruno@belanyi.fr>
* feat(excmd): add :uptime command #39331Olivia Kinnear2026-04-23
| | | | | | | Problem Nvim marks its v:starttime, but there is no user-friendly way to get Nvim's uptime. Solution Add :uptime (based loosely on uptime(1)).
* fix(lsp): handle null id in JSON-RPC responses #38340atusy2026-04-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: LSP spec allows response message to have a null request-id. This may happen when for example client sends unparseable request. https://github.com/microsoft/language-server-protocol/issues/196 Solution: Guard the server response branches against id=vim.NIL (json null), and handle error responses with null id by logging a warning and dispatching on error. Problem: CI (ubuntu asan, ubuntu tsan, windows) reports `uv_loop_close() hang?` from the two new null-id response tests. The leaked handle is the server-side accepted TCP socket created inside `server:listen` callback. The tests closed only the listener but not the accepted socket, so libuv could not finish shutting down the loop and each test session took ~2s extra to exit. Solution: Hoist the accepted socket to the outer `exec_lua` scope and close it at teardown before closing the listener. The close runs synchronously inside `exec_lua`, so the loop has time to dispose the handle before the session exits. * test(lsp): close accepted socket on read-loop exit/error Match the precedent in the handler test ("handler can return false as response") and the shared `_create_tcp_server` helper in `test/functional/plugin/lsp/testutil.lua`: close the accepted socket from inside the `create_read_loop` exit/error callbacks. The teardown close added in the previous commit remains as belt-and-suspenders, so the socket is disposed whether the server goes away first or the client does.