From 4e5086a67e8916d9a5c5c5cb1933633b3e200eee Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:20:31 +0200 Subject: refactor(lsp): s/options/opts for parameters in vim.lsp.buf See https://github.com/neovim/neovim/pull/28483#discussion_r1583344120 --- runtime/lua/vim/lsp/buf.lua | 116 ++++++++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 58 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 79c1aeb53d..820ff9c2ca 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -35,13 +35,13 @@ function M.hover() request(ms.textDocument_hover, params) end -local function request_with_options(name, params, options) +local function request_with_opts(name, params, opts) local req_handler --- @type function? - if options then + if opts then req_handler = function(err, result, ctx, config) local client = assert(vim.lsp.get_client_by_id(ctx.client_id)) local handler = client.handlers[name] or vim.lsp.handlers[name] - handler(err, result, ctx, vim.tbl_extend('force', config or {}, options)) + handler(err, result, ctx, vim.tbl_extend('force', config or {}, opts)) end end request(name, params, req_handler) @@ -83,32 +83,32 @@ end --- Jumps to the declaration of the symbol under the cursor. --- @note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead. ---- @param options? vim.lsp.LocationOpts -function M.declaration(options) +--- @param opts? vim.lsp.LocationOpts +function M.declaration(opts) local params = util.make_position_params() - request_with_options(ms.textDocument_declaration, params, options) + request_with_opts(ms.textDocument_declaration, params, opts) end --- Jumps to the definition of the symbol under the cursor. ---- @param options? vim.lsp.LocationOpts -function M.definition(options) +--- @param opts? vim.lsp.LocationOpts +function M.definition(opts) local params = util.make_position_params() - request_with_options(ms.textDocument_definition, params, options) + request_with_opts(ms.textDocument_definition, params, opts) end --- Jumps to the definition of the type of the symbol under the cursor. ---- @param options? vim.lsp.LocationOpts -function M.type_definition(options) +--- @param opts? vim.lsp.LocationOpts +function M.type_definition(opts) local params = util.make_position_params() - request_with_options(ms.textDocument_typeDefinition, params, options) + request_with_opts(ms.textDocument_typeDefinition, params, opts) end --- Lists all the implementations for the symbol under the cursor in the --- quickfix window. ---- @param options? vim.lsp.LocationOpts -function M.implementation(options) +--- @param opts? vim.lsp.LocationOpts +function M.implementation(opts) local params = util.make_position_params() - request_with_options(ms.textDocument_implementation, params, options) + request_with_opts(ms.textDocument_implementation, params, opts) end --- Displays signature information about the symbol under the cursor in a @@ -213,25 +213,25 @@ end --- Formats a buffer using the attached (and optionally filtered) language --- server clients. --- ---- @param options? vim.lsp.buf.format.Opts -function M.format(options) - options = options or {} - local bufnr = options.bufnr or api.nvim_get_current_buf() +--- @param opts? vim.lsp.buf.format.Opts +function M.format(opts) + opts = opts or {} + local bufnr = opts.bufnr or api.nvim_get_current_buf() local mode = api.nvim_get_mode().mode - local range = options.range + local range = opts.range if not range and mode == 'v' or mode == 'V' then range = range_from_selection(bufnr, mode) end local method = range and ms.textDocument_rangeFormatting or ms.textDocument_formatting local clients = vim.lsp.get_clients({ - id = options.id, + id = opts.id, bufnr = bufnr, - name = options.name, + name = opts.name, method = method, }) - if options.filter then - clients = vim.tbl_filter(options.filter, clients) + if opts.filter then + clients = vim.tbl_filter(opts.filter, clients) end if #clients == 0 then @@ -250,12 +250,12 @@ function M.format(options) return params end - if options.async then + if opts.async then local function do_format(idx, client) if not client then return end - local params = set_range(client, util.make_formatting_params(options.formatting_options)) + local params = set_range(client, util.make_formatting_params(opts.formatting_options)) client.request(method, params, function(...) local handler = client.handlers[method] or vim.lsp.handlers[method] handler(...) @@ -264,9 +264,9 @@ function M.format(options) end do_format(next(clients)) else - local timeout_ms = options.timeout_ms or 1000 + local timeout_ms = opts.timeout_ms or 1000 for _, client in pairs(clients) do - local params = set_range(client, util.make_formatting_params(options.formatting_options)) + local params = set_range(client, util.make_formatting_params(opts.formatting_options)) local result, err = client.request_sync(method, params, timeout_ms, bufnr) if result and result.result then util.apply_text_edits(result.result, bufnr, client.offset_encoding) @@ -295,18 +295,18 @@ end --- ---@param new_name string|nil If not provided, the user will be prompted for a new --- name using |vim.ui.input()|. ----@param options? vim.lsp.buf.rename.Opts Additional options: -function M.rename(new_name, options) - options = options or {} - local bufnr = options.bufnr or api.nvim_get_current_buf() +---@param opts? vim.lsp.buf.rename.Opts Additional options: +function M.rename(new_name, opts) + opts = opts or {} + local bufnr = opts.bufnr or api.nvim_get_current_buf() local clients = vim.lsp.get_clients({ bufnr = bufnr, - name = options.name, + name = opts.name, -- Clients must at least support rename, prepareRename is optional method = ms.textDocument_rename, }) - if options.filter then - clients = vim.tbl_filter(options.filter, clients) + if opts.filter then + clients = vim.tbl_filter(opts.filter, clients) end if #clients == 0 then @@ -415,21 +415,21 @@ end --- ---@param context (table|nil) Context for the request ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references ----@param options? vim.lsp.ListOpts -function M.references(context, options) +---@param opts? vim.lsp.ListOpts +function M.references(context, opts) validate({ context = { context, 't', true } }) local params = util.make_position_params() params.context = context or { includeDeclaration = true, } - request_with_options(ms.textDocument_references, params, options) + request_with_opts(ms.textDocument_references, params, opts) end --- Lists all symbols in the current buffer in the quickfix window. ---- @param options? vim.lsp.ListOpts -function M.document_symbol(options) +--- @param opts? vim.lsp.ListOpts +function M.document_symbol(opts) local params = { textDocument = util.make_text_document_params() } - request_with_options(ms.textDocument_documentSymbol, params, options) + request_with_opts(ms.textDocument_documentSymbol, params, opts) end --- @param call_hierarchy_items lsp.CallHierarchyItem[]? @@ -542,7 +542,7 @@ function M.typehierarchy(kind) ) end else - local opts = { + local select_opts = { prompt = 'Select a type hierarchy item:', kind = 'typehierarchy', format_item = function(item) @@ -553,7 +553,7 @@ function M.typehierarchy(kind) end, } - vim.ui.select(merged_results, opts, function(item) + vim.ui.select(merged_results, select_opts, function(item) local client = vim.lsp.get_client_by_id(item[1]) if client then --- @type lsp.TypeHierarchyItem @@ -626,14 +626,14 @@ end --- string means no filtering is done. --- --- @param query string? optional ---- @param options? vim.lsp.ListOpts -function M.workspace_symbol(query, options) +--- @param opts? vim.lsp.ListOpts +function M.workspace_symbol(query, opts) query = query or npcall(vim.fn.input, 'Query: ') if query == nil then return end local params = { query = query } - request_with_options(ms.workspace_symbol, params, options) + request_with_opts(ms.workspace_symbol, params, opts) end --- Send request to the server to resolve document highlights for the current @@ -825,19 +825,19 @@ end --- Selects a code action available at the current --- cursor position. --- ----@param options? vim.lsp.buf.code_action.Opts +---@param opts? vim.lsp.buf.code_action.Opts ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction ---@see vim.lsp.protocol.CodeActionTriggerKind -function M.code_action(options) - validate({ options = { options, 't', true } }) - options = options or {} +function M.code_action(opts) + validate({ options = { opts, 't', true } }) + opts = opts or {} -- Detect old API call code_action(context) which should now be -- code_action({ context = context} ) --- @diagnostic disable-next-line:undefined-field - if options.diagnostics or options.only then - options = { options = options } + if opts.diagnostics or opts.only then + opts = { options = opts } end - local context = options.context or {} + local context = opts.context or {} if not context.triggerKind then context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked end @@ -867,17 +867,17 @@ function M.code_action(options) results[ctx.client_id] = { error = err, result = result, ctx = ctx } remaining = remaining - 1 if remaining == 0 then - on_code_action_results(results, options) + on_code_action_results(results, opts) end end for _, client in ipairs(clients) do ---@type lsp.CodeActionParams local params - if options.range then - assert(type(options.range) == 'table', 'code_action range must be a table') - local start = assert(options.range.start, 'range must have a `start` property') - local end_ = assert(options.range['end'], 'range must have a `end` property') + if opts.range then + assert(type(opts.range) == 'table', 'code_action range must be a table') + local start = assert(opts.range.start, 'range must have a `start` property') + local end_ = assert(opts.range['end'], 'range must have a `end` property') params = util.make_given_range_params(start, end_, bufnr, client.offset_encoding) elseif mode == 'v' or mode == 'V' then local range = range_from_selection(bufnr, mode) -- cgit From 3da251efc6329c4d5e6b94780815dce8d6e24999 Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 09:56:18 +0200 Subject: refactor(lsp): use vim.is_callable() --- runtime/lua/vim/lsp/handlers.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 4672d94105..11818b6a89 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -257,7 +257,7 @@ M[ms.textDocument_references] = function(_, result, ctx, config) vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) api.nvim_command('lopen') elseif config.on_list then - assert(type(config.on_list) == 'function', 'on_list is not a function') + assert(vim.is_callable(config.on_list), 'on_list is not a function') config.on_list({ title = title, items = items, context = ctx }) else vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) @@ -290,7 +290,7 @@ local function response_to_list(map_result, entity, title_fn) vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) api.nvim_command('lopen') elseif config.on_list then - assert(type(config.on_list) == 'function', 'on_list is not a function') + assert(vim.is_callable(config.on_list), 'on_list is not a function') config.on_list({ title = title, items = items, context = ctx }) else vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) @@ -436,7 +436,7 @@ local function location_handler(_, result, ctx, config) local items = util.locations_to_items(result, client.offset_encoding) if config.on_list then - assert(type(config.on_list) == 'function', 'on_list is not a function') + assert(vim.is_callable(config.on_list), 'on_list is not a function') config.on_list({ title = title, items = items }) return end -- cgit From 6ffc209a8a84c6d627dde39d27283d98a451b105 Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 09:58:07 +0200 Subject: refactor(lsp): move repeated table construction into a variable As suggested in https://github.com/neovim/neovim/pull/28483#discussion_r1581712828 --- runtime/lua/vim/lsp/handlers.lua | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 11818b6a89..de146ab1ef 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -253,14 +253,15 @@ M[ms.textDocument_references] = function(_, result, ctx, config) local title = 'References' local items = util.locations_to_items(result, client.offset_encoding) + local list = { title = title, items = items, context = ctx } if config.loclist then - vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) + vim.fn.setloclist(0, {}, ' ', list) api.nvim_command('lopen') elseif config.on_list then assert(vim.is_callable(config.on_list), 'on_list is not a function') - config.on_list({ title = title, items = items, context = ctx }) + config.on_list(list) else - vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) + vim.fn.setqflist({}, ' ', list) api.nvim_command('botright copen') end end @@ -286,14 +287,15 @@ local function response_to_list(map_result, entity, title_fn) local title = title_fn(ctx) local items = map_result(result, ctx.bufnr) + local list = { title = title, items = items, context = ctx } if config.loclist then - vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) + vim.fn.setloclist(0, {}, ' ', list) api.nvim_command('lopen') elseif config.on_list then assert(vim.is_callable(config.on_list), 'on_list is not a function') - config.on_list({ title = title, items = items, context = ctx }) + config.on_list(list) else - vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) + vim.fn.setqflist({}, ' ', list) api.nvim_command('botright copen') end end -- cgit From cdc0974063fd18199040e783df5826af5786aee3 Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 10:02:56 +0200 Subject: docs(lsp): fix type annotations in response_to_list(...) --- runtime/lua/vim/lsp/handlers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index de146ab1ef..aff98dc5cb 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -273,7 +273,7 @@ end --- --- loclist: (boolean) use the location list (default is to use the quickfix list) --- ----@param map_result function `((resp, bufnr) -> list)` to convert the response +---@param map_result fun(resp, bufnr: integer): table to convert the response ---@param entity string name of the resource used in a `not found` error message ---@param title_fn fun(ctx: lsp.HandlerContext): string Function to call to generate list title ---@return lsp.Handler -- cgit From 80d108eeee89c095e0c1226a558a690a708abaa1 Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 10:04:47 +0200 Subject: refactor(lsp): use vim.cmd instead of api.nvim_command As suggested in https://github.com/neovim/neovim/pull/28483#discussion_r1586878457 and https://github.com/neovim/neovim/pull/28483#discussion_r1586878226 --- runtime/lua/vim/lsp/handlers.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index aff98dc5cb..c639a317cf 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -256,13 +256,13 @@ M[ms.textDocument_references] = function(_, result, ctx, config) local list = { title = title, items = items, context = ctx } if config.loclist then vim.fn.setloclist(0, {}, ' ', list) - api.nvim_command('lopen') + vim.cmd.lopen() elseif config.on_list then assert(vim.is_callable(config.on_list), 'on_list is not a function') config.on_list(list) else vim.fn.setqflist({}, ' ', list) - api.nvim_command('botright copen') + vim.cmd('botright copen') end end @@ -290,13 +290,13 @@ local function response_to_list(map_result, entity, title_fn) local list = { title = title, items = items, context = ctx } if config.loclist then vim.fn.setloclist(0, {}, ' ', list) - api.nvim_command('lopen') + vim.cmd.lopen() elseif config.on_list then assert(vim.is_callable(config.on_list), 'on_list is not a function') config.on_list(list) else vim.fn.setqflist({}, ' ', list) - api.nvim_command('botright copen') + vim.cmd('botright copen') end end end @@ -447,7 +447,7 @@ local function location_handler(_, result, ctx, config) return end vim.fn.setqflist({}, ' ', { title = title, items = items }) - api.nvim_command('botright copen') + vim.cmd('botright copen') end --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration @@ -557,7 +557,7 @@ local function make_call_hierarchy_handler(direction) end end vim.fn.setqflist({}, ' ', { title = 'LSP call hierarchy', items = items }) - api.nvim_command('botright copen') + vim.cmd('botright copen') end end @@ -596,7 +596,7 @@ local function make_type_hierarchy_handler() }) end vim.fn.setqflist({}, ' ', { title = 'LSP type hierarchy', items = items }) - api.nvim_command('botright copen') + vim.cmd('botright copen') end end -- cgit From b0cc85c00504dc5530ab5d6c5fa03f3fa96d5a1a Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 10:10:44 +0200 Subject: docs(lsp): document vim.lsp.ListOpts.loclist --- runtime/lua/vim/lsp/buf.lua | 9 ++++----- runtime/lua/vim/lsp/handlers.lua | 5 +---- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 820ff9c2ca..e05acff3df 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -62,14 +62,13 @@ end --- vim.lsp.buf.references(nil, { on_list = on_list }) --- ``` --- ---- If you prefer loclist do something like this: +--- If you prefer loclist instead of qflist: --- ```lua ---- local function on_list(options) ---- vim.fn.setloclist(0, {}, ' ', options) ---- vim.cmd.lopen() ---- end +--- vim.lsp.buf.definition({ loclist = true }) +--- vim.lsp.buf.references(nil, { loclist = true }) --- ``` --- @field on_list? fun(t: vim.lsp.LocationOpts.OnList) +--- @field loclist? boolean --- @class vim.lsp.LocationOpts.OnList --- @field items table[] Structured like |setqflist-what| diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index c639a317cf..205de68101 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -268,10 +268,7 @@ end --- Return a function that converts LSP responses to list items and opens the list --- ---- The returned function has an optional {config} parameter that accepts a table ---- with the following keys: ---- ---- loclist: (boolean) use the location list (default is to use the quickfix list) +--- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts| --- ---@param map_result fun(resp, bufnr: integer): table to convert the response ---@param entity string name of the resource used in a `not found` error message -- cgit From 5c40f3e86a81f78f821b8c75dafc3ce2ce67e1c5 Mon Sep 17 00:00:00 2001 From: tom-anders <13141438+tom-anders@users.noreply.github.com> Date: Sat, 4 May 2024 10:13:08 +0200 Subject: feat(lsp): support vim.lsp.ListOpts.loclist in location_handler() --- runtime/lua/vim/lsp/handlers.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'runtime/lua') diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 205de68101..eec16d7298 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -443,8 +443,13 @@ local function location_handler(_, result, ctx, config) util.jump_to_location(result[1], client.offset_encoding, config.reuse_win) return end - vim.fn.setqflist({}, ' ', { title = title, items = items }) - vim.cmd('botright copen') + if config.loclist then + vim.fn.setloclist(0, {}, ' ', { title = title, items = items }) + vim.cmd.lopen() + else + vim.fn.setqflist({}, ' ', { title = title, items = items }) + vim.cmd('botright copen') + end end --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration -- cgit