diff options
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/_editor.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/_meta.lua | 4 | ||||
-rw-r--r-- | runtime/lua/vim/filetype.lua | 1 | ||||
-rw-r--r-- | runtime/lua/vim/loader.lua | 22 | ||||
-rw-r--r-- | runtime/lua/vim/lsp.lua | 91 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/_inlay_hint.lua | 61 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/version.lua | 2 |
9 files changed, 91 insertions, 100 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 1de2ade1a1..e2ed0d980e 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -3,7 +3,7 @@ -- Lua code lives in one of three places: -- 1. runtime/lua/vim/ (the runtime): For "nice to have" features, e.g. the -- `inspect` and `lpeg` modules. --- 2. runtime/lua/vim/shared.lua: pure lua functions which always +-- 2. runtime/lua/vim/shared.lua: pure Lua functions which always -- are available. Used in the test runner, as well as worker threads -- and processes launched from Nvim. -- 3. runtime/lua/vim/_editor.lua: Code which directly interacts with @@ -839,10 +839,10 @@ do -- some bugs, so fake the two-step dance for now. local matches - --- Omnifunc for completing lua values from the runtime lua interpreter, + --- Omnifunc for completing Lua values from the runtime Lua interpreter, --- similar to the builtin completion for the `:lua` command. --- - --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a lua buffer. + --- Activate using `set omnifunc=v:lua.vim.lua_omnifunc` in a Lua buffer. function vim.lua_omnifunc(find_start, _) if find_start == 1 then local line = vim.api.nvim_get_current_line() diff --git a/runtime/lua/vim/_meta.lua b/runtime/lua/vim/_meta.lua index e3ad4d76c9..913f1fe203 100644 --- a/runtime/lua/vim/_meta.lua +++ b/runtime/lua/vim/_meta.lua @@ -239,7 +239,7 @@ local to_vim_value = { end, } ---- Convert a lua value to a vimoption_T value +--- Convert a Lua value to a vimoption_T value local function convert_value_to_vim(name, info, value) if value == nil then return vim.NIL @@ -250,7 +250,7 @@ local function convert_value_to_vim(name, info, value) return to_vim_value[info.metatype](info, value) end --- Map of OptionType to functions that take vimoption_T values and convert to lua values. +-- Map of OptionType to functions that take vimoption_T values and convert to Lua values. -- Each function takes (info, vim_value) -> lua_value local to_lua_value = { boolean = passthrough, diff --git a/runtime/lua/vim/filetype.lua b/runtime/lua/vim/filetype.lua index 91d5dc1c62..33e80690ff 100644 --- a/runtime/lua/vim/filetype.lua +++ b/runtime/lua/vim/filetype.lua @@ -1174,6 +1174,7 @@ local extension = { zir = 'zir', zu = 'zimbu', zut = 'zimbutempl', + zs = 'zserio', zsh = 'zsh', vala = 'vala', web = function(path, bufnr) diff --git a/runtime/lua/vim/loader.lua b/runtime/lua/vim/loader.lua index 9024bdb231..f340dc85b5 100644 --- a/runtime/lua/vim/loader.lua +++ b/runtime/lua/vim/loader.lua @@ -161,7 +161,7 @@ function Loader.read(name) end end ---- The `package.loaders` loader for lua files using the cache. +--- The `package.loaders` loader for Lua files using the cache. ---@param modname string module name ---@return string|function ---@private @@ -211,7 +211,7 @@ end ---@private -- luacheck: ignore 312 function Loader.loadfile(filename, mode, env) - -- ignore mode, since we byte-compile the lua source files + -- ignore mode, since we byte-compile the Lua source files mode = nil return Loader.load(normalize(filename), { mode = mode, env = env }) end @@ -268,7 +268,7 @@ function Loader.load(modpath, opts) return chunk, err end ---- Finds lua modules for the given module name. +--- Finds Lua modules for the given module name. ---@param modname string Module name, or `"*"` to find the top-level modules instead ---@param opts? ModuleFindOpts (table|nil) Options for finding a module: --- - rtp: (boolean) Search for modname in the runtime path (defaults to `true`) @@ -289,7 +289,7 @@ function M.find(modname, opts) local idx = modname:find('.', 1, true) -- HACK: fix incorrect require statements. Really not a fan of keeping this, - -- but apparently the regular lua loader also allows this + -- but apparently the regular Lua loader also allows this if idx == 1 then modname = modname:gsub('^%.+', '') basename = modname:gsub('%.', '/') @@ -386,9 +386,9 @@ end --- Enables the experimental Lua module loader: --- * overrides loadfile ---- * adds the lua loader using the byte-compilation cache +--- * adds the Lua loader using the byte-compilation cache --- * adds the libs loader ---- * removes the default Neovim loader +--- * removes the default Nvim loader function M.enable() if M.enabled then return @@ -396,11 +396,11 @@ function M.enable() M.enabled = true vim.fn.mkdir(vim.fn.fnamemodify(M.path, ':p'), 'p') _G.loadfile = Loader.loadfile - -- add lua loader + -- add Lua loader table.insert(loaders, 2, Loader.loader) -- add libs loader table.insert(loaders, 3, Loader.loader_lib) - -- remove Neovim loader + -- remove Nvim loader for l, loader in ipairs(loaders) do if loader == vim._load_package then table.remove(loaders, l) @@ -411,7 +411,7 @@ end --- Disables the experimental Lua module loader: --- * removes the loaders ---- * adds the default Neovim loader +--- * adds the default Nvim loader function M.disable() if not M.enabled then return @@ -426,8 +426,8 @@ function M.disable() table.insert(loaders, 2, vim._load_package) end ---- Return the top-level `/lua/*` modules for this path ----@param path string path to check for top-level lua modules +--- Return the top-level \`/lua/*` modules for this path +---@param path string path to check for top-level Lua modules ---@private function Loader.lsmod(path) if not Loader._indexed[path] then diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index cb1c101c58..2c115007de 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -902,18 +902,13 @@ end ---@return string function lsp.status() local percentage = nil - local groups = {} + local messages = {} for _, client in ipairs(vim.lsp.get_active_clients()) do for progress in client.progress do local value = progress.value if type(value) == 'table' and value.kind then - local group = groups[progress.token] - if not group then - group = {} - groups[progress.token] = group - end - group.title = value.title or group.title - group.message = value.message or group.message + local message = value.message and (value.title .. ': ' .. value.message) or value.title + messages[#messages + 1] = message if value.percentage then percentage = math.max(percentage or 0, value.percentage) end @@ -922,17 +917,6 @@ function lsp.status() -- Just ignore it as there is no sensible way to display it end end - local messages = {} - for _, group in pairs(groups) do - if group.title then - table.insert( - messages, - group.message and (group.title .. ': ' .. group.message) or group.title - ) - elseif group.message then - table.insert(messages, group.message) - end - end local message = table.concat(messages, ', ') if percentage then return string.format('%3d%%: %s', percentage, message) @@ -1092,7 +1076,7 @@ end --- `initialize_result.offsetEncoding` if `capabilities.offsetEncoding` was --- sent to it. You can only modify the `client.offset_encoding` here before --- any notifications are sent. Most language servers expect to be sent client specified settings after ---- initialization. Neovim does not make this assumption. A +--- initialization. Nvim does not make this assumption. A --- `workspace/didChangeConfiguration` notification should be sent --- to the server during on_init. --- @@ -1199,7 +1183,7 @@ function lsp.start_client(config) --- ---@param code (integer) Error code ---@param err (...) Other arguments may be passed depending on the error kind - ---@see `vim.lsp.rpc.client_errors` for possible errors. Use + ---@see vim.lsp.rpc.client_errors for possible errors. Use ---`vim.lsp.rpc.client_errors[code]` to get a human-friendly name. function dispatch.on_error(code, err) if log.error() then @@ -1345,7 +1329,6 @@ function lsp.start_client(config) messages = 'messages', verbose = 'verbose', } - local version = vim.version() local workspace_folders --- @type table[]? local root_uri --- @type string? @@ -1379,7 +1362,7 @@ function lsp.start_client(config) -- since 3.15.0 clientInfo = { name = 'Neovim', - version = string.format('%s.%s.%s', version.major, version.minor, version.patch), + version = tostring(vim.version()), }, -- The rootPath of the workspace. Is null if no folder is open. -- @@ -1757,7 +1740,7 @@ local function text_document_did_save_handler(bufnr) bufnr = resolve_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr) local text = once(buf_get_full_text) - for_each_buffer_client(bufnr, function(client) + for _, client in ipairs(lsp.get_active_clients({ bufnr = bufnr })) do local name = api.nvim_buf_get_name(bufnr) local old_name = changetracking._get_and_set_name(client, bufnr, name) if old_name and name ~= old_name then @@ -1789,7 +1772,7 @@ local function text_document_did_save_handler(bufnr) text = included_text, }) end - end) + end end --- Implements the `textDocument/did…` notifications required to track a buffer @@ -1825,7 +1808,7 @@ function lsp.buf_attach_client(bufnr, client_id) buffer = bufnr, desc = 'vim.lsp: textDocument/willSave', callback = function(ctx) - for_each_buffer_client(ctx.buf, function(client) + for _, client in ipairs(lsp.get_active_clients({ bufnr = ctx.buf })) do local params = { textDocument = { uri = uri, @@ -1844,7 +1827,7 @@ function lsp.buf_attach_client(bufnr, client_id) log.error(vim.inspect(err)) end end - end) + end end, }) api.nvim_create_autocmd('BufWritePost', { @@ -1860,23 +1843,23 @@ function lsp.buf_attach_client(bufnr, client_id) on_lines = text_document_did_change_handler, on_reload = function() local params = { textDocument = { uri = uri } } - for_each_buffer_client(bufnr, function(client, _) + for _, client in ipairs(lsp.get_active_clients({ bufnr = bufnr })) do changetracking.reset_buf(client, bufnr) if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then client.notify('textDocument/didClose', params) end text_document_did_open_handler(bufnr, client) - end) + end end, on_detach = function() local params = { textDocument = { uri = uri } } - for_each_buffer_client(bufnr, function(client, _) + for _, client in ipairs(lsp.get_active_clients({ bufnr = bufnr })) do changetracking.reset_buf(client, bufnr) if vim.tbl_get(client.server_capabilities, 'textDocumentSync', 'openClose') then client.notify('textDocument/didClose', params) end client.attached_buffers[bufnr] = nil - end) + end util.buf_versions[bufnr] = nil all_buffer_active_clients[bufnr] = nil end, @@ -1949,7 +1932,7 @@ function lsp.buf_detach_client(bufnr, client_id) all_buffer_active_clients[bufnr] = nil end - local namespace = vim.lsp.diagnostic.get_namespace(client_id) + local namespace = lsp.diagnostic.get_namespace(client_id) vim.diagnostic.reset(namespace, bufnr) vim.notify(string.format('Detached buffer (id: %d) from client (id: %d)', bufnr, client_id)) @@ -2121,34 +2104,30 @@ function lsp.buf_request(bufnr, method, params, handler) handler = { handler, 'f', true }, }) - local supported_clients = {} + bufnr = resolve_bufnr(bufnr) local method_supported = false - for_each_buffer_client(bufnr, function(client, client_id) + local clients = lsp.get_active_clients({ bufnr = bufnr }) + local client_request_ids = {} + for _, client in ipairs(clients) do if client.supports_method(method, { bufnr = bufnr }) then method_supported = true - table.insert(supported_clients, client_id) + + local request_success, request_id = client.request(method, params, handler, bufnr) + -- This could only fail if the client shut down in the time since we looked + -- it up and we did the request, which should be rare. + if request_success then + client_request_ids[client.id] = request_id + end end - end) + end -- if has client but no clients support the given method, notify the user - if - not tbl_isempty(all_buffer_active_clients[resolve_bufnr(bufnr)] or {}) and not method_supported - then + if next(clients) and not method_supported then vim.notify(lsp._unsupported_method(method), vim.log.levels.ERROR) nvim_command('redraw') return {}, function() end end - local client_request_ids = {} - for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr) - local request_success, request_id = client.request(method, params, handler, resolved_bufnr) - -- This could only fail if the client shut down in the time since we looked - -- it up and we did the request, which should be rare. - if request_success then - client_request_ids[client_id] = request_id - end - end, supported_clients) - local function _cancel_all_requests() for client_id, request_id in pairs(client_request_ids) do local client = active_clients[client_id] @@ -2176,11 +2155,11 @@ function lsp.buf_request_all(bufnr, method, params, handler) local expected_result_count = 0 local set_expected_result_count = once(function() - for_each_buffer_client(bufnr, function(client) + for _, client in ipairs(lsp.get_active_clients({ bufnr = bufnr })) do if client.supports_method(method, { bufnr = bufnr }) then expected_result_count = expected_result_count + 1 end - end) + end end) local function _sync_handler(err, result, ctx) @@ -2243,11 +2222,11 @@ function lsp.buf_notify(bufnr, method, params) method = { method, 's' }, }) local resp = false - for_each_buffer_client(bufnr, function(client, _client_id, _resolved_bufnr) + for _, client in ipairs(lsp.get_active_clients({ bufnr = bufnr })) do if client.rpc.notify(method, params) then resp = true end - end) + end return resp end @@ -2387,8 +2366,8 @@ function lsp.formatexpr(opts) } local response = client.request_sync('textDocument/rangeFormatting', params, timeout_ms, bufnr) - if response.result then - vim.lsp.util.apply_text_edits(response.result, 0, client.offset_encoding) + if response and response.result then + lsp.util.apply_text_edits(response.result, 0, client.offset_encoding) return 0 end end @@ -2469,6 +2448,7 @@ function lsp.get_log_path() return log.get_filename() end +---@private --- Invokes a function for each LSP client attached to a buffer. --- ---@param bufnr integer Buffer number @@ -2480,6 +2460,7 @@ end --- print(vim.inspect(client)) --- end) --- </pre> +---@deprecated use lsp.get_active_clients({ bufnr = bufnr }) with regular loop function lsp.for_each_buffer_client(bufnr, fn) return for_each_buffer_client(bufnr, fn) end diff --git a/runtime/lua/vim/lsp/_inlay_hint.lua b/runtime/lua/vim/lsp/_inlay_hint.lua index e7cc8ba7ae..84794841ae 100644 --- a/runtime/lua/vim/lsp/_inlay_hint.lua +++ b/runtime/lua/vim/lsp/_inlay_hint.lua @@ -8,6 +8,7 @@ local M = {} ---@field client_hint table<integer, table<integer, lsp.InlayHint[]>> client_id -> (lnum -> hints) ---@field enabled boolean Whether inlay hints are enabled for the buffer ---@field timer uv.uv_timer_t? Debounce timer associated with the buffer +---@field applied table<integer, integer> Last version of hints applied to this line ---@type table<integer, lsp._inlay_hint.bufstate> local bufstates = {} @@ -143,6 +144,9 @@ end ---@private local function clear(bufnr) bufnr = resolve_bufnr(bufnr) + if not bufstates[bufnr] then + return + end reset_timer(bufnr) local bufstate = bufstates[bufnr] local client_lens = (bufstate or {}).client_hint or {} @@ -169,7 +173,7 @@ function M.enable(bufnr) bufnr = resolve_bufnr(bufnr) local bufstate = bufstates[bufnr] if not (bufstate and bufstate.enabled) then - bufstates[bufnr] = { enabled = true, timer = nil } + bufstates[bufnr] = { enabled = true, timer = nil, applied = {} } M.refresh({ bufnr = bufnr }) api.nvim_buf_attach(bufnr, true, { on_lines = function(_, cb_bufnr) @@ -183,7 +187,9 @@ function M.enable(bufnr) end, on_reload = function(_, cb_bufnr) clear(cb_bufnr) - bufstates[cb_bufnr] = nil + if bufstates[cb_bufnr] and bufstates[cb_bufnr].enabled then + bufstates[cb_bufnr] = { enabled = true } + end M.refresh({ bufnr = cb_bufnr }) end, on_detach = function(_, cb_bufnr) @@ -238,35 +244,38 @@ api.nvim_set_decoration_provider(namespace, { return end local hints_by_client = bufstate.client_hint - api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) for lnum = topline, botline do - for _, hints_by_lnum in pairs(hints_by_client) do - local line_hints = hints_by_lnum[lnum] or {} - for _, hint in pairs(line_hints) do - local text = '' - if type(hint.label) == 'string' then - text = hint.label - else - for _, part in ipairs(hint.label) do - text = text .. part.value + if bufstate.applied[lnum] ~= bufstate.version then + api.nvim_buf_clear_namespace(bufnr, namespace, lnum, lnum + 1) + for _, hints_by_lnum in pairs(hints_by_client) do + local line_hints = hints_by_lnum[lnum] or {} + for _, hint in pairs(line_hints) do + local text = '' + if type(hint.label) == 'string' then + text = hint.label + else + for _, part in ipairs(hint.label) do + text = text .. part.value + end end + local vt = {} + if hint.paddingLeft then + vt[#vt + 1] = { ' ' } + end + vt[#vt + 1] = { text, 'LspInlayHint' } + if hint.paddingRight then + vt[#vt + 1] = { ' ' } + end + api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, { + virt_text_pos = 'inline', + ephemeral = false, + virt_text = vt, + hl_mode = 'combine', + }) end - if hint.paddingLeft then - text = ' ' .. text - end - if hint.paddingRight then - text = text .. ' ' - end - api.nvim_buf_set_extmark(bufnr, namespace, lnum, hint.position.character, { - virt_text_pos = 'inline', - ephemeral = false, - virt_text = { - { text, 'LspInlayHint' }, - }, - hl_mode = 'combine', - }) end + bufstate.applied[lnum] = bufstate.version end end end, diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 45056cf272..17b444a6e8 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -159,7 +159,7 @@ end --- @param options table|nil Optional table which holds the following optional fields: --- - formatting_options (table|nil): --- Can be used to specify FormattingOptions. Some unspecified options will be ---- automatically derived from the current Neovim options. +--- automatically derived from the current Nvim options. --- See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#formattingOptions --- - timeout_ms (integer|nil, default 1000): --- Time in milliseconds to block for formatting requests. No effect if async=true diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index b3a7903420..ea38bfe237 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -642,7 +642,7 @@ function protocol.make_client_capabilities() }, textDocument = { inlayHint = { - dynamicRegistration = false, + dynamicRegistration = true, resolveSupport = { properties = {}, }, diff --git a/runtime/lua/vim/version.lua b/runtime/lua/vim/version.lua index 92250ff1f8..cd28a9b54b 100644 --- a/runtime/lua/vim/version.lua +++ b/runtime/lua/vim/version.lua @@ -125,7 +125,7 @@ function Version:__tostring() if self.prerelease then ret = ret .. '-' .. self.prerelease end - if self.build then + if self.build and self.build ~= vim.NIL then ret = ret .. '+' .. self.build end return ret |