aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/inline_completion.lua
Commit message (Collapse)AuthorAge
* 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): 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(lsp): advance inline completion range over matching input #41434Étienne Robert2026-08-24
| | | | | | | | | | | | | | | Problem: `Completor:accept()` applies the item against the range the server answered with. Characters typed after the request but before accepting lie inside neither that range nor the replacement, so they are left behind by the insertion: typing `a` after `foob` and accepting `foobar` within the 200 ms debounce yields `foobara`. Solution: Grow the item's range over the characters typed since the request, so that `accept()` replaces them. Only while the candidate still matches, decided by the longest common prefix `show()` already computes, so input that contradicts it is left alone. Snippet items are unaffected, since `accept()` ignores the range for them.
* fix(lsp): clamp inline completion range to the line on accept #41435Étienne Robert2026-08-24
| | | | | | | | | | | | | | | | | | Problem: `Completor:accept()` hands the item's range straight to `nvim_buf_set_text()`. That range is resolved when the response arrives, so text deleted before accepting (backspacing within the 200 ms debounce) leaves the range end past what is left of the line, and the accept aborts with `Invalid 'end_col': out of range`. 18d6436 fixed the same staleness in `Completor:show()`, which drops an item once its range *start* falls outside the buffer. That guard does not cover the range end, and `accept()` was never given one, so this is a hole left by that fix rather than a regression of it. Solution: Clamp the end of the range to the end of the line before writing. The start needs no clamp: `show()` dropped the item one event loop tick earlier if it had gone out of range.
* feat(extmark): virt_lines can highlight until EOL #41289Goldpigg2026-08-18
|
* refactor(lsp): unify LspNotify, decor provider for capabilities #40691jdrouhard2026-07-15
| | | | | | | | | | | | | | | | | | | | | | | | | Problem: Every LSP capability that sends a request on a document change to update its state was using its own buffer-local autocmd to do so. That means there is a separate autocmd per buffer per active capability/feature, and the actual code inside the autocmd callback was virtually identical. The same problem occurred for capabilities that had components to draw on the screen that had their own decoration providers. Solution: Introduce a central `LspNotify` autocmd and decoration provider in the capability module itself. New base class methods `on_close` and `on_change` that take a client_id have been provided, for `didClose` and `didOpen`/`didChange` notifications respectively. New base class method `on_win` that takes topline and botline has been provided to add extmarks or perform other work when lines of a buffer are being drawn. The autocmd callback loops through each active capability instance for the buffer and calls a corresponding method with the triggering client_id if it is currently attached to the buffer that triggered the autocmd. The decoration provider just calls on_win for all active capabilities on the buffer. This slightly tweaks folding range to make use of these new client-id specific callbacks.
* refactor: introduce nvim_on internally #39883Justin M. Keyes2026-05-20
| | | | | | | | | Problem: `nvim_create_autocmd` is too verbose and its `callback` requires extra "nesting". Solution: Introduce `nvim_on`. Start using it internally. Then we can get a feel for how it should look before making it public.
* feat(pos,range)!: remove `range.cursor()` and `range:to_cursor()`,Yi Ming2026-05-20
| | | | | | | | | | | | | Problem: - A window can only have one cursor, ranges selected by the cursor are typically obtained by marks like ">" and "<", instead of calling get_cursor() twice. - `vim.Range` is described as end-exclusive, but the current `range.cursor()`/`range:to_cursor()` are end-inclusive. - Conversion between `vim.Range` and mark-indexed range can be done by `range.mark()`/`range:to_mark()` Solution: Remove `range.cursor()` and `range:to_cursor()`,
* docs: misc #39511Justin M. Keyes2026-04-29
|
* refactor: update usages of deprecated "buffer" param #39089Justin M. Keyes2026-04-15
|
* feat(vim.pos)!: require `buf` param on vim.pos, vim.range #38665Luis Calle2026-04-06
| | | | | | | Problem: `buf` is optional even though its needed to perform conversions and the ordering of `(buf, row, col)` is not consistent. Solution: make `buf` mandatory on `vim.range` and `vim.pos` and enforce the `buf, row, col` ordering
* feat: extend vim.Pos, vim.Range #36397Luis Calle2026-03-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: Using nested `vim.Pos` objects to represent each `vim.Range` object requires 3 tables for each `vim.Range`, which may be undesirable in performance critical code. Using key-value tables performs worse than using array-like tables (lists). Solution: Use array-like indices for the internal fields of both `vim.Pos` and `vim.Range` objects. Use a metatable to allow users to access them like if they were key-value tables. --- Problem: The `vim.Pos` conversion interface for `extmark` indexing does not take into account the difference in how a position on top of a newline is represented in `vim.Pos` and `extmark`. - `vim.Pos`: for a newline at the end of row `n`, `row` takes the value `n + 1` and `col` takes the value `0`. - `extmark`: for a newline at the end of for `n`, `row` takes the value `n` and `col` takes the value `#row_text`. Solution: Handle this in the `extmark` interface. --- Problem: Not all `to_xxx` interfaces have wrapping objects like `to_lsp`. Solution: Return unwrapped values in `to_xxx` interfaces where it makes sense. Accept unwrapped values in "from" interfaces where it makes sense. --- Problem: `start` and `end` positions have different semantics, so they can't be compared. `vim.Range` relies on comparing the `end` and `start` of two ranges to decide which one is greater, which doesn't work as expected because this of the different semantics. For example, for the ranges: local a = { start = { row = 0, col = 22, }, end_ = { row = 0, col = 24, }, } local b = { start = { row = 0, col = 17, }, end_ = { row = 0, col = 22, }, } in this code: local foo, bar = "foo", "bar" -- |---||-| -- b a The range `b` is smaller than the range `a`, but the current implementation compares `b._end` (`col = 22`) and `a.start` (`col = 22`) and concludes that, since `b.col` is not smaller than `a.col`, `b` should be greater than `a`. Solution: - Use a `to_inclusive_pos` to normalize end positions inside of `vim.Range` whenever a comparison between a start and an end position is necessary.
* docs(lsp): add `init_options` to Copilot example #38502Maria Solano2026-03-27
| | | | | | | Problem: When following this example from our docs the Copilot LSP won't attach. Solution: Add `init_options` as done by [`nvim-lspconfig`](https://github.com/neovim/nvim-lspconfig/blob/1a6d69206749a646ef28bfb39460610b14baff40/lsp/copilot.lua#L112-L121).
* fix(lsp): unify LSP error logging prefixes #38354Yi Ming2026-03-20
| | | | | | | Problem The format of LSP log messages is inconsistent; some include underscores, while others are not logged at all. Solution Standardize log recording and unify the log message prefixes with the module names.
* fix(lsp): stop and close timer when `Capability` is destroyedYi Ming2026-03-09
|
* feat(lsp): on_accept can return item to customize behavior #37092Yi Ming2025-12-26
| | | | | | | | Problem: `on_accept` is a bit cumbersome to customize. Solution: * Before: users had to override the entire `on_accept` logic for their changes to be applied. * Now: users can modify the item and return it to apply the modified changes, or return `nil` to fully customize how the changes are applied.
* fix(lsp): don't overlay insertion-style inline completions (#36477)Riley Bruins2025-11-09
| | | | | | | | | | | | | | | * feat(lua): `Range:is_empty()` to check vim.range emptiness * fix(lsp): don't overlay insertion-style inline completions **Problem:** Some servers commonly respond with an empty inline completion range which acts as a position where text should be inserted. However, the inline completion module assumes that all responses with a range are deletions + insertions that thus require an `overlay` display style. This causes an incorrect preview, because the virtual text should have the `inline` display style (to reflect that this is purely an insertion). **Solution:** Only use `overlay` for non-empty replacement ranges.
* fix(lsp): ignore inline completions after leaving insert mode (#36476)Riley Bruins2025-11-09
| | | | | | | | | **Problem:** When quickly entering and leaving insert mode, sometimes inline completion requests are returned and handled in normal mode. This causes an extmark to be set, which will not get cleared until the next time entering & leaving insert mode. **Solution:** Return early in the inline completion handler if we have left insert mode.
* fix(lsp): fix window to set cursor for inline completion (#36444)Folke Lemaitre2025-11-04
|
* fix(lsp): ensure bufnr is passed for buffer-local requests (#36325)skewb1k2025-10-25
| | | | | | | | | | Problem: Some LSP method handlers were making requests without specifying a bufnr, defaulting to 0 (current). This works in most cases but fails when client attaches to background buffers, causing assertions in handlers to fail. Solution: Ensure bufnr is passed to Client.request for buffer-local methods.
* fix(lsp): deprecate `vim.lsp.protocol.Methods` (#35998)Maria Solano2025-10-04
|
* fix(lsp): inlineCompletion: ignore out-of-range items #35990Yi Ming2025-10-02
|
* fix(lsp): scope inline_completion autocmds to buffer (#35965)v1nh1shungry2025-10-01
| | | | | | | | | | | | | Problem: Autocmds in inline_completion Completor are not scoped to specific buffers. When multiple buffers have inline completion enabled, events (InsertEnter, CursorMovedI, TextChangedP, InsertLeave) in any buffer trigger callbacks for all Completor instances, causing incorrect behavior across buffers. Solution: Add `buffer = bufnr` parameter to nvim_create_autocmd() calls to make them buffer-local. Each Completor instance now only responds to events in its own buffer.
* fix(lsp): avoid automatic request after leaving insert mode (#35767)zeertzjq2025-09-15
| | | | | | | | | | | | | | | | | This also fixes the following warning in tests with ASAN or TSAN: -------- Running tests from test/functional/plugin/lsp/inline_completion_spec.lua RUN T4604 vim.lsp.inline_completion enable() requests or abort when entered/left insert mode: 225.00 ms OK RUN T4605 vim.lsp.inline_completion get() applies the current candidate: 212.00 ms OK nvim took 2013 milliseconds to exit after last test This indicates a likely problem with the test even if it passed! RUN T4606 vim.lsp.inline_completion get() accepts on_accept callback: 212.00 ms OK RUN T4607 vim.lsp.inline_completion select() selects the next candidate: 220.00 ms OK -------- 4 tests from test/functional/plugin/lsp/inline_completion_spec.lua (3437.00 ms total) -------- Running tests from test/functional/plugin/lsp/linked_editing_range_spec.lua nvim took 2011 milliseconds to exit after last test This indicates a likely problem with the test even if it passed!
* docs(lsp): tweak `inline_completion.get` code snippet #35657Maria José Solano2025-09-06
| | | | `replace_keycodes` is true if `expr` is set, and "Accept" is a better term to describe the keymap.
* docs: lsp, miscJustin M. Keyes2025-09-03
| | | | | | | | | - Problem: It's not clear for new plugin developers that `:help` uses a help-tags file for searching the docs, generated by `:helptags`. - Solution: Hint to the |:helptags| docs for regenerating the tags file for their freshly written documentation. Co-authored-by: Yochem van Rosmalen <git@yochem.nl>
* feat(lsp): vim.lsp.inline_completion on_accept #35507Yi Ming2025-09-01
|
* refactor(lua): consistent use of local aliasesChristian Clason2025-08-28
|
* fix(lsp): update completion items on `TextChangedP`Yi Ming2025-08-27
|
* fix(lsp): update on `CursorHoldI` cause users unable to `select()`Yi Ming2025-08-27
|
* fix(lsp): `opts.wrap` always `true`Yi Ming2025-08-27
|
* feat(lsp): support `textDocument/inlineCompletion`Yi Ming2025-08-25