summaryrefslogtreecommitdiffstatshomepage
path: root/runtime/lua/vim/lsp/completion.lua
AgeCommit message (Collapse)AuthorFiles
2026-04-18fix(lsp): show CompletionItem.detail in info popup #38904glepnir1
Problem: completionItem/resolve response's `detail` field is silently dropped. Only `documentation` is shown in the popup. Solution: Prepend `detail` as a fenced code block before `documentation` in the info popup, skipping if documentation already contains it.
2026-04-13feat(completion): completeopt=preselect, LSP CompletionItem.preselect #36613glepnir1
Problem: LSP CompletionItem.preselect is not supported. https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionClientCapabilities Solution: - Add "preselect" field to complete-items and "preselect" flag to 'completeopt'. - Set preselectSupport=true in LSP client capabilities.
2026-04-08feat(api): rename buffer to buf #35330Jordan1
Problem: `:help dev-name-common` states that "buf" should be used instead of "buffer" but there are cases where buffer is mentioned in the lua API. Solution: - Rename occurrences of "buffer" to "buf" for consistency with the documentation. - Support (but deprecate) "buffer" for backwards compatibility. Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
2026-03-29fix(lsp): highlight snippet preview when server can't completionItem/resolve ↵Marcus Caisey1
(#38534) Problem: The snippet preview is not being highlighted by treesitter for completion items from servers which don't support `completionItem/resolve` (like gopls). This was broken by #38428. Solution: Call `update_popup_window` after updating the completion item with the snippet preview. I've added assertions to the `selecting an item triggers completionItem/resolve + (snippet) preview` test case which covers the snippet preview being shown since no tests failed when I removed the `nvim__complete_set` call which actually populates the preview on this codepath.
2026-03-23fix(lsp): completion word includes leading space from label #38435glepnir1
Problem: clangd prepends a space/bullet indicator to label. With labelDetailsSupport enabled, the signature moves to labelDetails, making label shorter. This flips the length comparison in get_completion_word, causing it to use item.label directly and insert the indicator into the buffer. Solution: only prefer filterText over label when label starts with non-keyword character in get_completion_word fallback branch.
2026-03-23fix(lsp): snippet preview blocked completionItem/resolve request #38428glepnir1
Problem: Generating snippet preview in get_doc() populated the documentation field before resolve, so the resolve request was never sent. Solution: Move snippet preview logic into on_completechanged and the resolve callback so it no longer blocks the resolve request.
2026-03-21feat(lsp): support CompletionItem.labelDetails #38403glepnir1
Problem: CompletionItem.labelDetails is ignored, losing function signatures and module info in the completion menu. Solution: Append labelDetails.detail to abbr and use labelDetails.description for menu with fallback to item.detail. https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItemLabelDetails
2026-03-20fix(lsp): handle completion/resolve response arriving after on_insert_leaveMathias Fussenegger1
If a user accepts completion and immediately exits insert mode, it could happen that `Context.cursor` was nil by the time the `completion/resolve` response arrives, leading to an error.
2026-03-18docs: misc, terminalJustin M. Keyes1
Close #38319 Close #38348 Co-authored-by: zeertzjq <zeertzjq@outlook.com> Co-authored-by: Barrett Ruth <br.barrettruth@gmail.com>
2026-03-17fix(lsp): respect documentation markup kind in completion preview #38338glepnir1
Problem: Completion preview always assumes plain text, ignoring LSP documentation "kind". Solution: Pass markup kind from completion item to info window, or fallback to PlainText.
2026-03-14fix(lsp): handle non-string documentation in completion items #38291glepnir1
Problem: `get_doc` throws error with "attempt to get length of a userdata value" when `item.documentation` is truthy but not a string (e.g. vim.NIL from a JSON null). Solution: Check `type(item.documentation)` before taking its length.
2026-03-13refactor: rename _ensure_integer => _assert_integerJustin M. Keyes1
2026-03-12refactor: integer functions, optimize asserts #34112Lewis Russell1
refactor(lua): add integer coercion helpers Add vim._tointeger() and vim._ensure_integer(), including optional base support, and switch integer-only tonumber()/assert call sites in the Lua runtime to use them. This also cleans up related integer parsing in LSP, health, loader, URI, tohtml, and Treesitter code. supported by AI
2026-03-12docs: use "ev" convention in event-handlersJustin M. Keyes1
Problem: In autocmd examples, using "args" as the event-object name is vague and may be confused with a user-command. Solution: Use "ev" as the conventional event-object name.
2026-03-11fix(lsp): ensure augroup before querying autocmds #38254glepnir1
2026-03-11docs: api, messages, lsp, trustJustin M. Keyes1
gen_vimdoc.lua: In prepare for the upcoming release, comment-out the "Experimental" warning for prerelease features.
2026-03-11feat(lsp): do completionItem/resolve if completeopt=popup #32820glepnir1
Problem: No completionItem/resolve handler. Solution: If completeopt=popup is set, invoke completionItem/resolve when a completion item is selected. Show resolved documentation in popup next to the completion menu.
2026-03-10feat(lsp): show snippet preview if completeopt=popup #32553glepnir1
Problem: LSP completion does not show snippet preview. Solution: Show snippet preview if 'completeopt' includes popup.
2026-02-28feat(lsp): show color preview in completion items #32138glepnir1
Problem: Color completion items display as plain text without visual preview Solution: Parse RGB/hex colors from documentation and render with colored symbol ■
2026-02-22fix(lsp): vim.lsp.completion clean up triggers on client detach (#38009)glepnir1
Problem: LspDetach didn't clean up stale client refs in triggers table. Solution: create LspDetach autocmd and call disable_completion.
2026-02-18fix(lsp): use entire line as completion word (#37949)Maria Solano1
2026-02-09fix(lsp): error on omnifunc completion (#37790)phanium1
Problem: After eaacdc9, complete with emmylua_ls error with: runtime/lua/vim/lsp/completion.lua:586: attempt to get length of field 'items' (a nil value) Solution: Result can be CompletionItem[] according the spec: > If a `CompletionItem[]` is provided, it is interpreted to be complete, > so it is the same as `{ isIncomplete: false, items }`
2026-02-08fix(lsp): ignore empty response on trigger completion #37663Tomasz N1
Problem: Empty response affects server start boundary computed before. Solution: Ignore empty responses. This is mostly micro-optimization that avoids extending existing results with empty responses.
2026-02-03fix(lsp): don't empty server start-boundary by next client response #37665Tomasz N1
Problem: Server start boundary can be emptied by response provided by next client. Solution: Don't empty it when extending the result list.
2026-01-30fix(lsp): use LSP textEdit range for completion start boundary (#37491)Harsh Kapse1
Previously, adjust_start_col returned nil when completion items had different start position from lsp textEdit range This caused the completion to fall back to \k*$ which ignores the non-keyword characters Changes: - adjust_start_col: now returns the minimum start postion among all items instead of nil - _lsp_to_complete_items - normalizes the items by adding the gap between current and minimum start Fixes: https://github.com/neovim/neovim/issues/37441
2025-12-16fix(lsp): sort items when completeopt include fuzzy #36974glepnir1
Problem: When fuzzy is enabled and the prefix is not empty, items are not sorted by fuzzy score before calling fn.complete. Solution: Use matchfuzzypos to get the scores and sort the items by fuzzy score before calling fn.complete.
2025-11-18fix(lsp): enable insertReplaceSupport for use in adjust_start_col #36569Jeff Martin1
Problem: With the typescript LSes typescript-language-server and vtsls, omnicompletion on partial tokens for certain types, such as array methods, and functions that are attached as attributes to other functions, either results in no entries populated in the completion menu (typescript-language-server), or an unfiltered completion menu with all array methods included, even if they don't share the same prefix as the partial token being completed (vtsls). Solution: Enable insertReplaceSupport and uses the insert portion of the lsp completion response in adjust_start_col if it's included in the response. Completion results are still filtered client side.
2025-11-18feat(lsp): user-specified sorting of lsp.completion multi-server results #36401glepnir1
Problem: No way to customize completion order across multiple servers. Solution: Add `cmp` function to `vim.lsp.completion.enable()` options for custom sorting logic.
2025-10-20fix(lsp): deduplicate completion items #36166Till Bungert1
The current implementation has a race condition where items are appended to the completion list twice when a second completion runs while the first is still going. This hotfix just deduplicates the entire list. Co-authored-by: Tomasz N <przepompownia@users.noreply.github.com>
2025-10-11fix: vim.lsp.omnifunc should not throw away other items #35346Till Bungert1
2025-10-04fix(lsp): deprecate `vim.lsp.protocol.Methods` (#35998)Maria Solano1
2025-09-17fix(lsp): treat 2-triggers-at-once as "last char wins" #35435Tomasz N1
Problem: If there are 2 language servers with different trigger chars (`-` and `>`), and a keymap inputs both simultaneously (`->`), then `>` doesn't trigger. We get completion items from server1 only. This happens because the `completion_timer` for the `-` trigger is still pending. Solution: If the next character arrived enough quickly (< 25 ms), replace the existing deferred autotrigger with a new one that matches this later character.
2025-08-28refactor(lua): consistent use of local aliasesChristian Clason1
2025-08-03vim-patch:9.1.1590: cannot perform autocompletion (#35141)zeertzjq1
Problem: cannot perform autocompletion Solution: Add the 'autocomplete' option value (Girish Palya) This change introduces the 'autocomplete' ('ac') boolean option to enable automatic popup menu completion during insert mode. When enabled, Vim shows a completion menu as you type, similar to pressing |i\_CTRL-N| manually. The items are collected from sources defined in the 'complete' option. To ensure responsiveness, this feature uses a time-sliced strategy: - Sources earlier in the 'complete' list are given more time. - If a source exceeds its allocated timeout, it is interrupted. - The next source is then started with a reduced timeout (exponentially decayed). - A small minimum ensures every source still gets a brief chance to contribute. The feature is fully compatible with other |i_CTRL-X| completion modes, which can temporarily suspend automatic completion when triggered. See :help 'autocomplete' and :help ins-autocompletion for more details. To try it out, use :set ac You should see a popup menu appear automatically with suggestions. This works seamlessly across: - Large files (multi-gigabyte size) - Massive codebases (:argadd thousands of .c or .h files) - Large dictionaries via the `k` option - Slow or blocking LSP servers or user-defined 'completefunc' Despite potential slowness in sources, the menu remains fast, responsive, and useful. Compatibility: This mode is fully compatible with existing completion methods. You can still invoke any CTRL-X based completion (e.g., CTRL-X CTRL-F for filenames) at any time (CTRL-X temporarily suspends 'autocomplete'). To specifically use i_CTRL-N, dismiss the current popup by pressing CTRL-E first. --- How it works To keep completion snappy under all conditions, autocompletion uses a decaying time-sliced algorithm: - Starts with an initial timeout (80ms). - If a source does not complete within the timeout, it's interrupted and the timeout is halved for the next source. - This continues recursively until a minimum timeout (5ms) is reached. - All sources are given a chance, but slower ones are de-prioritized quickly. Most of the time, matches are computed well within the initial window. --- Implementation details - Completion logic is mostly triggered in `edit.c` and handled in insexpand.c. - Uses existing inc_compl_check_keys() mechanism, so no new polling hooks are needed. - The completion system already checks for user input periodically; it now also checks for timer expiry. --- Design notes - The menu doesn't continuously update after it's shown to prevent visual distraction (due to resizing) and ensure the internal list stays synchronized with the displayed menu. - The 'complete' option determines priority—sources listed earlier get more time. - The exponential time-decay mechanism prevents indefinite collection, contributing to low CPU usage and a minimal memory footprint. - Timeout values are intentionally not configurable—this system is optimized to "just work" out of the box. If autocompletion feels slow, it typically indicates a deeper performance bottleneck (e.g., a slow custom function not using `complete_check()`) rather than a configuration issue. --- Performance Based on testing, the total roundtrip time for completion is generally under 200ms. For common usage, it often responds in under 50ms on an average laptop, which falls within the "feels instantaneous" category (sub-100ms) for perceived user experience. | Upper Bound (ms) | Perceived UX |----------------- |------------- | <100 ms | Excellent; instantaneous | <200 ms | Good; snappy | >300 ms | Noticeable lag | >500 ms | Sluggish/Broken --- Why this belongs in core: - Minimal and focused implementation, tightly integrated with existing Insert-mode completion logic. - Zero reliance on autocommands and external scripting. - Makes full use of Vim’s highly composable 'complete' infrastructure while avoiding the complexity of plugin-based solutions. - Gives users C native autocompletion with excellent responsiveness and no configuration overhead. - Adds a key UX functionality in a simple, performant, and Vim-like way. closes: vim/vim#17812 https://github.com/vim/vim/commit/af9a7a04f18693eee4400dd134135527f4e8cd5f Co-authored-by: Girish Palya <girishji@gmail.com>
2025-06-23refactor(lsp): use `vim.lsp.buf_request_all` internally (#34604)Maria José Solano1
2025-06-06fix: type fixesLewis Russell1
Type fixes caught by emmylua
2025-05-22fix(lsp): fix error with InsertReplaceEdit events #33973Evan Hahn1
Problem: Some LSPs cause the following completion error (reformatted slightly): Error executing vim.schedule lua callback: .../runtime/lua/vim/lsp/completion.lua:373 attempt to index field 'range' (a nil value) This is because an internal function assumes edits are either missing or of type `TextEdit`, but there's a third [possibility][0] that's not handled: the `InsertReplaceEdit`. This was previously reported in at least two issues: - https://github.com/neovim/neovim/issues/33142 - https://github.com/neovim/neovim/issues/33224 Solution: Don't assume the edit is a `TextEdit`. This implicitly handles `InsertReplaceEdit`s. Also, add a test case for this, which previously caused an error. [0]: https://github.com/neovim/neovim/blob/2c07428966a74c76003e00e2a37bf98eb8802c93/runtime/lua/vim/lsp/_meta/protocol.lua#L1099
2025-05-04fix(lsp): improve error completion message #33812glepnir1
problem: Error notifications from LSP responses were difficult to read due to inconsistent formatting and missing critical information like client name and error codes. solution: Implemented a more structured error notification format using pipe separators to clearly display client name, error code (when available), and error message.
2025-03-26docs(lsp): completion.enable #33063Mathias Fußenegger1
2025-03-26docs: news, lsp autocomplete #33047Justin M. Keyes1
2025-03-21docs: LSP completion #33006Justin M. Keyes1
2025-03-17docs: miscJustin M. Keyes1
2025-03-16refactor(lsp)!: rename lsp.completion.trigger() to get() (#32911)Mathias Fußenegger1
Problem: `trigger` is a custom word not yet used in APIs. Solution: Use `get` instead because the main effect is that the completion candidates will be collected (and shown by default, but follow-up commits are planned to add an `on_result` callback that allows more general handling). --------- Co-authored-by: Christian Clason <c.clason@uni-graz.at>
2025-03-11fix(lsp): wrapped ctx in opts before passed to vim.lsp.completion.trigger #32837glepnir1
Problem: ctx is passed directly to M.trigger. In fact, it is a field of opts. Solution: wrapped in a table and passed to M.trigger.
2025-03-10feat(lsp): support completion context #32793Maria José Solano1
Problem: vim.lsp.completion with "autotrigger" enabled, does not send completion context, even though it has all the necessary info. Solution: Include the context for "autotrigger". trigger() also optionally accepts context when manually invoked.
2025-03-02docs: misc #31996Justin M. Keyes1
2025-02-22fix(lsp): unify get_completion_word for textEdits/insertTextMathias Fussenegger1
Problem: After https://github.com/neovim/neovim/pull/32377 selecting snippets provided by luals inserted the multi-line text before accepting the candidates. That's inconsistent with servers who provide `textEdit` instead of `insertText` and having lines shift up/down while cycling through the completion candidates is a bit irritating. Solution: Use the logic used for `textEdit` snippets also for `insertText`
2025-02-14feat(lsp): add support for completionItem.command resolvingMathias Fussenegger1
`command` was already resolved via a `completionItem/resolve` request but only if `additionalTextEdits` were also present, and the `resolveSupport` capability wasn't listed. Closes https://github.com/neovim/neovim/issues/32406
2025-02-13fix(lsp): clear word when expand multi-lines word (#32393)glepnir1
Problem: When expanding a completion item that contains a multi-line word, the word is not deleted correctly. Solution: If the word contains a line break, delete the text from Context.cursor to the current cursor position.
2025-02-13fix(lsp): autotrigger should only trigger on client's triggerCharacters (#32266)Robert Muir1
Problem: autotrigger option of vim.lsp.completion.enable() would trigger all clients, as long as it matched at least one client's triggerCharacters. Solution: trigger only the clients with triggerCharacters matching the character. overtriggering still happens if any client returns isIncomplete=true (this case is more involved). Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>