diff options
| author | Yi Ming <ofseed@foxmail.com> | 2025-09-01 23:46:29 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-09-01 08:46:29 -0700 |
| commit | 6888f65be1772f34a35a324c7f3d817e486fc0ab (patch) | |
| tree | f8a05b278b0ea8b61905bb9ddac6e5310f28677a /runtime/lua/vim/lsp/inline_completion.lua | |
| parent | 06df3376170f407b40af8b73b872da7b0f2a98f0 (diff) | |
| download | rneovim-6888f65be1772f34a35a324c7f3d817e486fc0ab.tar.gz rneovim-6888f65be1772f34a35a324c7f3d817e486fc0ab.tar.bz2 rneovim-6888f65be1772f34a35a324c7f3d817e486fc0ab.zip | |
feat(lsp): vim.lsp.inline_completion on_accept #35507
Diffstat (limited to 'runtime/lua/vim/lsp/inline_completion.lua')
| -rw-r--r-- | runtime/lua/vim/lsp/inline_completion.lua | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/runtime/lua/vim/lsp/inline_completion.lua b/runtime/lua/vim/lsp/inline_completion.lua index 1d9be0bcfa..64bf2a1cb8 100644 --- a/runtime/lua/vim/lsp/inline_completion.lua +++ b/runtime/lua/vim/lsp/inline_completion.lua @@ -11,11 +11,11 @@ local M = {} local namespace = api.nvim_create_namespace('nvim.lsp.inline_completion') ----@class (private) vim.lsp.inline_completion.CurrentItem ----@field index integer The index among all items form all clients. +---@class vim.lsp.inline_completion.Item +---@field _index integer The index among all items form all clients. ---@field client_id integer Client ID ---@field insert_text string|lsp.StringValue The text to be inserted, can be a snippet. ----@field filter_text? string +---@field _filter_text? string ---@field range? vim.Range Which range it be applied. ---@field command? lsp.Command Corresponding server command. @@ -25,7 +25,7 @@ local namespace = api.nvim_create_namespace('nvim.lsp.inline_completion') ---@class (private) vim.lsp.inline_completion.Completor : vim.lsp.Capability ---@field active table<integer, vim.lsp.inline_completion.Completor?> ---@field timer? uv.uv_timer_t Timer for debouncing automatic requests ----@field current? vim.lsp.inline_completion.CurrentItem Currently selected item +---@field current? vim.lsp.inline_completion.Item Currently selected item ---@field client_state table<integer, vim.lsp.inline_completion.ClientState> local Completor = { name = 'inline_completion', @@ -146,11 +146,11 @@ function Completor:select(index, show_index) local client = assert(vim.lsp.get_client_by_id(client_id)) local range = item.range and vim.range.lsp(self.bufnr, item.range, client.offset_encoding) self.current = { - index = index, + _index = index, client_id = client_id, insert_text = item.insertText, range = range, - filter_text = item.filterText, + _filter_text = item.filterText, command = item.command, } @@ -281,19 +281,14 @@ function Completor:abort() self.current = nil end ---- Apply the current completion item to the buffer. +--- Accept the current completion item to the buffer. --- ---@package -function Completor:apply() - local current = self.current - self:abort() - if not current then - return - end - - local insert_text = current.insert_text +---@param item vim.lsp.inline_completion.Item +function Completor:accept(item) + local insert_text = item.insert_text if type(insert_text) == 'string' then - local range = current.range + local range = item.range if range then local lines = vim.split(insert_text, '\n') api.nvim_buf_set_text( @@ -304,7 +299,7 @@ function Completor:apply() range.end_.col, lines ) - local pos = range.start:to_cursor() + local pos = item.range.start:to_cursor() api.nvim_win_set_cursor(vim.fn.bufwinid(self.bufnr), { pos[1] + #lines - 1, (#lines == 1 and pos[2] or 0) + #lines[#lines], @@ -317,9 +312,9 @@ function Completor:apply() end -- Execute the command *after* inserting this completion. - if current.command then - local client = assert(vim.lsp.get_client_by_id(current.client_id)) - client:exec_cmd(current.command, { bufnr = self.bufnr }) + if item.command then + local client = assert(vim.lsp.get_client_by_id(item.client_id)) + client:exec_cmd(item.command, { bufnr = self.bufnr }) end end @@ -381,7 +376,7 @@ function M.select(opts) end local n = completor:count_items() - local index = current.index + count + local index = current._index + count if wrap then index = (index - 1) % n + 1 else @@ -396,10 +391,15 @@ end --- Buffer handle, or 0 for current. --- (default: 0) ---@field bufnr? integer +--- +--- Accept handler, called with the accepted item. +--- If not provided, the default handler is used, +--- which applies changes to the buffer based on the completion item. +---@field on_accept? fun(item: vim.lsp.inline_completion.Item) ---- Apply the currently displayed completion candidate to the buffer. +--- Accept the currently displayed completion candidate to the buffer. --- ---- It returns false when no candidate can be applied, +--- It returns false when no candidate can be accepted, --- so you can use the return value to implement a fallback: --- --- ```lua @@ -420,11 +420,23 @@ function M.get(opts) opts = opts or {} local bufnr = vim._resolve_bufnr(opts.bufnr) + local on_accept = opts.on_accept + local completor = Completor.active[bufnr] if completor and completor.current then -- Schedule apply to allow `get()` can be mapped with `<expr>`. vim.schedule(function() - completor:apply() + local item = completor.current + completor:abort() + if not item then + return + end + + if on_accept then + on_accept(item) + else + completor:accept(item) + end end) return true end |