aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
Commit message (Collapse)AuthorAge
...
* | feat(api): optional params after `opts` #40720Justin M. Keyes2026-07-13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: After 25439dad7e2b, `opts` is optional, but not params that follow it. Solution: - Update `gen_api_dispatch.lua`, docs, tests. - Enhance the `nvim_get_api_info()` api-metadata to include a boolean flag indicating whether a parameter is optional: ``` [type, name, optional] ``` Note: Currently, optional params are assumed to be Dict/Array. Since we don't yet have any use-cases of optional params following `opts`, the build just checks this assumption and we can deal with it later if we ever care to: nvim_get_hl: optional param "foo" has type "Integer" but (currently) we assume Dict/Array
* | fix(path): normalize separators (slashes) #39155tao2026-07-12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Continue separators normalization, and try to keep it at the nvim <-> external boundary, e.g., `fn.xxx`, `api.xxx`, `:xxx` Solution: some key changes - normalize `$HOME-windows` - normalize entry points of changing directory - `nvim_set_current_dir()`, `chdir()` - normalize the named pipe - `--listen` arg, `--server` arg, `:restart` - `serverstart()`, `sockconnect()`, `serverstop()` - make `expand()` respect 'shellslash' again - clean up `did_set_shellslash` - replace `forward_slash` with `TO_SLASH` - remove obsolete `TMP_PATHSEPSTR` - remove `slash_adjust` in `do_autocmd_dirchanged`? - make `fnamemodify()` always return `/` (except when substituting separators via `:s`, `:gs` ?) Note: - these funcs still apply `slash_adjust` on return, as before: `:pwd`, `chdir()`, `exepath()`, `getcwd()` - these funcs alwarys return `/`, unlike before the normalization PRs - `getcompletion()`, `finddir()`, `findfile()` Also - clean up code, comments, formatting and tests - move `TO_SLASH` from `f_chdir` to `changedir_func` - move `TO_SLASH` from `f_bufadd` to `buflist_new` Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
* | fix(lsp): unclear error on malformed server responses #40422Kim A. Brandt2026-07-12
| | | | | | | | | | | | | | | | | | Problem: Malformed server responses with `null` (vim.NIL) values, do not show clear error messages. Solution: Assert two known, specific cases, to avoid user confusion.
* | fix(filetype): false positive when matching directory buffer #40695Barrett Ruth2026-07-11
|/ | | | | | | | | | | Problem: URI buffer names can end with a slash, but slash-ended directory matching should not preempt URI filetype patterns. Solution: Do not use the slash shortcut for names with URI schemes, so those continue through normal filetype matching. Co-authored-by: Adam Karafyllidis <akisarou90@gmail.com>
* fix(api): nvim_cmd() "args" type too narrow #40670glepnir2026-07-10
| | | | | | | Problem: nvim_cmd() accepts number/boolean in args and converts them to strings, but the keyset declares ArrayOf(String). Solution: use ArrayOf(Union(Integer, String, Boolean)) and wrap union types in parens when generating array annotations.
* fix(filetype): ensure directory bufname ends w/ slash sep #40552Barrett Ruth2026-07-10
| | | | | | | | | | | | Problem: `vim.filetype.match()` needs a cheap way to recognize directory buffers without doing filesystem stat work. Solution: Ensure full buffer names for directories end in a trailing slash. Now directory buffers can proceed through the normal 'filetype' path. Note side-effects: session and ShaDa buffer-list restore behavior must be compatible, so those + corresponding tests must be updated.
* fix(dir): user/plugin can override default "-" mapping #40676Barrett Ruth2026-07-10
|
* feat(lua): add `cwd` context to `vim._with()` #40653Evgeni Chasnovski2026-07-09
| | | | | | | | Problem: No concise way to execute a callback with temporarily set working directory. This might be useful when sourcing nested files to allow them to assume that current working directory is their root directory. Solution: Add `cwd` context to `vim._with().`
* refactor(logging)!: rename current_level #40642Justin M. Keyes2026-07-08
|
* feat(pack): 'packlockfile' option #40562Evgeni Chasnovski2026-07-08
| | | | | Problem: No way to configure the lockfile location. Solution: Add 'packlockfile' option.
* fix(lsp): clear push diagnostics on detach #40634Oleh Volynets2026-07-08
| | | | | | | | | Problem: when an LS client detaches from the buffer, only pull diagnostics are cleared via capability framework. Push diagnostics remain stuck even when client stops/restarts. Solution: clear push diagnostics on client detach. ref #33864
* fix(lsp): refresh document-pull buffers on workspace/diagnostic/refresh #40623Caleb White2026-07-08
| | | | | | | | | | | | | | When a server supports both document and workspace pull diagnostics, `on_refresh` only dispatched a `workspace/diagnostic` request. The workspace response handler skips buffers with `pull_kind == "document"` (i.e. all buffers opened by the user), so their diagnostics went stale until the next `didChange` or `didOpen` event. Change `on_refresh` to always refresh document-pull buffers via `textDocument/diagnostic`, regardless of whether the server also supports workspace diagnostics. This ensures that opened buffers see updated diagnostics (e.g. after a save triggers an external tool like PHPStan) without requiring the user to re-enter insert mode.
* feat(vim.fs): vim.fs.mkdir() #40599Barrett Ruth2026-07-08
| | | | | | | | | Problem: `vim.fs` does not provide a directory creation helper matching its filesystem API shape. Solution: Add `vim.fs.mkdir()` as a thin wrapper around `vim.fn.mkdir()`, with `parents` and `mode` options.
* refactor(lsp): use LspNotify for codelens #40604jdrouhard2026-07-07
| | | | | | | | | | | | | | | | | | | | | Problem: The codelens LSP module was using its own raw buffer events and its own debounce mechanism for refreshing code lens in attached buffers. Solution: Switch the module to using the LspNotify autocmd events. LspNotify fires just after document versions are synced with the server and provides a built in debounce mechanism for changes. Additionally, this fixes some bugs with the previous implementation: 1. The workspace/codeLens/refresh handler re-requested codelens for all buffers but when the response came back, it forced an extra redraw after clearing the work the handler had just done. 2. Document synchronization was reworked to be more resilient to multiple clients providing codelens for a single buffer. The latest document version is now separately tracked per client (and per client's lenses per row) instead of for the buffer as a whole. This allows the on_win() function to properly redraw all codelens even when different clients' responses for a particular document version come back at different times.
* fix(api): nvim_win_resize tweaks #40596Justin M. Keyes2026-07-05
|
* feat(lsp): convert inlay_hint to capability framework #40569jdrouhard2026-07-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Inlay hints used separate global and per-buffer bufstates tables and bespoke global autocmds for managing the inlay hint state across buffers and clients, duplicating the lifecycle logic already provided by the Capability framework. This caused inconsistencies in how client state was handled and inlay hint state lifecycle was managed compared to other LSP features. Solution: Replace the ad-hoc bufstate tracking and global autocmds in vim.lsp.inlay_hint with a proper InlayHint subclass of Capability. This also refactors the way inlay hint state is managed and fixes bugs I found while doing this: 1. For each line with inlay hints, the list of the hints along with whether they have been applied is stored in a current result on the client state. This allows the on_win decorator to clear all inlay hints for an old document version once, and then re-add the new version's hints line-by-line as they are drawn to the screen, modeling the semantic tokens module. 2. It fixes problems with mixing results from multiple clients attached to the buffer by fully moving each client's state to its own table. Previously, only the most recent document version used to populate a line's inlay hints was stored, but there was no distinction for which client the hints may have come from. (Fixes #36318) 3. It fixes the workspace/inlayHint/refresh server->client notification behavior. Previously it would only re-request inlay hints for buffers currently displayed in a window but would not invalidate them in non-displayed buffers (or provide any mechanism for those buffers to re-request at a later time). Model semantic token module here again by invalidating all buffers, and adding a BufWinEnter autocmd to refresh hints. 4. Add a mechanism to cancel in-flight requests if a new request for a newer document version is made before the last one returned 5. Handle stale results by simply dropping them.
* Merge #40520 nvim_win_resizeJustin M. Keyes2026-07-05
|\
| * feat(api): add nvim_win_resize()XiaowenHu962026-07-05
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Ref #6645 Problem: When a window is resized it takes space from the window right/below first, and only falls back to the window left/above when there is no more room. Sometimes a user wants the space to come from a specific direction. Solution: Add nvim_win_resize(win, width, height, {anchor}) which resizes a window with a choosable anchor edge, letting a window grow leftwards or upwards by taking space from the window to the left or above first. The default anchor reproduces nvim_win_set_width()/nvim_win_set_height().
* | fix(lsp): support -1 column in format range #40570Barrett Ruth2026-07-05
| | | | | | | | | | | | | | | | | | | | Problem: `vim.lsp.buf.format()` accepts ranges using nvim indexing, where an end column of -1 means end of line. LSP ranges cannot use that, which is confusing for things like range formatting. Solution: Resolve -1 end columns to the line length before converting the range to LSP positions.
* | fix(health): always set 'modifiable' #40584dqnne2026-07-05
| | | | | | | | | | | | | | | | Problem: When buffers are by default `nomodifiable`, such as when Nvim starts with `-M`, the health buffer cannot be updated. Solution: Always set `modifiable` before modifying the buffer.
* | fix(health): don't check node package via yarn #40572Barrett Ruth2026-07-04
| |
* | feat(channel): add ChanClose event #40568Barrett Ruth2026-07-04
| | | | | | | | | | | | | | | | | | Problem: Plugins using RPC sockets cannot detect when the peer closes a `sockconnect()` channel, so reconnect logic has no reliable trigger. Solution: Add a `ChanClose` event with channel info before the channel is removed, matching the existing `ChanOpen`/`ChanInfo` event model.
* | fix(lsp): semantic tokens reset_timer() usage #40554jdrouhard2026-07-04
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: reset_timer() was being called without checking for whether the client state for the client_id still existed. debounce_request() starts a timer that defers a call to send_request() which then calls reset_timer(). If the timer fires after the client_state is erased, then the deferred function attempts to dereference the timer on a nil client state. Solution: Change reset_timer to take a state directly so it can't be nil and move the reset_timer() call inside a guard that ensures state exists. Additionally, reset a client's timer when the client detaches so it doesn't become dangling.
* | fix(lsp): use LspNotify for document_color #40571jdrouhard2026-07-04
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: The document_color lsp module was already using the capability framework but was still using raw buffer events to handle requests and reloading. This means that every keystroke was sending a document_color request to the server since there was no debounce in the raw handlers. Solution: Switch to using LspNotify autocmd events. LspNotify fires just after new document versions are synced with the server and provides a built in debounce mechanism for changes. It also provides the signal for when the current state should be cleared (didClose). The detach part is already handled by the capability framework. Fixes #39785
* | docs(lsp): document rpc Client request/notify as fields #40573Barrett Ruth2026-07-04
| | | | | | | | | | | | | | | | | | | | Problem: `request()` and `notify()` are methods of the object returned by `vim.lsp.rpc.start()`/`connect()`, but were rendered with module-level helptags (`vim.lsp.rpc.request()`, `vim.lsp.rpc.notify()`) (erroneously implying module functions that do not exist). Solution: Mark the wrappers `@private` and describe them on `vim.lsp.rpc.Client` instead.
* | fix(cmdwin): set 'noscrollbind' #40556STG2026-07-04
| | | | | | | | | | | | | | | | Problem: Opening cmdwin from a 'scrollbind' window makes cmdwin scrollbinded. Legacy cmdwin set 'noscrollbind'. Solution: Set 'noscrollbind'.
* | fix(dir): define "-" (up/parent) mapping earlier #40531Barrett Ruth2026-07-02
| | | | | | | | | | | | | | | | | | | | Problem: The dir.lua "-" mapping cannot be easily overridden (because of autocmd ordering). Solution: - Move it to defaults.lua. - Also to be extra polite: fall back to builtin `-` motion if the user disabled the `dir.lua` plugin.
* | docs: pos argument in vim.lsp.ListOpts should be optional #40550nikolightsaber2026-07-02
| | | | | | | | | | | | | | | | Problem: the pos argument in ListOps for lsp is an optional parameter, but the lua_ls typing system doesn't reflect that Solution: let pos be optional Co-authored-by: nikolightsaber <nikolightsaber@gmail.com>
* | fix(pack): do not assert non-nil `stderr` #40544Evgeni Chasnovski2026-07-02
| | | | | | | | | | | | | | | | | | | | | | | | Problem: On some systems `stderr` can be disabled. This results in not usable `vim.pack` since it asserted `stderr` to be non-nil. Solution: Stop asserting non-nil `stderr`. The downside is that potential errors are not shown, but this is intentional since `stderr` is disabled on system level. Still assert non-nil `stdout` as its output is important for `vim.pack` to actually do its job. Disabled `stdout` is not something that can work with `vim.pack`.
* | fix(health): handle failed dir listingJustin M. Keyes2026-07-01
| |
* | feat(health): report ulimit infoJustin M. Keyes2026-07-01
| | | | | | | | | | | | | | | | | | Problem: Nvim shows `(libuv) kqueue(): Too many open files` on macos. ref https://github.com/neovim/neovim/issues/40238 Solution: Add a healthcheck for this situation.
* | feat(vim.fs): dir() ergonomicsJustin M. Keyes2026-07-01
| |
* | fix(vim.fs): dir(), find() error-reportingJustin M. Keyes2026-07-01
| |
* | feat(vim.fs): dir(), find() error-reportingRudrajeet Pal2026-07-01
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: vim.fs.dir() and vim.fs.find() drop errors returned by uv.fs_scandir(). Solution: - vim.fs.dir(): - Return root scan failures as a secondary return value. - Propagate recursive scan failures through the iterator. This allows callers to distinguish unreadable directories from empty ones. - vim.fs.find(): Collect errors during search, and return the list as a second retval.
* | fix(lsp): request semantic tokens in BufWinEnter (#40510)jdrouhard2026-06-30
| | | | | | | | | | | | | | | | | | Problem: A previous refactor removed the BufWinEnter autocmd that initiated a token request. When an LSP server sends a refresh notification, then buffers that aren't shown in any window lost their only trigger to request new tokens. Solution: Add the BufWinEnter autocmd back which simply requests tokens for all clients attached to the buffer.
* | fix(cmdwin): handle control characters properly #40488zeertzjq2026-06-30
| | | | | | | | | | - Replace newlines in the current cmdline with NULs when opening cmdwin, and do the reverse when putting a cmdwin line back into the cmdline. - Escape control characters with Ctrl-V when feeding cmdline.
* | fix(cmdwin): handle split/tabpageJustin M. Keyes2026-06-29
| | | | | | | | | | | | | | | | | | | | | | | | Problem: - If cmdwin window is split, ENTER in one does not close the others. - If cmdwin is put into a different tabpage via <c-w>T, it stops working (ENTER does not execute the cmd). Solution: - Close the buffer instead of the window. - In the WinClosed handler, skip `M._cleanup()` unless this is the last cmdwin window.
* | refactor: cleanup, docs #40480Justin M. Keyes2026-06-29
| |
* | feat(:restart)!: ":restart" (no bang) saves/restores session #40321Nathan Zeng2026-06-29
| | | | | | | | | | | | | | | | | | | | | | Problem: `:restart` does not preserve window layout, etc. Solution: - Change `:restart` to save/restore a session automatically. - Introduce "bang" variant `:restart!` to restart *without* session save/restore. - Introduce `v:startreason`. - `ZR` maps to `:restart!`.
* | perf(options): avoid Lua<=>API roundtrips #40477Justin M. Keyes2026-06-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: - Lua<=>API roundtrips - Although we prefer Lua for most business-logic code, doing this conversion in C makes sense in this case because: 1. setting options is a hot path 2. most of the options logic lives in C 3. the current arrangement is MORE verbose and requires MORE code Solution: Move conversion to a C util. - nvim_set_option_value passes the raw Object (scalar, Array, or Dict) to `object_as_optval_for()` which flattens it to the canonical `:set` string and validates the type. - drop `convert_value_to_vim`, eliminate its roundtrip.
* | vim-patch:9.2.0742: filetype: SSH keys and related filetypes not recognized ↵zeertzjq2026-06-28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | (#40469) Problem: filetype: SSH keys and related filetypes not recognized Solution: Detect sshpublickey, sshknownhosts sshauthorizedkeys and sshallowedsigners filetypes, add syntax scripts for those filetypes (Fionn Fitzmaurice) This adds syntax highlighting for SSH public keys, as well as related filetypes derived from this (SSH authorized keys, SSH known hosts and SSH allowed signers). Also add filetype detection based on the path and name. closes: vim/vim#20635 https://github.com/vim/vim/commit/6e66ebc0fdd7804db4baa076e62c78d208adaeaf Co-authored-by: Fionn Fitzmaurice <git@fionn.computer>
* | feat(api): nvim_set_option_value(operation=...) #39849Kyle2026-06-28
| | | | | | | | | | | | | | | | | | | | | | | | | | Problem: `nvim_set_option_value` cannot "update" options similar to `:set opt=`, `:set opt+=`, etc. The Lua impls of "vim.opt" / "vim.o" have incomplete, bespoke reimplementations of those operations. ref #38420 Solution: - Add `operation` param to `nvim_set_option_value`, which may be "set", "append", "prepend", or "remove". - Use this feature to implement `vim.opt` / `vim.o`.
* | feat(pack): ensure order of `PackChanged{Pre,}` events #40455Evgeni Chasnovski2026-06-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: due to totally async install/update/checkout there is no guaranteed order of `PackChanged{Pre,}` events across different plugins. This might lead to conflicts when callback for some "main" plugin relies on features from "dependency" plugin: i.e. callback for "main" plugin can trigger before installing/updating "dependency" plugin. The installation order can be enforced by separate vim.pack.add() calls, but update/checkout can not. Solution: Trigger events in bulk independently of async execution: - `PackChangedPre` before any action for all input plugins in order they are supplied. It will also trigger even if an action will fail. - `PackChanged` after all actions finished for all sucessfully affected plugins in order they are supplied. This also comes with a couple of side effect changes: - `PackChangedPre kind=delete` is now also triggered even if the delete won't be done. This makes it more aligned with `kind=install` and `kind=update`. - Force update (`:packupdate!`) and "udpate LSP action" now do two async steps: download/compute updates and apply them. This also results in two progress reports. This is mostly a by-product of the implementation (there has to be a pre-computation of target revision for all plugins before doing `PackChangedPre` in bulk before possibly applying an update), but I kind of like it more this way as it is more explicit of what's going on. If absolutely not acceptable, there might be some hacks to mitigate it at least in code action, but I'd keep it like this.
* | feat(statusline)!: allow %= in item groups, scope %< to item groups #40369Sébastien Hoffmann2026-06-27
| | | | | | | | | | | | |</