aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua
Commit message (Collapse)AuthorAge
...
* | fix(lua): types for getloclist() signatures #42131glepnir2026-09-28
| | | | | | | | | | Problem: vim.fn.getloclist() is untyped, unlike getqflist(). Solution: Split it into typed list and {what} forms, like getqflist().
* | fix(lua): enable unnecessary-assert diagnosticLewis Russell2026-09-28
| | | | | | | | AI-assisted
* | fix(editor)!: operator target/cgn modifies Visual marks #42119Justin M. Keyes2026-09-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: An operator on a target that creates a Visual selection (`cgn`, `d<C-v>j`, an omap text object like `:<C-U>normal! viw`) sets `'< '>`, `gv` and `visualmode()` to the operator target. This causes at least the following problems: - clobbers the user's previous `'< '>` (annoying and usually unwanted) - E.g. after a custom textobj, `:help text-object-define`. - "cgn" with a `\%V` pattern can't be dot-repeated (".") Solution: Don't save the Visual area if the operator target created it (operator was pending). Also fix `an`/`in` with `'selection'=exclusive` starting from an empty range.
* | feat(multicursor): 'follow' option #42095Justin M. Keyes2026-09-27
| | | | | | | | | | | | | | | | Problem: - gQ does not restore follow-mode (q=). - Users/plugins have no way to check if follow-mode is enabled. Solution: Introduce buffer-local 'follow' option.
* | fix(lsp): preserve tag types to stabilize emmylua checks #42117Volodymyr Chernetskyi2026-09-27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: EmmyLua widens singleton completion and symbol tags to integer during generic inference. Nested field checking can skip the resulting type mismatch depending on member iteration order, making lint flaky. Solution: Annotate both tag tables with their protocol types so get_value_set() preserves the singleton tag types without changing runtime behavior or disabling diagnostics. Validated with 1,000 consecutive full-runtime checks using EmmyLua 0.25.1 on macOS arm64. AI-assisted
* | perf(lsp): read options once per completion response #42106glepnir2026-09-27
|/ | | | | | | | Problem: Converting completion items reads 'completeopt' through vim.opt, 'ignorecase' and 'smartcase' for every item. Solution: Read them once per response.
* vim-patch:5959274: runtime(doc): Tweak documentation stylezeertzjq2026-09-26
| | | | | | | | | | closes: vim/vim#21361 https://github.com/vim/vim/commit/5959274607038bac22e9dde740060ddb748fedfe Omit :h :source-dryrun as it needs changes to port to Nvim anyway. Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
* vim-patch:b3a4882: runtime(doc): mention getcellwidths() in setcellwidths()zeertzjq2026-09-26
| | | | | | closes: vim/vim#21362 https://github.com/vim/vim/commit/b3a4882a915634c6031a4b4c8e25d459ac7b4319
* fix(lua): enable assignment type checking in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | Enable EmmyLua's assign-type-mismatch diagnostic after correcting the runtime annotations and assignments it flags. Correct option, tuple, and return types, and use separate locals when a value changes representation. Add guards and narrow casts where needed so the runtime passes the stricter check. Regenerate the affected docs. AI-assisted
* fix(lua): accept nil nosuf in the expand list overloadLewis Russell2026-09-25
| | | | | | | The expand() overload required nosuf even though callers can pass nil. Mark it optional in the source metadata and regenerate the Lua types. AI-assisted
* fix(api): include all supported window border stylesLewis Russell2026-09-25
| | | | | | | | The border metadata omitted the empty string and bold styles accepted by the API. Include both literals and regenerate the Lua types so valid window configurations pass type checking. AI-assisted
* fix(lua): enable nil-safety diagnostics in runtime codeLewis Russell2026-09-25
| | | | | | | | | | | | Enable EmmyLua's need-check-nil diagnostic and resolve nullable values through more precise types, explicit invariants, and guards for missing runtime state. Keep analyzer-specific workarounds local and update the affected API documentation. Exclude the bundled re.lua from analysis so its nil-check warnings do not fail CI. AI-assisted
* fix(treesitter): type synchronous parse results as non-nilLewis Russell2026-09-25
| | | | | | | | LanguageTree:parse() always returns trees when no callback is supplied, but its shared return type also permits nil for asynchronous parsing. Add the synchronous overload and document that distinction. AI-assisted
* fix(filetype): handle short diff and DNS headersLewis Russell2026-09-25
| | | | | | | | | Content detection indexed lines that short files do not have. Check the available diff and BAAN header lines before matching, and concatenate only existing DNS header lines. Preserve standalone Bazaar operation headers even when the multiline forms are incomplete. AI-assisted
* fix(diagnostic): default absent quickfix coordinatesLewis Russell2026-09-25
| | | | | | | | | Quickfix entries can omit their start and end positions. Default absent start coordinates to the first position and absent end coordinates to the start, avoiding arithmetic and comparisons on nil. Cover both cases in the conversion tests. AI-assisted
* fix(gen): ignore return casts in generated documentationLewis Russell2026-09-25
| | | | | | | | Return-cast annotations refine types but do not add return values. Recognize them before @return and exclude them from rendered docs. Apply narrowing to vim.isnil() without changing its runtime behavior. AI-assisted
* fix(lua): generate explicit overloads for vim.fnLewis Russell2026-09-25
| | | | | | | | | | | | | | | | The generated vim.fn stubs represent overloads as repeated function declarations. EmmyLua merges their return types, so getline(lnum) is inferred as string|string[] even though it always returns a string. Generate one declaration with @overload annotations from the existing __N entries, while keeping separate Vimdoc signatures. Parenthesize the overload return list so types such as (0|-1)[] remain arrays. Correct getline()'s single-line and range signatures, and add typed getqflist() signatures for its entry-list and property-query forms. This lets callers infer quickfix results without local type overrides. AI-assisted
* vim-patch:9.2.1128: filetype: icalendar files are not recognizedzeertzjq2026-09-25
| | | | | | | | | | | | | | | Problem: filetype: icalendar files are not recognized Solution: Detect *.ics files as icalendar filetype, include syntax and filetype plugins (Anakin Childerhose). Reference: https://datatracker.ietf.org/doc/html/rfc5545 closes: vim/vim#21356 https://github.com/vim/vim/commit/7c049d5ce1d6bc119abf9749ca5cad74225ca83e Co-authored-by: Anakin Childerhose <anakin@childerhose.ca>
* vim-patch:9.2.1127: filetype: Gentoo portage config files are not recognizedzeertzjq2026-09-25
| | | | | | | | | | | | | | | | | Problem: filetype: Gentoo portage config files are not recognized Solution: Detect portage files as sh or confini filetype (Wu, Zhenyu) Reference: https://wiki.gentoo.org/wiki//etc/portage/make.conf https://wiki.gentoo.org/wiki//etc/portage/repos.conf https://wiki.gentoo.org/wiki//etc/portage/binrepos.conf closes: vim/vim#21343 https://github.com/vim/vim/commit/2c2bae52ac66dbb8ff13c3842aba64c1b64aa0e5 Co-authored-by: Wu, Zhenyu <wuzhenyu@ustc.edu>
* vim-patch:9.2.0934: filetype: hlsl files are not recognizedzeertzjq2026-09-25
| | | | | | | | | | | | | Problem: filetype: hlsl files are not recognized Solution: Detect *.hlsl files hlsl filetype, include ftplugin, indent and syntax plugins, update gvim menu (Maxim Kim) closes: vim/vim#20993 https://github.com/vim/vim/commit/11fca33162ad2e6a6365dbf6202fb1af0f21b7cb Co-authored-by: Maxim Kim <habamax@gmail.com>
* perf(lua): share compatible file watchersLewis Russell2026-09-24
| | | | | | | | | | | | | | | | | | Problem: LSP servers can register identical file watchers before removing old registrations. Each registration creates another watcher tree, making setup and teardown expensive in large workspaces. Solution: Move glob compilation into vim._watch and accept rules for multiple roots alongside existing single-path and LPeg inputs. Share compatible backends until their last subscription is cancelled. Ref: #23291 AI-assisted
* fix(ui): ui.open() modifies opts.cmd #41885Volodymyr Chernetskyi2026-09-24
| | | | | | | | Problem: ui.open() appends the path to the caller's opts.cmd, so reusing the opts opens previously supplied paths again. Solution: Copy opt.cmd before appending the path.
* feat(multicursor): gQ restores primary-cursor position #42071Justin M. Keyes2026-09-24
| | | | | | | | | | | | | | | | | | | | | Problem: Unlike "gv", "gQ" does not restore the primary-cursor position. This is inconvenient for workflows where you temporarily clear the cursors, navigate somewhere, then want to return to the multicursor session. Solution: Store the primary-cursor position at extmark-id 1 of the `'nvim.multicursor.last'` namespace. Note: users that *don't* want to restore the primary-cursor position can delete extmark-id 1 from the `'nvim.multicursor.last'` namespace just before `gQ`. (Intentionally undocumented because this interface is not final, and should not block Nvim 0.13 release.) vim.keymap.set('n', 'gQ', function() local ns = vim.api.nvim_create_namespace('nvim.multicursor.last') pcall(vim.api.nvim_buf_del_extmark, 0, ns, 1) return 'gQ' end, { expr = true })
* fix(multicursor): skip gQ during an active session #42068Justin M. Keyes2026-09-24
| | | | | | | Problem: gQ is nonsense during an active multicursor session. Solution: Make it a no-op.
* vim-patch:3041cf6: runtime(filetype): improve *.h filetype detection (#42028)Humble Seer2026-09-23
| | | | | | | | | | | | | | | This commit changes *.h files to default to C (instead of C++), and deprecates the existing `g:c_syntax_for_h` and `g:ch_syntax_for_h` variables in favor of a unified `g:filetype_h`, like is used for other ambiguous file extensions. closes: vim/vim#17135 https://github.com/vim/vim/commit/3041cf67d37cc23b79b17cc2c1c09feb7c22baf7 AI-assisted Co-authored-by: Amelia Clarke <selene@perilune.dev> Co-authored-by: Christian Brabandt <cb@256bit.org>
* fix(filetype): using incorrect set of word characters (#42042)zeertzjq2026-09-23
| | | | Unlike `\w` in Vim patterns, `%w` in Lua patterns doesn't match an underscore, so `[%w_]` needs to be used instead...
* refactor(charset)!: delete 'isprint' and cleanup 'iskeyword' and friendsbfredl2026-09-22
| | | | | | | | | | | | | In the `enc=utf-8` only world, the 'isprint' option is quite obsolete. The function is only consulted for decoded U+0080 to U+00FF chars whose printability is defined by the unicode charset, just like higher codepoints. Meanwhile, invalid `\x80` to `\xFF` bytes are always unprintable. Disentangle 'iskeyword', 'isfname' and 'isident' from each other by giving them all separate bitsets. Now these can be updated individually. These updaters can back out of errors gracefully, no need for extra panic logic in option[str].c to restore partially updated chartabs.
* fix(multicursor): revert "]C"/"[C" cursor-plopping behavior #42034Justin M. Keyes2026-09-22
| | | | | | | | | | | | | Problem: Jumping to a cursor adds one at the old position, so navigation has a side-effect. "]CQ" no longer deletes a cursor, and returning with "[C" after wandering off adds a cursor wherever you were. This is useful in some cases, but as a default it is surprising. The default behavior should be simple and composable. Solution: Revert the "]C"/"[C" cursor-plopping behavior. Document a mapping for the "rotate" behavior.
* fix(multicursor): may exceed kitty cursors param limit #42029Justin M. Keyes2026-09-21
| | | | | | | | Problem: If there are >85 cursors on-screen, the terminal barfs the termcodes to the screen. Solution: Emit the coords in chunks. Only "0;4" clears, so the groups accumulate.
* fix(help): follow symlink files in :helptags #42008Shougo2026-09-20
|
* fix(options): validate nvim_set_option_value() dry runsLewis Russell2026-09-18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: nvim_set_option_value() with dry_run=true accepts invalid values such as foldmethod='nonsense'. Validation is mixed with side effects in the did_set_* callbacks, so dry runs skip it. Solution: Split value validation out of the did_set_* callbacks into separate validation_cb callbacks. Use these checks for both normal assignments and nvim_set_option_value() dry runs. Keep side effects in did_set_*. Replace direct foldenable/foldlevel assignments in C folding commands with setters. This gives C commands the same OptionSet and synchronization behavior as Lua assignments. Use normal setters for 'tabstop' and 'vartabstop' in :retab so C code indentation and folds based on indentation use the new tab widths. Direct assignments could leave them using the old widths. :retab temporarily turns off 'list' to calculate tab widths. Previously, :retab -1 reported an error and returned without restoring 'list'. Check the argument before turning 'list' off, so an invalid argument leaves the option unchanged. AI-assisted
* fix(lsp): silently ignore unknown folding range kinds (#41964)Maria Solano2026-09-18
|
* feat(multicursor): color extra Kitty cursors #41935phanium2026-09-18
| | | | | | | | | | | Problem: Extra cursors use shape 29 (follow primary), so they render identically to the primary instead of using hl-MCursor colors. Solution: Send MCursor fg/bg as sRGB via shapes 30/40 before placing cursors. Terminals without 30/40 support ignore the color sequences. AI-assisted
* docs(lua): v:event field annotations #41963glepnir2026-09-18
|
* docs(pack): mention `:checkhealth vim.pack` #41955Evgeni Chasnovski2026-09-18
| | | | | | Problem: No explicit recommendations about how to check for possible issues related to `vim.pack`. Soltuion: Mention `:checkhealth vim.pack` explicitlye as a recipe.
* fix(filetype): empty 'filetype' skips :setfiletype #41958Justin M. Keyes2026-09-17
| | | | | | | | | | | | | Problem: After `:restart` a restored buffer can have an empty 'filetype'. Lazy LSP setup during the read replays FileType via `:doautoall`, which sets `did_filetype` even though `filetype=''`. :e foo.md :restart :set ft? " filetype= Solution: Set `did_filetype` only if 'filetype' is non-empty.
* perf(hightlight): compute only bounds for non-blockwise highlightsVolodymyr Chernetskyi2026-09-16
| | | | | | | | | | | | | Problem: vim.hl.range() computes a segment for every selected line, then discards all but the outer endpoints for characterwise and linewise highlights. This makes highlighting large yanks and puts unnecessarily expensive. Solution: Use getregionpos() with bounds=true for these highlights. Also use bounds in the keymap example that only needs the first and last selected lines. AI-assisted
* fix(lua): add missing param annotations (#41911)Lewis Russell2026-09-15
|
* vim-patch:9.2.1107: getregionpos() is slow when only the region bounds are ↵Volodymyr Chernetskyi2026-09-15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | needed (#41925) Problem: getregionpos() returns a pair of positions for every line, so obtaining just the outer endpoints of a region costs O(lines); for a 100000 line region that is about 1.4 million list allocations for a result of which the caller keeps two positions. Solution: Add a "bounds" item to {opts} that returns a single pair with the start on the first line and the end on the last line (Volodymyr Chernetskyi). The lines in between do not influence the outer endpoints, so with "bounds" they are not visited at all. The two positions then come from different lines and describe a diagonal of the region rather than its shape; for a blockwise region they are the start of the first line and the end of the last line, not the corners of the block. This is exactly what indexing the full result gives, so the awkward corners are kept as they are, including an empty first line yielding a "col" of 0 for the start while the end keeps its own column. On a 100000 line buffer this takes getregionpos() from about 45 ms to about 0.003 ms per call. closes: vim/vim#21209 https://github.com/vim/vim/commit/2173c3e4eceedc76c4fd7d56cdbfbbd35e9be853
* fix(fs): honor the starting directory as an upward search stop #41886Volodymyr Chernetskyi2026-09-15
| | | | | | | | | | | | Problem: An upward find() searches its initial directory before checking stop, so path=stop can return a match or continue above the stop directory. Downward search already stops before searching when path equals stop. Solution: Check the starting path before searching upward, matching the existing downward search behavior. AI-assisted
* refactor(pos): only get current buf once #41905Eman Resu2026-09-14
| | | | This check is already performed by M.new() - there's no need to do it multiple times.
* fix(loader): use the statistic name when printing its heading #41887Volodymyr Chernetskyi2026-09-12
| | | | | | | | | | Problem: Printing loader statistics concatenates the statistics table into the heading, raising an error before displaying the results. Solution: Use the iteration key for the heading. Cover printing loader statistics. AI-assisted
* fix(range): preserve single-character intersections #41881Volodymyr Chernetskyi2026-09-12
| | | | | | | | | | | Problem: Intersection rejects ranges whose inclusive end equals the other start, discarding a shared character and even a one-character self-intersection. Solution: Use strict comparisons when checking inclusive ends for non-overlap. Cover two ranges that share a single character. AI-assisted
* fix(range): use the preceding line for inclusive end marks #41880Volodymyr Chernetskyi2026-09-12
| | | | | | | | | | | Problem: Converting an exclusive end at column zero moves to the preceding row but calculates the inclusive column from the original row's text. Solution: Read the preceding line after decrementing the row. Cover adjacent lines with unequal lengths. AI-assisted
* vim-patch:9.2.1080: filetype: not all crontab files are recognized (#41874)zeertzjq2026-09-12
| | | | | | | | | | | Problem: filetype: not all crontab files are recognized (efahl) Solution: Detect crontabs.* as crontab filetype fixes: vim/vim#21253 https://github.com/vim/vim/commit/86a3567396d6f5fca6b4222363a8201308795a49 Co-authored-by: Christian Brabandt <cb@256bit.org>
* feat(dir): open entries in splits with a, o mappings #41834Barrett Ruth2026-09-11
|
* feat(multicursor): {Visual}[count]Q matches in Visual selection #41863Justin M. Keyes2026-09-11
| | | | | | | | | | | | | | Problem: `[count]Q` cannot be limited to a Visual selection. Solution: `{Visual}[count]Q` places cursors on matches within a Visual selection (linewise). TODO: This works linewise, even if the visual selection is charwise/block. If we really want to limit by charwise/block selection, then we should add that feature to `seachpos()` or similar. Every caller of `seachpos()` should not have to cobble together bespoke support thereof.
* fix(multicursor): {Visual}Q should not move primary cursor #41862Justin M. Keyes2026-09-11
| | | | | | | | | Problem: `{Visual}Q` moves the primary to the top of the selection, for no particular reason. And it's inconsistent with `[count]Q`. Solution: Keep the primary on the line where the selection ended, aligned to the shared screen column so it still coincides with that line's cursor.
* fix(lsp): snippet is not expanded when resolve races the user #41774glepnir2026-09-11
| | | | | | | | | | | Problem: on_complete_done() defers clear_word() and the snippet expansion until completionItem/resolve answers, and drops both when 'changedtick' moved meanwhile. Typing right after accepting leaves the plain word in the buffer. Solution: Expand before requesting, and anchor the resolved edits with an extmark instead of gating them on 'changedtick'.
* feat(lsp): support timeout_ms for async formatting #41850Barrett Ruth2026-09-11
| | | | | | | | | Problem: `vim.lsp.buf.format()` does not support a timeout for asynchronous requests. Solution: Honor an explicit timeouts per client so formatting can continue. Do not permit a default value for async format requests.