Merge #28637 more support for vim.lsp.ListOpts.loclist

This commit is contained in:
Justin M. Keyes
2024-05-07 12:56:39 -07:00
committed by GitHub
4 changed files with 164 additions and 159 deletions

View File

@@ -1201,12 +1201,11 @@ Lua module: vim.lsp.buf *lsp-buf*
vim.lsp.buf.references(nil, { on_list = on_list }) vim.lsp.buf.references(nil, { on_list = on_list })
< <
If you prefer loclist do something like this: >lua If you prefer loclist instead of qflist: >lua
local function on_list(options) vim.lsp.buf.definition({ loclist = true })
vim.fn.setloclist(0, {}, ' ', options) vim.lsp.buf.references(nil, { loclist = true })
vim.cmd.lopen()
end
< <
• {loclist}? (`boolean`)
*vim.lsp.LocationOpts* *vim.lsp.LocationOpts*
Extends: |vim.lsp.ListOpts| Extends: |vim.lsp.ListOpts|
@@ -1235,30 +1234,30 @@ add_workspace_folder({workspace_folder})
clear_references() *vim.lsp.buf.clear_references()* clear_references() *vim.lsp.buf.clear_references()*
Removes document highlights from current buffer. Removes document highlights from current buffer.
code_action({options}) *vim.lsp.buf.code_action()* code_action({opts}) *vim.lsp.buf.code_action()*
Selects a code action available at the current cursor position. Selects a code action available at the current cursor position.
Parameters: ~ Parameters: ~
• {options} (`table?`) A table with the following fields: • {opts} (`table?`) A table with the following fields:
• {context}? (`lsp.CodeActionContext`) Corresponds to • {context}? (`lsp.CodeActionContext`) Corresponds to
`CodeActionContext` of the LSP specification: `CodeActionContext` of the LSP specification:
• {diagnostics}? (`table`) LSP `Diagnostic[]`. Inferred • {diagnostics}? (`table`) LSP `Diagnostic[]`. Inferred from
from the current position if not provided. the current position if not provided.
• {only}? (`table`) List of LSP `CodeActionKind`s used to • {only}? (`table`) List of LSP `CodeActionKind`s used to
filter the code actions. Most language servers support filter the code actions. Most language servers support
values like `refactor` or `quickfix`. values like `refactor` or `quickfix`.
• {triggerKind}? (`integer`) The reason why code actions • {triggerKind}? (`integer`) The reason why code actions
were requested. were requested.
• {filter}? (`fun(x: lsp.CodeAction|lsp.Command):boolean`) • {filter}? (`fun(x: lsp.CodeAction|lsp.Command):boolean`)
Predicate taking an `CodeAction` and returning a boolean. Predicate taking an `CodeAction` and returning a boolean.
• {apply}? (`boolean`) When set to `true`, and there is • {apply}? (`boolean`) When set to `true`, and there is just
just one remaining action (after filtering), the action one remaining action (after filtering), the action is
is applied without user query. applied without user query.
• {range}? (`{start: integer[], end: integer[]}`) Range for • {range}? (`{start: integer[], end: integer[]}`) Range for
which code actions should be requested. If in visual mode which code actions should be requested. If in visual mode
this defaults to the active selection. Table must contain this defaults to the active selection. Table must contain
`start` and `end` keys with {row,col} tuples using `start` and `end` keys with {row,col} tuples using mark-like
mark-like indexing. See |api-indexing| indexing. See |api-indexing|
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
@@ -1277,7 +1276,7 @@ completion({context}) *vim.lsp.buf.completion()*
See also: ~ See also: ~
• vim.lsp.protocol.CompletionTriggerKind • vim.lsp.protocol.CompletionTriggerKind
declaration({options}) *vim.lsp.buf.declaration()* declaration({opts}) *vim.lsp.buf.declaration()*
Jumps to the declaration of the symbol under the cursor. Jumps to the declaration of the symbol under the cursor.
Note: ~ Note: ~
@@ -1285,13 +1284,13 @@ declaration({options}) *vim.lsp.buf.declaration()*
|vim.lsp.buf.definition()| instead. |vim.lsp.buf.definition()| instead.
Parameters: ~ Parameters: ~
• {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|. • {opts} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
definition({options}) *vim.lsp.buf.definition()* definition({opts}) *vim.lsp.buf.definition()*
Jumps to the definition of the symbol under the cursor. Jumps to the definition of the symbol under the cursor.
Parameters: ~ Parameters: ~
• {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|. • {opts} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
document_highlight() *vim.lsp.buf.document_highlight()* document_highlight() *vim.lsp.buf.document_highlight()*
Send request to the server to resolve document highlights for the current Send request to the server to resolve document highlights for the current
@@ -1307,11 +1306,11 @@ document_highlight() *vim.lsp.buf.document_highlight()*
highlights. |hl-LspReferenceText| |hl-LspReferenceRead| highlights. |hl-LspReferenceText| |hl-LspReferenceRead|
|hl-LspReferenceWrite| |hl-LspReferenceWrite|
document_symbol({options}) *vim.lsp.buf.document_symbol()* document_symbol({opts}) *vim.lsp.buf.document_symbol()*
Lists all symbols in the current buffer in the quickfix window. Lists all symbols in the current buffer in the quickfix window.
Parameters: ~ Parameters: ~
• {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|. • {opts} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
execute_command({command_params}) *vim.lsp.buf.execute_command()* execute_command({command_params}) *vim.lsp.buf.execute_command()*
Executes an LSP server command. Executes an LSP server command.
@@ -1322,53 +1321,53 @@ execute_command({command_params}) *vim.lsp.buf.execute_command()*
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#workspace_executeCommand
format({options}) *vim.lsp.buf.format()* format({opts}) *vim.lsp.buf.format()*
Formats a buffer using the attached (and optionally filtered) language Formats a buffer using the attached (and optionally filtered) language
server clients. server clients.
Parameters: ~ Parameters: ~
• {options} (`table?`) A table with the following fields: • {opts} (`table?`) A table with the following fields:
• {formatting_options}? (`table`) Can be used to specify • {formatting_options}? (`table`) Can be used to specify
FormattingOptions. Some unspecified options will be FormattingOptions. Some unspecified options will be
automatically derived from the current Nvim options. See automatically derived from the current Nvim options. See
https://microsoft.github.io/language-server-protocol/specification/#formattingOptions https://microsoft.github.io/language-server-protocol/specification/#formattingOptions
• {timeout_ms}? (`integer`, default: `1000`) Time in • {timeout_ms}? (`integer`, default: `1000`) Time in
milliseconds to block for formatting requests. No effect milliseconds to block for formatting requests. No effect if
if async=true. async=true.
• {bufnr}? (`integer`, default: current buffer) Restrict • {bufnr}? (`integer`, default: current buffer) Restrict
formatting to the clients attached to the given buffer. formatting to the clients attached to the given buffer.
• {filter}? (`fun(client: vim.lsp.Client): boolean?`) • {filter}? (`fun(client: vim.lsp.Client): boolean?`)
Predicate used to filter clients. Receives a client as Predicate used to filter clients. Receives a client as
argument and must return a boolean. Clients matching the argument and must return a boolean. Clients matching the
predicate are included. Example: >lua predicate are included. Example: >lua
-- Never request typescript-language-server for formatting -- Never request typescript-language-server for formatting
vim.lsp.buf.format { vim.lsp.buf.format {
filter = function(client) return client.name ~= "tsserver" end filter = function(client) return client.name ~= "tsserver" end
} }
< <
• {async}? (`boolean`, default: false) If true the method • {async}? (`boolean`, default: false) If true the method
won't block. Editing the buffer while formatting won't block. Editing the buffer while formatting
asynchronous can lead to unexpected changes. asynchronous can lead to unexpected changes.
• {id}? (`integer`) Restrict formatting to the client with • {id}? (`integer`) Restrict formatting to the client with ID
ID (client.id) matching this field. (client.id) matching this field.
• {name}? (`string`) Restrict formatting to the client with • {name}? (`string`) Restrict formatting to the client with
name (client.name) matching this field. name (client.name) matching this field.
• {range}? (`{start:integer[],end:integer[]}`, default: • {range}? (`{start:integer[],end:integer[]}`, default:
current selection in visual mode, `nil` in other modes, current selection in visual mode, `nil` in other modes,
formatting the full buffer) Range to format. Table must formatting the full buffer) Range to format. Table must
contain `start` and `end` keys with {row,col} tuples contain `start` and `end` keys with {row,col} tuples using
using (1,0) indexing. (1,0) indexing.
hover() *vim.lsp.buf.hover()* hover() *vim.lsp.buf.hover()*
Displays hover information about the symbol under the cursor in a floating Displays hover information about the symbol under the cursor in a floating
window. Calling the function twice will jump into the floating window. window. Calling the function twice will jump into the floating window.
implementation({options}) *vim.lsp.buf.implementation()* implementation({opts}) *vim.lsp.buf.implementation()*
Lists all the implementations for the symbol under the cursor in the Lists all the implementations for the symbol under the cursor in the
quickfix window. quickfix window.
Parameters: ~ Parameters: ~
• {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|. • {opts} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
incoming_calls() *vim.lsp.buf.incoming_calls()* incoming_calls() *vim.lsp.buf.incoming_calls()*
Lists all the call sites of the symbol under the cursor in the |quickfix| Lists all the call sites of the symbol under the cursor in the |quickfix|
@@ -1383,13 +1382,13 @@ outgoing_calls() *vim.lsp.buf.outgoing_calls()*
|quickfix| window. If the symbol can resolve to multiple items, the user |quickfix| window. If the symbol can resolve to multiple items, the user
can pick one in the |inputlist()|. can pick one in the |inputlist()|.
references({context}, {options}) *vim.lsp.buf.references()* references({context}, {opts}) *vim.lsp.buf.references()*
Lists all the references to the symbol under the cursor in the quickfix Lists all the references to the symbol under the cursor in the quickfix
window. window.
Parameters: ~ Parameters: ~
• {context} (`table?`) Context for the request • {context} (`table?`) Context for the request
• {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|. • {opts} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
See also: ~ See also: ~
• https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references • https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
@@ -1402,13 +1401,13 @@ remove_workspace_folder({workspace_folder})
Parameters: ~ Parameters: ~
• {workspace_folder} (`string?`) • {workspace_folder} (`string?`)
rename({new_name}, {options}) *vim.lsp.buf.rename()* rename({new_name}, {opts}) *vim.lsp.buf.rename()*
Renames all references to the symbol under the cursor. Renames all references to the symbol under the cursor.
Parameters: ~ Parameters: ~
• {new_name} (`string?`) If not provided, the user will be prompted for • {new_name} (`string?`) If not provided, the user will be prompted for
a new name using |vim.ui.input()|. a new name using |vim.ui.input()|.
• {options} (`table?`) Additional options: • {opts} (`table?`) Additional options:
• {filter}? (`fun(client: vim.lsp.Client): boolean?`) • {filter}? (`fun(client: vim.lsp.Client): boolean?`)
Predicate used to filter clients. Receives a client as Predicate used to filter clients. Receives a client as
argument and must return a boolean. Clients matching the argument and must return a boolean. Clients matching the
@@ -1421,11 +1420,11 @@ signature_help() *vim.lsp.buf.signature_help()*
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.
type_definition({options}) *vim.lsp.buf.type_definition()* type_definition({opts}) *vim.lsp.buf.type_definition()*
Jumps to the definition of the type of the symbol under the cursor. Jumps to the definition of the type of the symbol under the cursor.
Parameters: ~ Parameters: ~
• {options} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|. • {opts} (`vim.lsp.LocationOpts?`) See |vim.lsp.LocationOpts|.
typehierarchy({kind}) *vim.lsp.buf.typehierarchy()* typehierarchy({kind}) *vim.lsp.buf.typehierarchy()*
Lists all the subtypes or supertypes of the symbol under the cursor in the Lists all the subtypes or supertypes of the symbol under the cursor in the
@@ -1435,7 +1434,7 @@ typehierarchy({kind}) *vim.lsp.buf.typehierarchy()*
Parameters: ~ Parameters: ~
• {kind} (`"subtypes"|"supertypes"`) • {kind} (`"subtypes"|"supertypes"`)
workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()* workspace_symbol({query}, {opts}) *vim.lsp.buf.workspace_symbol()*
Lists all symbols in the current workspace in the quickfix window. Lists all symbols in the current workspace in the quickfix window.
The list is filtered against {query}; if the argument is omitted from the The list is filtered against {query}; if the argument is omitted from the
@@ -1443,8 +1442,8 @@ workspace_symbol({query}, {options}) *vim.lsp.buf.workspace_symbol()*
string means no filtering is done. string means no filtering is done.
Parameters: ~ Parameters: ~
• {query} (`string?`) optional • {query} (`string?`) optional
• {options} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|. • {opts} (`vim.lsp.ListOpts?`) See |vim.lsp.ListOpts|.
============================================================================== ==============================================================================

View File

@@ -268,6 +268,9 @@ The following new APIs and features were added.
respective capability can be unset. respective capability can be unset.
• |vim.lsp.start()| accepts a "silent" option for suppressing messages • |vim.lsp.start()| accepts a "silent" option for suppressing messages
if an LSP server failed to start. if an LSP server failed to start.
• |vim.lsp.buf.definition()|, |vim.lsp.buf.declaration()|,
|vim.lsp.buf.type_definition()|, and |vim.lsp.buf.implementation()| now
support the `loclist` field of |vim.lsp.ListOpts|.
• Treesitter • Treesitter
• Bundled parsers and queries (highlight, folds) for Markdown, Python, and • Bundled parsers and queries (highlight, folds) for Markdown, Python, and

View File

@@ -35,13 +35,13 @@ function M.hover()
request(ms.textDocument_hover, params) request(ms.textDocument_hover, params)
end end
local function request_with_options(name, params, options) local function request_with_opts(name, params, opts)
local req_handler --- @type function? local req_handler --- @type function?
if options 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(vim.lsp.get_client_by_id(ctx.client_id))
local handler = client.handlers[name] or vim.lsp.handlers[name] 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
end end
request(name, params, req_handler) request(name, params, req_handler)
@@ -62,14 +62,13 @@ end
--- vim.lsp.buf.references(nil, { on_list = on_list }) --- 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 --- ```lua
--- local function on_list(options) --- vim.lsp.buf.definition({ loclist = true })
--- vim.fn.setloclist(0, {}, ' ', options) --- vim.lsp.buf.references(nil, { loclist = true })
--- vim.cmd.lopen()
--- end
--- ``` --- ```
--- @field on_list? fun(t: vim.lsp.LocationOpts.OnList) --- @field on_list? fun(t: vim.lsp.LocationOpts.OnList)
--- @field loclist? boolean
--- @class vim.lsp.LocationOpts.OnList --- @class vim.lsp.LocationOpts.OnList
--- @field items table[] Structured like |setqflist-what| --- @field items table[] Structured like |setqflist-what|
@@ -83,32 +82,32 @@ end
--- Jumps to the declaration of the symbol under the cursor. --- 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. --- @note Many servers do not implement this method. Generally, see |vim.lsp.buf.definition()| instead.
--- @param options? vim.lsp.LocationOpts --- @param opts? vim.lsp.LocationOpts
function M.declaration(options) function M.declaration(opts)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_declaration, params, options) request_with_opts(ms.textDocument_declaration, params, opts)
end end
--- Jumps to the definition of the symbol under the cursor. --- Jumps to the definition of the symbol under the cursor.
--- @param options? vim.lsp.LocationOpts --- @param opts? vim.lsp.LocationOpts
function M.definition(options) function M.definition(opts)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_definition, params, options) request_with_opts(ms.textDocument_definition, params, opts)
end end
--- Jumps to the definition of the type of the symbol under the cursor. --- Jumps to the definition of the type of the symbol under the cursor.
--- @param options? vim.lsp.LocationOpts --- @param opts? vim.lsp.LocationOpts
function M.type_definition(options) function M.type_definition(opts)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_typeDefinition, params, options) request_with_opts(ms.textDocument_typeDefinition, params, opts)
end end
--- Lists all the implementations for the symbol under the cursor in the --- Lists all the implementations for the symbol under the cursor in the
--- quickfix window. --- quickfix window.
--- @param options? vim.lsp.LocationOpts --- @param opts? vim.lsp.LocationOpts
function M.implementation(options) function M.implementation(opts)
local params = util.make_position_params() local params = util.make_position_params()
request_with_options(ms.textDocument_implementation, params, options) request_with_opts(ms.textDocument_implementation, params, opts)
end end
--- Displays signature information about the symbol under the cursor in a --- Displays signature information about the symbol under the cursor in a
@@ -213,25 +212,25 @@ end
--- Formats a buffer using the attached (and optionally filtered) language --- Formats a buffer using the attached (and optionally filtered) language
--- server clients. --- server clients.
--- ---
--- @param options? vim.lsp.buf.format.Opts --- @param opts? vim.lsp.buf.format.Opts
function M.format(options) function M.format(opts)
options = options or {} opts = opts or {}
local bufnr = options.bufnr or api.nvim_get_current_buf() local bufnr = opts.bufnr or api.nvim_get_current_buf()
local mode = api.nvim_get_mode().mode 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 if not range and mode == 'v' or mode == 'V' then
range = range_from_selection(bufnr, mode) range = range_from_selection(bufnr, mode)
end end
local method = range and ms.textDocument_rangeFormatting or ms.textDocument_formatting local method = range and ms.textDocument_rangeFormatting or ms.textDocument_formatting
local clients = vim.lsp.get_clients({ local clients = vim.lsp.get_clients({
id = options.id, id = opts.id,
bufnr = bufnr, bufnr = bufnr,
name = options.name, name = opts.name,
method = method, method = method,
}) })
if options.filter then if opts.filter then
clients = vim.tbl_filter(options.filter, clients) clients = vim.tbl_filter(opts.filter, clients)
end end
if #clients == 0 then if #clients == 0 then
@@ -250,12 +249,12 @@ function M.format(options)
return params return params
end end
if options.async then if opts.async then
local function do_format(idx, client) local function do_format(idx, client)
if not client then if not client then
return return
end 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(...) client.request(method, params, function(...)
local handler = client.handlers[method] or vim.lsp.handlers[method] local handler = client.handlers[method] or vim.lsp.handlers[method]
handler(...) handler(...)
@@ -264,9 +263,9 @@ function M.format(options)
end end
do_format(next(clients)) do_format(next(clients))
else else
local timeout_ms = options.timeout_ms or 1000 local timeout_ms = opts.timeout_ms or 1000
for _, client in pairs(clients) do 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) local result, err = client.request_sync(method, params, timeout_ms, bufnr)
if result and result.result then if result and result.result then
util.apply_text_edits(result.result, bufnr, client.offset_encoding) util.apply_text_edits(result.result, bufnr, client.offset_encoding)
@@ -295,18 +294,18 @@ end
--- ---
---@param new_name string|nil If not provided, the user will be prompted for a new ---@param new_name string|nil If not provided, the user will be prompted for a new
--- name using |vim.ui.input()|. --- name using |vim.ui.input()|.
---@param options? vim.lsp.buf.rename.Opts Additional options: ---@param opts? vim.lsp.buf.rename.Opts Additional options:
function M.rename(new_name, options) function M.rename(new_name, opts)
options = options or {} opts = opts or {}
local bufnr = options.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 = vim.lsp.get_clients({
bufnr = bufnr, bufnr = bufnr,
name = options.name, name = opts.name,
-- Clients must at least support rename, prepareRename is optional -- Clients must at least support rename, prepareRename is optional
method = ms.textDocument_rename, method = ms.textDocument_rename,
}) })
if options.filter then if opts.filter then
clients = vim.tbl_filter(options.filter, clients) clients = vim.tbl_filter(opts.filter, clients)
end end
if #clients == 0 then if #clients == 0 then
@@ -415,21 +414,21 @@ end
--- ---
---@param context (table|nil) Context for the request ---@param context (table|nil) Context for the request
---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references
---@param options? vim.lsp.ListOpts ---@param opts? vim.lsp.ListOpts
function M.references(context, options) function M.references(context, opts)
validate({ context = { context, 't', true } }) validate({ context = { context, 't', true } })
local params = util.make_position_params() local params = util.make_position_params()
params.context = context or { params.context = context or {
includeDeclaration = true, includeDeclaration = true,
} }
request_with_options(ms.textDocument_references, params, options) request_with_opts(ms.textDocument_references, params, opts)
end end
--- Lists all symbols in the current buffer in the quickfix window. --- Lists all symbols in the current buffer in the quickfix window.
--- @param options? vim.lsp.ListOpts --- @param opts? vim.lsp.ListOpts
function M.document_symbol(options) function M.document_symbol(opts)
local params = { textDocument = util.make_text_document_params() } 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 end
--- @param call_hierarchy_items lsp.CallHierarchyItem[]? --- @param call_hierarchy_items lsp.CallHierarchyItem[]?
@@ -542,7 +541,7 @@ function M.typehierarchy(kind)
) )
end end
else else
local opts = { local select_opts = {
prompt = 'Select a type hierarchy item:', prompt = 'Select a type hierarchy item:',
kind = 'typehierarchy', kind = 'typehierarchy',
format_item = function(item) format_item = function(item)
@@ -553,7 +552,7 @@ function M.typehierarchy(kind)
end, 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]) local client = vim.lsp.get_client_by_id(item[1])
if client then if client then
--- @type lsp.TypeHierarchyItem --- @type lsp.TypeHierarchyItem
@@ -626,14 +625,14 @@ end
--- string means no filtering is done. --- string means no filtering is done.
--- ---
--- @param query string? optional --- @param query string? optional
--- @param options? vim.lsp.ListOpts --- @param opts? vim.lsp.ListOpts
function M.workspace_symbol(query, options) function M.workspace_symbol(query, opts)
query = query or npcall(vim.fn.input, 'Query: ') query = query or npcall(vim.fn.input, 'Query: ')
if query == nil then if query == nil then
return return
end end
local params = { query = query } local params = { query = query }
request_with_options(ms.workspace_symbol, params, options) request_with_opts(ms.workspace_symbol, params, opts)
end end
--- Send request to the server to resolve document highlights for the current --- Send request to the server to resolve document highlights for the current
@@ -825,19 +824,19 @@ end
--- Selects a code action available at the current --- Selects a code action available at the current
--- cursor position. --- 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 https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
---@see vim.lsp.protocol.CodeActionTriggerKind ---@see vim.lsp.protocol.CodeActionTriggerKind
function M.code_action(options) function M.code_action(opts)
validate({ options = { options, 't', true } }) validate({ options = { opts, 't', true } })
options = options or {} opts = opts or {}
-- Detect old API call code_action(context) which should now be -- Detect old API call code_action(context) which should now be
-- code_action({ context = context} ) -- code_action({ context = context} )
--- @diagnostic disable-next-line:undefined-field --- @diagnostic disable-next-line:undefined-field
if options.diagnostics or options.only then if opts.diagnostics or opts.only then
options = { options = options } opts = { options = opts }
end end
local context = options.context or {} local context = opts.context or {}
if not context.triggerKind then if not context.triggerKind then
context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked context.triggerKind = vim.lsp.protocol.CodeActionTriggerKind.Invoked
end end
@@ -867,17 +866,17 @@ function M.code_action(options)
results[ctx.client_id] = { error = err, result = result, ctx = ctx } results[ctx.client_id] = { error = err, result = result, ctx = ctx }
remaining = remaining - 1 remaining = remaining - 1
if remaining == 0 then if remaining == 0 then
on_code_action_results(results, options) on_code_action_results(results, opts)
end end
end end
for _, client in ipairs(clients) do for _, client in ipairs(clients) do
---@type lsp.CodeActionParams ---@type lsp.CodeActionParams
local params local params
if options.range then if opts.range then
assert(type(options.range) == 'table', 'code_action range must be a table') assert(type(opts.range) == 'table', 'code_action range must be a table')
local start = assert(options.range.start, 'range must have a `start` property') local start = assert(opts.range.start, 'range must have a `start` property')
local end_ = assert(options.range['end'], 'range must have a `end` 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) params = util.make_given_range_params(start, end_, bufnr, client.offset_encoding)
elseif mode == 'v' or mode == 'V' then elseif mode == 'v' or mode == 'V' then
local range = range_from_selection(bufnr, mode) local range = range_from_selection(bufnr, mode)

View File

@@ -253,26 +253,24 @@ M[ms.textDocument_references] = function(_, result, ctx, config)
local title = 'References' local title = 'References'
local items = util.locations_to_items(result, client.offset_encoding) local items = util.locations_to_items(result, client.offset_encoding)
local list = { title = title, items = items, context = ctx }
if config.loclist then if config.loclist then
vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) vim.fn.setloclist(0, {}, ' ', list)
api.nvim_command('lopen') vim.cmd.lopen()
elseif config.on_list then 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 }) config.on_list(list)
else else
vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) vim.fn.setqflist({}, ' ', list)
api.nvim_command('botright copen') vim.cmd('botright copen')
end end
end end
--- Return a function that converts LSP responses to list items and opens the list --- 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 --- The returned function has an optional {config} parameter that accepts |vim.lsp.ListOpts|
--- with the following keys:
--- ---
--- loclist: (boolean) use the location list (default is to use the quickfix list) ---@param map_result fun(resp, bufnr: integer): table to convert the response
---
---@param map_result function `((resp, bufnr) -> list)` to convert the response
---@param entity string name of the resource used in a `not found` error message ---@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 ---@param title_fn fun(ctx: lsp.HandlerContext): string Function to call to generate list title
---@return lsp.Handler ---@return lsp.Handler
@@ -286,15 +284,16 @@ local function response_to_list(map_result, entity, title_fn)
local title = title_fn(ctx) local title = title_fn(ctx)
local items = map_result(result, ctx.bufnr) local items = map_result(result, ctx.bufnr)
local list = { title = title, items = items, context = ctx }
if config.loclist then if config.loclist then
vim.fn.setloclist(0, {}, ' ', { title = title, items = items, context = ctx }) vim.fn.setloclist(0, {}, ' ', list)
api.nvim_command('lopen') vim.cmd.lopen()
elseif config.on_list then 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 }) config.on_list(list)
else else
vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) vim.fn.setqflist({}, ' ', list)
api.nvim_command('botright copen') vim.cmd('botright copen')
end end
end end
end end
@@ -436,7 +435,7 @@ local function location_handler(_, result, ctx, config)
local items = util.locations_to_items(result, client.offset_encoding) local items = util.locations_to_items(result, client.offset_encoding)
if config.on_list then 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 }) config.on_list({ title = title, items = items })
return return
end end
@@ -444,8 +443,13 @@ local function location_handler(_, result, ctx, config)
util.jump_to_location(result[1], client.offset_encoding, config.reuse_win) util.jump_to_location(result[1], client.offset_encoding, config.reuse_win)
return return
end end
vim.fn.setqflist({}, ' ', { title = title, items = items }) if config.loclist then
api.nvim_command('botright copen') 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 end
--- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration --- @see # https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_declaration
@@ -555,7 +559,7 @@ local function make_call_hierarchy_handler(direction)
end end
end end
vim.fn.setqflist({}, ' ', { title = 'LSP call hierarchy', items = items }) vim.fn.setqflist({}, ' ', { title = 'LSP call hierarchy', items = items })
api.nvim_command('botright copen') vim.cmd('botright copen')
end end
end end
@@ -594,7 +598,7 @@ local function make_type_hierarchy_handler()
}) })
end end
vim.fn.setqflist({}, ' ', { title = 'LSP type hierarchy', items = items }) vim.fn.setqflist({}, ' ', { title = 'LSP type hierarchy', items = items })
api.nvim_command('botright copen') vim.cmd('botright copen')
end end
end end