aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/_editor.lua6
-rw-r--r--runtime/lua/vim/_meta.lua4
-rw-r--r--runtime/lua/vim/filetype.lua1
-rw-r--r--runtime/lua/vim/loader.lua22
-rw-r--r--runtime/lua/vim/lsp.lua91
-rw-r--r--runtime/lua/vim/lsp/_inlay_hint.lua61
-rw-r--r--runtime/lua/vim/lsp/buf.lua2
-rw-r--r--runtime/lua/vim/lsp/protocol.lua2
-rw-r--r--runtime/lua/vim/version.lua2
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