Merge pull request #30929 from lewis6991/fix/lsp_param_encodings

This commit is contained in:
Lewis Russell 2024-10-24 11:19:38 +01:00 committed by GitHub
commit 5c44c02405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 79 additions and 72 deletions

View File

@ -854,7 +854,7 @@ api.nvim_create_autocmd('VimLeavePre', {
--- ---
---@param bufnr (integer) Buffer handle, or 0 for current. ---@param bufnr (integer) Buffer handle, or 0 for current.
---@param method (string) LSP method name ---@param method (string) LSP method name
---@param params table|nil Parameters to send to the server ---@param params? table|(fun(client: vim.lsp.Client, bufnr: integer): table?) Parameters to send to the server
---@param handler? lsp.Handler See |lsp-handler| ---@param handler? lsp.Handler See |lsp-handler|
--- If nil, follows resolution strategy defined in |lsp-handler-configuration| --- If nil, follows resolution strategy defined in |lsp-handler-configuration|
---@param on_unsupported? fun() ---@param on_unsupported? fun()
@ -879,7 +879,8 @@ function lsp.buf_request(bufnr, method, params, handler, on_unsupported)
if client.supports_method(method, { bufnr = bufnr }) then if client.supports_method(method, { bufnr = bufnr }) then
method_supported = true method_supported = true
local request_success, request_id = client.request(method, params, handler, bufnr) local cparams = type(params) == 'function' and params(client, bufnr) or params --[[@as table?]]
local request_success, request_id = client.request(method, cparams, handler, bufnr)
-- This could only fail if the client shut down in the time since we looked -- 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. -- it up and we did the request, which should be rare.
if request_success then if request_success then

View File

@ -1,4 +1,5 @@
local api = vim.api local api = vim.api
local lsp = vim.lsp
local validate = vim.validate local validate = vim.validate
local util = require('vim.lsp.util') local util = require('vim.lsp.util')
local npcall = vim.F.npcall local npcall = vim.F.npcall
@ -6,24 +7,17 @@ local ms = require('vim.lsp.protocol').Methods
local M = {} local M = {}
--- Sends an async request to all active clients attached to the current --- @param params? table
--- buffer. --- @return fun(client: vim.lsp.Client): lsp.TextDocumentPositionParams
--- local function client_positional_params(params)
---@param method (string) LSP method name local win = api.nvim_get_current_win()
---@param params (table|nil) Parameters to send to the server return function(client)
---@param handler lsp.Handler? See |lsp-handler|. Follows |lsp-handler-resolution| local ret = util.make_position_params(win, client.offset_encoding)
--- if params then
---@return table<integer, integer> client_request_ids Map of client-id:request-id pairs ret = vim.tbl_extend('force', ret, params)
---for all successful requests. end
---@return function _cancel_all_requests Function which can be used to return ret
---cancel all the requests. You could instead end
---iterate all clients and call their `cancel_request()` methods.
---
---@see |vim.lsp.buf_request()|
local function request(method, params, handler)
validate('method', method, 'string')
validate('handler', handler, 'function', true)
return vim.lsp.buf_request(0, method, params, handler)
end end
--- Displays hover information about the symbol under the cursor in a floating --- Displays hover information about the symbol under the cursor in a floating
@ -34,20 +28,19 @@ end
--- except that "q" dismisses the window. --- except that "q" dismisses the window.
--- You can scroll the contents the same as you would any other buffer. --- You can scroll the contents the same as you would any other buffer.
function M.hover() function M.hover()
local params = util.make_position_params() lsp.buf_request(0, ms.textDocument_hover, client_positional_params())
request(ms.textDocument_hover, params)
end end
local function request_with_opts(name, params, opts) local function request_with_opts(name, params, opts)
local req_handler --- @type function? local req_handler --- @type function?
if opts then if opts then
req_handler = function(err, result, ctx, config) req_handler = function(err, result, ctx, config)
local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) local client = assert(lsp.get_client_by_id(ctx.client_id))
local handler = client.handlers[name] or vim.lsp.handlers[name] local handler = client.handlers[name] or lsp.handlers[name]
handler(err, result, ctx, vim.tbl_extend('force', config or {}, opts)) handler(err, result, ctx, vim.tbl_extend('force', config or {}, opts))
end end
end end
request(name, params, req_handler) lsp.buf_request(0, name, params, req_handler)
end end
---@param method string ---@param method string
@ -55,9 +48,9 @@ end
local function get_locations(method, opts) local function get_locations(method, opts)
opts = opts or {} opts = opts or {}
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ method = method, bufnr = bufnr }) local clients = lsp.get_clients({ method = method, bufnr = bufnr })
if not next(clients) then if not next(clients) then
vim.notify(vim.lsp._unsupported_method(method), vim.log.levels.WARN) vim.notify(lsp._unsupported_method(method), vim.log.levels.WARN)
return return
end end
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
@ -185,8 +178,7 @@ end
--- Displays signature information about the symbol under the cursor in a --- Displays signature information about the symbol under the cursor in a
--- floating window. --- floating window.
function M.signature_help() function M.signature_help()
local params = util.make_position_params() lsp.buf_request(0, ms.textDocument_signatureHelp, client_positional_params())
request(ms.textDocument_signatureHelp, params)
end end
--- Retrieves the completion items at the current cursor position. Can only be --- Retrieves the completion items at the current cursor position. Can only be
@ -198,9 +190,13 @@ end
--- ---
---@see vim.lsp.protocol.CompletionTriggerKind ---@see vim.lsp.protocol.CompletionTriggerKind
function M.completion(context) function M.completion(context)
local params = util.make_position_params() return lsp.buf_request(
params.context = context 0,
return request(ms.textDocument_completion, params) ms.textDocument_completion,
client_positional_params({
context = context,
})
)
end end
---@param bufnr integer ---@param bufnr integer
@ -307,7 +303,7 @@ function M.format(opts)
method = ms.textDocument_formatting method = ms.textDocument_formatting
end end
local clients = vim.lsp.get_clients({ local clients = lsp.get_clients({
id = opts.id, id = opts.id,
bufnr = bufnr, bufnr = bufnr,
name = opts.name, name = opts.name,
@ -344,7 +340,7 @@ function M.format(opts)
end end
local params = set_range(client, util.make_formatting_params(opts.formatting_options)) local params = set_range(client, util.make_formatting_params(opts.formatting_options))
client.request(method, params, function(...) client.request(method, params, function(...)
local handler = client.handlers[method] or vim.lsp.handlers[method] local handler = client.handlers[method] or lsp.handlers[method]
handler(...) handler(...)
do_format(next(clients, idx)) do_format(next(clients, idx))
end, bufnr) end, bufnr)
@ -386,7 +382,7 @@ end
function M.rename(new_name, opts) function M.rename(new_name, opts)
opts = opts or {} opts = opts or {}
local bufnr = opts.bufnr or api.nvim_get_current_buf() local bufnr = opts.bufnr or api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ local clients = lsp.get_clients({
bufnr = bufnr, bufnr = bufnr,
name = opts.name, name = opts.name,
-- Clients must at least support rename, prepareRename is optional -- Clients must at least support rename, prepareRename is optional
@ -428,7 +424,7 @@ function M.rename(new_name, opts)
local params = util.make_position_params(win, client.offset_encoding) local params = util.make_position_params(win, client.offset_encoding)
params.newName = name params.newName = name
local handler = client.handlers[ms.textDocument_rename] local handler = client.handlers[ms.textDocument_rename]
or vim.lsp.handlers[ms.textDocument_rename] or lsp.handlers[ms.textDocument_rename]
client.request(ms.textDocument_rename, params, function(...) client.request(ms.textDocument_rename, params, function(...)
handler(...) handler(...)
try_use_client(next(clients, idx)) try_use_client(next(clients, idx))
@ -508,7 +504,7 @@ end
function M.references(context, opts) function M.references(context, opts)
validate('context', context, 'table', true) validate('context', context, 'table', true)
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ method = ms.textDocument_references, bufnr = bufnr }) local clients = lsp.get_clients({ method = ms.textDocument_references, bufnr = bufnr })
if not next(clients) then if not next(clients) then
return return
end end
@ -575,7 +571,7 @@ end
--- @param handler? lsp.Handler --- @param handler? lsp.Handler
--- @param bufnr? integer --- @param bufnr? integer
local function request_with_id(client_id, method, params, handler, bufnr) local function request_with_id(client_id, method, params, handler, bufnr)
local client = vim.lsp.get_client_by_id(client_id) local client = lsp.get_client_by_id(client_id)
if not client then if not client then
vim.notify( vim.notify(
string.format('Client with id=%d disappeared during call hierarchy request', client_id), string.format('Client with id=%d disappeared during call hierarchy request', client_id),
@ -606,9 +602,12 @@ end
--- @param method string --- @param method string
local function call_hierarchy(method) local function call_hierarchy(method)
local params = util.make_position_params() lsp.buf_request(
0,
ms.textDocument_prepareCallHierarchy,
client_positional_params(),
--- @param result lsp.CallHierarchyItem[]? --- @param result lsp.CallHierarchyItem[]?
request(ms.textDocument_prepareCallHierarchy, params, function(err, result, ctx) function(err, result, ctx)
if err then if err then
vim.notify(err.message, vim.log.levels.WARN) vim.notify(err.message, vim.log.levels.WARN)
return return
@ -622,7 +621,8 @@ local function call_hierarchy(method)
return return
end end
request_with_id(ctx.client_id, method, { item = item }, nil, ctx.bufnr) request_with_id(ctx.client_id, method, { item = item }, nil, ctx.bufnr)
end) end
)
end end
--- Lists all the call sites of the symbol under the cursor in the --- Lists all the call sites of the symbol under the cursor in the
@ -654,9 +654,9 @@ end
function M.typehierarchy(kind) function M.typehierarchy(kind)
local method = kind == 'subtypes' and ms.typeHierarchy_subtypes or ms.typeHierarchy_supertypes local method = kind == 'subtypes' and ms.typeHierarchy_subtypes or ms.typeHierarchy_supertypes
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local clients = vim.lsp.get_clients({ bufnr = bufnr, method = method }) local clients = lsp.get_clients({ bufnr = bufnr, method = method })
if not next(clients) then if not next(clients) then
vim.notify(vim.lsp._unsupported_method(method), vim.log.levels.WARN) vim.notify(lsp._unsupported_method(method), vim.log.levels.WARN)
return return
end end
@ -713,7 +713,7 @@ end
--- ---
function M.list_workspace_folders() function M.list_workspace_folders()
local workspace_folders = {} local workspace_folders = {}
for _, client in pairs(vim.lsp.get_clients({ bufnr = 0 })) do for _, client in pairs(lsp.get_clients({ bufnr = 0 })) do
for _, folder in pairs(client.workspace_folders or {}) do for _, folder in pairs(client.workspace_folders or {}) do
table.insert(workspace_folders, folder.name) table.insert(workspace_folders, folder.name)
end end
@ -736,7 +736,7 @@ function M.add_workspace_folder(workspace_folder)
return return
end end
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
for _, client in pairs(vim.lsp.get_clients({ bufnr = bufnr })) do for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do
client:_add_workspace_folder(workspace_folder) client:_add_workspace_folder(workspace_folder)
end end
end end
@ -753,7 +753,7 @@ function M.remove_workspace_folder(workspace_folder)
return return
end end
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
for _, client in pairs(vim.lsp.get_clients({ bufnr = bufnr })) do for _, client in pairs(lsp.get_clients({ bufnr = bufnr })) do
client:_remove_workspace_folder(workspace_folder) client:_remove_workspace_folder(workspace_folder)
end end
print(workspace_folder, 'is not currently part of the workspace') print(workspace_folder, 'is not currently part of the workspace')
@ -792,8 +792,7 @@ end
--- |hl-LspReferenceRead| --- |hl-LspReferenceRead|
--- |hl-LspReferenceWrite| --- |hl-LspReferenceWrite|
function M.document_highlight() function M.document_highlight()
local params = util.make_position_params() lsp.buf_request(0, ms.textDocument_documentHighlight, client_positional_params())
request(ms.textDocument_documentHighlight, params)
end end
--- Removes document highlights from current buffer. --- Removes document highlights from current buffer.
@ -916,7 +915,7 @@ local function on_code_action_results(results, opts)
-- command: string -- command: string
-- arguments?: any[] -- arguments?: any[]
-- --
local client = assert(vim.lsp.get_client_by_id(choice.ctx.client_id)) local client = assert(lsp.get_client_by_id(choice.ctx.client_id))
local action = choice.action local action = choice.action
local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number') local bufnr = assert(choice.ctx.bufnr, 'Must have buffer number')
@ -951,14 +950,14 @@ local function on_code_action_results(results, opts)
---@param item {action: lsp.Command|lsp.CodeAction, ctx: lsp.HandlerContext} ---@param item {action: lsp.Command|lsp.CodeAction, ctx: lsp.HandlerContext}
local function format_item(item) local function format_item(item)
local clients = vim.lsp.get_clients({ bufnr = item.ctx.bufnr }) local clients = lsp.get_clients({ bufnr = item.ctx.bufnr })
local title = item.action.title:gsub('\r\n', '\\r\\n'):gsub('\n', '\\n') local title = item.action.title:gsub('\r\n', '\\r\\n'):gsub('\n', '\\n')
if #clients == 1 then if #clients == 1 then
return title return title
end end
local source = vim.lsp.get_client_by_id(item.ctx.client_id).name local source = lsp.get_client_by_id(item.ctx.client_id).name
return ('%s [%s]'):format(title, source) return ('%s [%s]'):format(title, source)
end end
@ -987,16 +986,16 @@ function M.code_action(opts)
end end
local context = opts.context and vim.deepcopy(opts.context) or {} local context = opts.context and vim.deepcopy(opts.context) or {}
if not context.triggerKind then if not context.triggerKind then
context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked context.triggerKind = lsp.protocol.CodeActionTriggerKind.Invoked
end end
local mode = api.nvim_get_mode().mode local mode = api.nvim_get_mode().mode
local bufnr = api.nvim_get_current_buf() local bufnr = api.nvim_get_current_buf()
local win = api.nvim_get_current_win() local win = api.nvim_get_current_win()
local clients = vim.lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_codeAction }) local clients = lsp.get_clients({ bufnr = bufnr, method = ms.textDocument_codeAction })
local remaining = #clients local remaining = #clients
if remaining == 0 then if remaining == 0 then
if next(vim.lsp.get_clients({ bufnr = bufnr })) then if next(lsp.get_clients({ bufnr = bufnr })) then
vim.notify(vim.lsp._unsupported_method(ms.textDocument_codeAction), vim.log.levels.WARN) vim.notify(lsp._unsupported_method(ms.textDocument_codeAction), vim.log.levels.WARN)
end end
return return
end end
@ -1033,8 +1032,8 @@ function M.code_action(opts)
if context.diagnostics then if context.diagnostics then
params.context = context params.context = context
else else
local ns_push = vim.lsp.diagnostic.get_namespace(client.id, false) local ns_push = lsp.diagnostic.get_namespace(client.id, false)
local ns_pull = vim.lsp.diagnostic.get_namespace(client.id, true) local ns_pull = lsp.diagnostic.get_namespace(client.id, true)
local diagnostics = {} local diagnostics = {}
local lnum = api.nvim_win_get_cursor(0)[1] - 1 local lnum = api.nvim_win_get_cursor(0)[1] - 1
vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_pull, lnum = lnum })) vim.list_extend(diagnostics, vim.diagnostic.get(bufnr, { namespace = ns_pull, lnum = lnum }))
@ -1062,7 +1061,7 @@ function M.execute_command(command_params)
arguments = command_params.arguments, arguments = command_params.arguments,
workDoneToken = command_params.workDoneToken, workDoneToken = command_params.workDoneToken,
} }
request(ms.workspace_executeCommand, command_params) lsp.buf_request(0, ms.workspace_executeCommand, command_params)
end end
return M return M

View File

@ -12,6 +12,8 @@ end
local sysname = vim.uv.os_uname().sysname local sysname = vim.uv.os_uname().sysname
--- @class vim.lsp.protocol.constants
--- @nodoc
local constants = { local constants = {
--- @enum lsp.DiagnosticSeverity --- @enum lsp.DiagnosticSeverity
DiagnosticSeverity = { DiagnosticSeverity = {
@ -314,7 +316,9 @@ local constants = {
}, },
} }
-- Protocol for the Microsoft Language Server Protocol (mslsp) --- Protocol for the Microsoft Language Server Protocol (mslsp)
--- @class vim.lsp.protocol : vim.lsp.protocol.constants
--- @nodoc
local protocol = {} local protocol = {}
--- @diagnostic disable:no-unknown --- @diagnostic disable:no-unknown

View File

@ -289,6 +289,9 @@ local config = {
}, },
fn_xform = function(fun) fn_xform = function(fun)
fun.name = fun.name:gsub('result%.', '') fun.name = fun.name:gsub('result%.', '')
if fun.module == 'vim.lsp.protocol' then
fun.classvar = nil
end
end, end,
section_fmt = function(name) section_fmt = function(name)
if name:lower() == 'lsp' then if name:lower() == 'lsp' then