diff options
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/lsp.lua | 18 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/_changetracking.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/client.lua | 5 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/completion.lua | 49 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/inlay_hint.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/semantic_tokens.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 16 |
7 files changed, 62 insertions, 39 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index 94c31359da..c2deac0113 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -391,8 +391,8 @@ end local function on_client_exit(code, signal, client_id) local client = all_clients[client_id] - for bufnr in pairs(client.attached_buffers) do - vim.schedule(function() + vim.schedule(function() + for bufnr in pairs(client.attached_buffers) do if client and client.attached_buffers[bufnr] then api.nvim_exec_autocmds('LspDetach', { buffer = bufnr, @@ -401,15 +401,16 @@ local function on_client_exit(code, signal, client_id) }) end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) - vim.diagnostic.reset(namespace, bufnr) client.attached_buffers[bufnr] = nil if #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 then reset_defaults(bufnr) end - end) - end + end + + local namespace = vim.lsp.diagnostic.get_namespace(client_id) + vim.diagnostic.reset(namespace) + end) local name = client.name or 'unknown' @@ -483,7 +484,6 @@ local function text_document_did_save_handler(bufnr) text = lsp._buf_get_full_text(bufnr), }, }) - util.buf_versions[bufnr] = 0 end local save_capability = vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'save') if save_capability then @@ -519,7 +519,6 @@ local function buf_detach_client(bufnr, client) end client.attached_buffers[bufnr] = nil - util.buf_versions[bufnr] = nil local namespace = lsp.diagnostic.get_namespace(client.id) vim.diagnostic.reset(namespace, bufnr) @@ -575,12 +574,11 @@ local function buf_attach(bufnr) }) -- First time, so attach and set up stuff. api.nvim_buf_attach(bufnr, false, { - on_lines = function(_, _, changedtick, firstline, lastline, new_lastline) + on_lines = function(_, _, _, firstline, lastline, new_lastline) if #lsp.get_clients({ bufnr = bufnr }) == 0 then -- detach if there are no clients return #lsp.get_clients({ bufnr = bufnr, _uninitialized = true }) == 0 end - util.buf_versions[bufnr] = changedtick changetracking.send_changes(bufnr, firstline, lastline, new_lastline) end, diff --git a/runtime/lua/vim/lsp/_changetracking.lua b/runtime/lua/vim/lsp/_changetracking.lua index b2be53269f..ce701f0772 100644 --- a/runtime/lua/vim/lsp/_changetracking.lua +++ b/runtime/lua/vim/lsp/_changetracking.lua @@ -1,6 +1,5 @@ local protocol = require('vim.lsp.protocol') local sync = require('vim.lsp.sync') -local util = require('vim.lsp.util') local api = vim.api local uv = vim.uv @@ -277,7 +276,7 @@ local function send_changes(bufnr, sync_kind, state, buf_state) client.notify(protocol.Methods.textDocument_didChange, { textDocument = { uri = uri, - version = util.buf_versions[bufnr], + version = vim.b[bufnr].changedtick, }, contentChanges = changes, }) diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 327cd19125..b28fe2f797 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -673,8 +673,8 @@ function Client:_request(method, params, handler, bufnr) end -- Ensure pending didChange notifications are sent so that the server doesn't operate on a stale state changetracking.flush(self, bufnr) - local version = lsp.util.buf_versions[bufnr] bufnr = resolve_bufnr(bufnr) + local version = vim.b[bufnr].changedtick log.debug(self._log_prefix, 'client.request', self.id, method, params, handler, bufnr) local success, request_id = self.rpc.request(method, params, function(err, result) local context = { @@ -922,14 +922,13 @@ function Client:_text_document_did_open_handler(bufnr) local params = { textDocument = { - version = 0, + version = vim.b[bufnr].changedtick, uri = vim.uri_from_bufnr(bufnr), languageId = self.get_language_id(bufnr, filetype), text = lsp._buf_get_full_text(bufnr), }, } self.notify(ms.textDocument_didOpen, params) - lsp.util.buf_versions[bufnr] = params.textDocument.version -- Next chance we get, we should re-do the diagnostics vim.schedule(function() diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua index 25b3d53c8c..39c0c5fa29 100644 --- a/runtime/lua/vim/lsp/completion.lua +++ b/runtime/lua/vim/lsp/completion.lua @@ -129,18 +129,33 @@ end --- @param item lsp.CompletionItem --- @return string local function get_completion_word(item) - if item.textEdit ~= nil and item.textEdit.newText ~= nil and item.textEdit.newText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.textEdit.newText - else - return parse_snippet(item.textEdit.newText) - end - elseif item.insertText ~= nil and item.insertText ~= '' then - if item.insertTextFormat == protocol.InsertTextFormat.PlainText then - return item.insertText - else + if item.insertTextFormat == protocol.InsertTextFormat.Snippet then + if item.textEdit then + -- Use label instead of text if text has different starting characters. + -- label is used as abbr (=displayed), but word is used for filtering + -- This is required for things like postfix completion. + -- E.g. in lua: + -- + -- local f = {} + -- f@| + -- ▲ + -- └─ cursor + -- + -- item.textEdit.newText: table.insert(f, $0) + -- label: insert + -- + -- Typing `i` would remove the candidate because newText starts with `t`. + local text = item.insertText or item.textEdit.newText + return #text < #item.label and text or item.label + elseif item.insertText and item.insertText ~= '' then return parse_snippet(item.insertText) + else + return item.label end + elseif item.textEdit then + return item.textEdit.newText + elseif item.insertText and item.insertText ~= '' then + return item.insertText end return item.label end @@ -201,11 +216,17 @@ function M._lsp_to_complete_items(result, prefix, client_id) return {} end - local function matches_prefix(item) - return vim.startswith(get_completion_word(item), prefix) - end + if prefix ~= '' then + ---@param item lsp.CompletionItem + local function match_prefix(item) + if item.filterText then + return next(vim.fn.matchfuzzy({ item.filterText }, prefix)) + end + return true + end - items = vim.tbl_filter(matches_prefix, items) --[[@as lsp.CompletionItem[]|]] + items = vim.tbl_filter(match_prefix, items) --[[@as lsp.CompletionItem[]|]] + end table.sort(items, function(a, b) return (a.sortText or a.label) < (b.sortText or b.label) end) diff --git a/runtime/lua/vim/lsp/inlay_hint.lua b/runtime/lua/vim/lsp/inlay_hint.lua index f98496456b..78f309abf7 100644 --- a/runtime/lua/vim/lsp/inlay_hint.lua +++ b/runtime/lua/vim/lsp/inlay_hint.lua @@ -43,7 +43,7 @@ function M.on_inlayhint(err, result, ctx, _) return end local bufnr = assert(ctx.bufnr) - if util.buf_versions[bufnr] ~= ctx.version then + if vim.b[bufnr].changedtick ~= ctx.version then return end local client_id = ctx.client_id @@ -324,7 +324,7 @@ api.nvim_set_decoration_provider(namespace, { return end - if bufstate.version ~= util.buf_versions[bufnr] then + if bufstate.version ~= vim.b[bufnr].changedtick then return end diff --git a/runtime/lua/vim/lsp/semantic_tokens.lua b/runtime/lua/vim/lsp/semantic_tokens.lua index ef2502b12e..278014a4ea 100644 --- a/runtime/lua/vim/lsp/semantic_tokens.lua +++ b/runtime/lua/vim/lsp/semantic_tokens.lua @@ -116,7 +116,7 @@ local function tokens_to_ranges(data, bufnr, client, request) if elapsed_ns > yield_interval_ns then vim.schedule(function() - coroutine.resume(co, util.buf_versions[bufnr]) + coroutine.resume(co, vim.b[bufnr].changedtick) end) if request.version ~= coroutine.yield() then -- request became stale since the last time the coroutine ran. @@ -275,7 +275,7 @@ end --- ---@package function STHighlighter:send_request() - local version = util.buf_versions[self.bufnr] + local version = vim.b[self.bufnr].changedtick self:reset_timer() @@ -418,7 +418,7 @@ end function STHighlighter:on_win(topline, botline) for client_id, state in pairs(self.client_state) do local current_result = state.current_result - if current_result.version and current_result.version == util.buf_versions[self.bufnr] then + if current_result.version and current_result.version == vim.b[self.bufnr].changedtick then if not current_result.namespace_cleared then api.nvim_buf_clear_namespace(self.bufnr, state.namespace, 0, -1) current_result.namespace_cleared = true diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 0099e82f52..d1f0e97065 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -509,8 +509,7 @@ function M.apply_text_document_edit(text_document_edit, index, offset_encoding) and ( text_document.version and text_document.version > 0 - and M.buf_versions[bufnr] - and M.buf_versions[bufnr] > text_document.version + and vim.b[bufnr].changedtick > text_document.version ) then print('Buffer ', text_document.uri, ' newer than edits.') @@ -2200,9 +2199,16 @@ function M._refresh(method, opts) end end -M._get_line_byte_from_position = get_line_byte_from_position - ---@nodoc -M.buf_versions = {} ---@type table<integer,integer> +---@deprecated +---@type table<integer,integer> +M.buf_versions = setmetatable({}, { + __index = function(_, bufnr) + vim.deprecate('vim.lsp.util.buf_versions', 'vim.b.changedtick', '0.13') + return vim.b[bufnr].changedtick + end, +}) + +M._get_line_byte_from_position = get_line_byte_from_position return M |