diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2022-08-03 00:08:17 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2022-08-03 00:08:17 -0600 |
commit | 9449e1b8d273ff78eb894c588110ffa0c17d6ee3 (patch) | |
tree | 9e4470c33bd4187d9f42f0b2c4aaa995310c5be8 /runtime/lua/vim/lsp | |
parent | 308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (diff) | |
parent | b8dcbcc732baf84fc48d6b272c3ade0bcb129b3b (diff) | |
download | rneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.tar.gz rneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.tar.bz2 rneovim-9449e1b8d273ff78eb894c588110ffa0c17d6ee3.zip |
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 99 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 52 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 1 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 24 |
4 files changed, 113 insertions, 63 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 50a51e897c..63f4688d94 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -11,8 +11,8 @@ local M = {} --- buffer. --- ---@param method (string) LSP method name ----@param params (optional, table) Parameters to send to the server ----@param handler (optional, functionnil) See |lsp-handler|. Follows |lsp-handler-resolution| +---@param params (table|nil) Parameters to send to the server +---@param handler (function|nil) See |lsp-handler|. Follows |lsp-handler-resolution| -- ---@returns 2-tuple: --- - Map of client-id:request-id pairs for all successful requests. @@ -61,6 +61,7 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. +--- - on_list: (function) handler for list results. See |on-list-handler| function M.declaration(options) local params = util.make_position_params() request_with_options('textDocument/declaration', params, options) @@ -70,6 +71,7 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. +--- - on_list: (function) handler for list results. See |on-list-handler| function M.definition(options) local params = util.make_position_params() request_with_options('textDocument/definition', params, options) @@ -79,6 +81,7 @@ end --- ---@param options table|nil additional options --- - reuse_win: (boolean) Jump to existing window if buffer is already open. +--- - on_list: (function) handler for list results. See |on-list-handler| function M.type_definition(options) local params = util.make_position_params() request_with_options('textDocument/typeDefinition', params, options) @@ -86,9 +89,12 @@ end --- Lists all the implementations for the symbol under the cursor in the --- quickfix window. -function M.implementation() +--- +---@param options table|nil additional options +--- - on_list: (function) handler for list results. See |on-list-handler| +function M.implementation(options) local params = util.make_position_params() - request('textDocument/implementation', params) + request_with_options('textDocument/implementation', params, options) end --- Displays signature information about the symbol under the cursor in a @@ -151,7 +157,7 @@ end --- - formatting_options (table|nil): --- Can be used to specify FormattingOptions. Some unspecified options will be --- automatically derived from the current Neovim options. ---- @see https://microsoft.github.io/language-server-protocol/specification#textDocument_formatting +--- 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 --- - bufnr (number|nil): @@ -496,20 +502,24 @@ end --- ---@param context (table) Context for the request ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references -function M.references(context) +---@param options table|nil additional options +--- - on_list: (function) handler for list results. See |on-list-handler| +function M.references(context, options) validate({ context = { context, 't', true } }) local params = util.make_position_params() params.context = context or { includeDeclaration = true, } - request('textDocument/references', params) + request_with_options('textDocument/references', params, options) end --- Lists all symbols in the current buffer in the quickfix window. --- -function M.document_symbol() +---@param options table|nil additional options +--- - on_list: (function) handler for list results. See |on-list-handler| +function M.document_symbol(options) local params = { textDocument = util.make_text_document_params() } - request('textDocument/documentSymbol', params) + request_with_options('textDocument/documentSymbol', params, options) end ---@private @@ -648,13 +658,15 @@ end --- string means no filtering is done. --- ---@param query (string, optional) -function M.workspace_symbol(query) +---@param options table|nil additional options +--- - on_list: (function) handler for list results. See |on-list-handler| +function M.workspace_symbol(query, options) query = query or npcall(vim.fn.input, 'Query: ') if query == nil then return end local params = { query = query } - request('workspace/symbol', params) + request_with_options('workspace/symbol', params, options) end --- Send request to the server to resolve document highlights for the current @@ -830,20 +842,27 @@ end --- cursor position. --- ---@param options table|nil Optional table which holds the following optional fields: ---- - context (table|nil): ---- Corresponds to `CodeActionContext` of the LSP specification: ---- - diagnostics (table|nil): ---- LSP `Diagnostic[]`. Inferred from the current ---- position if not provided. ---- - only (table|nil): ---- List of LSP `CodeActionKind`s used to filter the code actions. ---- Most language servers support values like `refactor` ---- or `quickfix`. ---- - filter (function|nil): ---- Predicate function taking an `CodeAction` and returning a boolean. ---- - apply (boolean|nil): ---- When set to `true`, and there is just one remaining action ---- (after filtering), the action is applied without user query. +--- - context: (table|nil) +--- Corresponds to `CodeActionContext` of the LSP specification: +--- - diagnostics (table|nil): +--- LSP `Diagnostic[]`. Inferred from the current +--- position if not provided. +--- - only (table|nil): +--- List of LSP `CodeActionKind`s used to filter the code actions. +--- Most language servers support values like `refactor` +--- or `quickfix`. +--- - filter: (function|nil) +--- Predicate taking an `CodeAction` and returning a boolean. +--- - apply: (boolean|nil) +--- When set to `true`, and there is just one remaining action +--- (after filtering), the action is applied without user query. +--- +--- - range: (table|nil) +--- Range for which code actions should be requested. +--- If in visual mode this defaults to the active selection. +--- Table must contain `start` and `end` keys with {row, col} tuples +--- using mark-like indexing. See |api-indexing| +--- ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction function M.code_action(options) validate({ options = { options, 't', true } }) @@ -858,7 +877,34 @@ function M.code_action(options) local bufnr = api.nvim_get_current_buf() context.diagnostics = vim.lsp.diagnostic.get_line_diagnostics(bufnr) end - local params = util.make_range_params() + local params + local mode = api.nvim_get_mode().mode + 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') + params = util.make_given_range_params(start, end_) + elseif mode == 'v' or mode == 'V' then + -- [bufnum, lnum, col, off]; both row and column 1-indexed + local start = vim.fn.getpos('v') + local end_ = vim.fn.getpos('.') + local start_row = start[2] + local start_col = start[3] + local end_row = end_[2] + local end_col = end_[3] + + -- A user can start visual selection at the end and move backwards + -- Normalize the range to start < end + if start_row == end_row and end_col < start_col then + end_col, start_col = start_col, end_col + elseif end_row < start_row then + start_row, end_row = end_row, start_row + start_col, end_col = end_col, start_col + end + params = util.make_given_range_params({ start_row, start_col - 1 }, { end_row, end_col - 1 }) + else + params = util.make_range_params() + end params.context = context code_action_request(params, options) end @@ -879,6 +925,7 @@ end ---@param end_pos ({number, number}, optional) mark-indexed position. ---Defaults to the end of the last visual selection. function M.range_code_action(context, start_pos, end_pos) + vim.deprecate('vim.lsp.buf.range_code_action', 'vim.lsp.buf.code_action', '0.9.0') validate({ context = { context, 't', true } }) context = context or {} if not context.diagnostics then diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index 3b869d8f5c..1e6ac8dddf 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -189,19 +189,17 @@ M['textDocument/references'] = function(_, result, ctx, config) else local client = vim.lsp.get_client_by_id(ctx.client_id) config = config or {} + local title = 'References' + local items = util.locations_to_items(result, client.offset_encoding) + if config.loclist then - vim.fn.setloclist(0, {}, ' ', { - title = 'References', - items = util.locations_to_items(result, client.offset_encoding), - context = ctx, - }) + 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') + config.on_list({ title = title, items = items, context = ctx }) else - vim.fn.setqflist({}, ' ', { - title = 'References', - items = util.locations_to_items(result, client.offset_encoding), - context = ctx, - }) + vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) api.nvim_command('botright copen') end end @@ -224,19 +222,17 @@ local function response_to_list(map_result, entity, title_fn) vim.notify('No ' .. entity .. ' found') else config = config or {} + local title = title_fn(ctx) + local items = map_result(result, ctx.bufnr) + if config.loclist then - vim.fn.setloclist(0, {}, ' ', { - title = title_fn(ctx), - items = map_result(result, ctx.bufnr), - context = ctx, - }) + 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') + config.on_list({ title = title, items = items, context = ctx }) else - vim.fn.setqflist({}, ' ', { - title = title_fn(ctx), - items = map_result(result, ctx.bufnr), - context = ctx, - }) + vim.fn.setqflist({}, ' ', { title = title, items = items, context = ctx }) api.nvim_command('botright copen') end end @@ -261,6 +257,7 @@ end) --see: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename M['textDocument/rename'] = function(_, result, ctx, _) if not result then + vim.notify("Language server couldn't provide rename result", vim.log.levels.INFO) return end local client = vim.lsp.get_client_by_id(ctx.client_id) @@ -354,11 +351,16 @@ local function location_handler(_, result, ctx, config) util.jump_to_location(result[1], client.offset_encoding, config.reuse_win) if #result > 1 then - vim.fn.setqflist({}, ' ', { - title = 'LSP locations', - items = util.locations_to_items(result, client.offset_encoding), - }) - api.nvim_command('botright copen') + local title = 'LSP locations' + 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') + config.on_list({ title = title, items = items }) + else + vim.fn.setqflist({}, ' ', { title = title, items = items }) + api.nvim_command('botright copen') + end end else util.jump_to_location(result, client.offset_encoding, config.reuse_win) diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua index 6ecb9959d5..27da60b4ae 100644 --- a/runtime/lua/vim/lsp/protocol.lua +++ b/runtime/lua/vim/lsp/protocol.lua @@ -759,6 +759,7 @@ function protocol.make_client_capabilities() }, hierarchicalWorkspaceSymbolSupport = true, }, + configuration = true, workspaceFolders = true, applyEdit = true, workspaceEdit = { diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 70f5010256..8e89d92a56 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -1821,7 +1821,7 @@ function M.try_trim_markdown_code_blocks(lines) end ---@private ----@param window (optional, number): window handle or 0 for current, defaults to current +---@param window number|nil: window handle or 0 for current, defaults to current ---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` local function make_position_param(window, offset_encoding) window = window or 0 @@ -1841,7 +1841,7 @@ end --- Creates a `TextDocumentPositionParams` object for the current buffer and cursor position. --- ----@param window (optional, number): window handle or 0 for current, defaults to current +---@param window number|nil: window handle or 0 for current, defaults to current ---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` ---@returns `TextDocumentPositionParams` object ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentPositionParams @@ -1894,8 +1894,8 @@ end --- `textDocument/codeAction`, `textDocument/colorPresentation`, --- `textDocument/rangeFormatting`. --- ----@param window (optional, number): window handle or 0 for current, defaults to current ----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of buffer of `window` +---@param window number|nil: window handle or 0 for current, defaults to current +---@param offset_encoding "utf-8"|"utf-16"|"utf-32"|nil defaults to `offset_encoding` of first client of buffer of `window` ---@returns { textDocument = { uri = `current_file_uri` }, range = { start = ---`current_position`, end = `current_position` } } function M.make_range_params(window, offset_encoding) @@ -1911,12 +1911,12 @@ end --- Using the given range in the current buffer, creates an object that --- is similar to |vim.lsp.util.make_range_params()|. --- ----@param start_pos ({number, number}, optional) mark-indexed position. ----Defaults to the start of the last visual selection. ----@param end_pos ({number, number}, optional) mark-indexed position. ----Defaults to the end of the last visual selection. ----@param bufnr (optional, number): buffer handle or 0 for current, defaults to current ----@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of `bufnr` +---@param start_pos number[]|nil {row, col} mark-indexed position. +--- Defaults to the start of the last visual selection. +---@param end_pos number[]|nil {row, col} mark-indexed position. +--- Defaults to the end of the last visual selection. +---@param bufnr number|nil buffer handle or 0 for current, defaults to current +---@param offset_encoding "utf-8"|"utf-16"|"utf-32"|nil defaults to `offset_encoding` of first client of `bufnr` ---@returns { textDocument = { uri = `current_file_uri` }, range = { start = ---`start_position`, end = `end_position` } } function M.make_given_range_params(start_pos, end_pos, bufnr, offset_encoding) @@ -1956,7 +1956,7 @@ end --- Creates a `TextDocumentIdentifier` object for the current buffer. --- ----@param bufnr (optional, number): Buffer handle, defaults to current +---@param bufnr number|nil: Buffer handle, defaults to current ---@returns `TextDocumentIdentifier` ---@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocumentIdentifier function M.make_text_document_params(bufnr) @@ -2000,7 +2000,7 @@ end --- Returns the UTF-32 and UTF-16 offsets for a position in a certain buffer. --- ----@param buf buffer id (0 for current) +---@param buf number buffer number (0 for current) ---@param row 0-indexed line ---@param col 0-indexed byte offset in line ---@param offset_encoding string utf-8|utf-16|utf-32|nil defaults to `offset_encoding` of first client of `buf` |