diff options
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 46 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/callbacks.lua | 21 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/rpc.lua | 11 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 49 |
4 files changed, 80 insertions, 47 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 208082f241..c015884f5b 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -1,9 +1,7 @@ local vim = vim local validate = vim.validate -local api = vim.api local vfn = vim.fn local util = require 'vim.lsp.util' -local list_extend = vim.list_extend local M = {} @@ -142,6 +140,7 @@ function M.formatting_sync(options, timeout_ms) local result = vim.lsp.buf_request_sync(0, "textDocument/formatting", params, timeout_ms) if not result then return end result = result[1].result + if not result then return end vim.lsp.util.apply_text_edits(result) end @@ -153,36 +152,14 @@ end --@param start_pos ({number, number}, optional) mark-indexed position. ---Defaults to the end of the last visual selection. function M.range_formatting(options, start_pos, end_pos) - validate { - options = {options, 't', true}; - start_pos = {start_pos, 't', true}; - end_pos = {end_pos, 't', true}; - } + validate { options = {options, 't', true} } local sts = vim.bo.softtabstop; options = vim.tbl_extend('keep', options or {}, { tabSize = (sts > 0 and sts) or (sts < 0 and vim.bo.shiftwidth) or vim.bo.tabstop; insertSpaces = vim.bo.expandtab; }) - local A = list_extend({}, start_pos or api.nvim_buf_get_mark(0, '<')) - local B = list_extend({}, end_pos or api.nvim_buf_get_mark(0, '>')) - -- convert to 0-index - A[1] = A[1] - 1 - B[1] = B[1] - 1 - -- account for encoding. - if A[2] > 0 then - A = {A[1], util.character_offset(0, A[1], A[2])} - end - if B[2] > 0 then - B = {B[1], util.character_offset(0, B[1], B[2])} - end - local params = { - textDocument = { uri = vim.uri_from_bufnr(0) }; - range = { - start = { line = A[1]; character = A[2]; }; - ["end"] = { line = B[1]; character = B[2]; }; - }; - options = options; - } + local params = util.make_given_range_params(start_pos, end_pos) + params.options = options return request('textDocument/rangeFormatting', params) end @@ -307,6 +284,21 @@ function M.code_action(context) request('textDocument/codeAction', params) end +--- Performs |vim.lsp.buf.code_action()| for a given range. +--- +--@param context: (table, optional) Valid `CodeActionContext` object +--@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. +function M.range_code_action(context, start_pos, end_pos) + validate { context = { context, 't', true } } + context = context or { diagnostics = util.get_line_diagnostics() } + local params = util.make_given_range_params(start_pos, end_pos) + params.context = context + request('textDocument/codeAction', params) +end + --- Executes an LSP server command. --- --@param command A valid `ExecuteCommandParams` object diff --git a/runtime/lua/vim/lsp/callbacks.lua b/runtime/lua/vim/lsp/callbacks.lua index 0ee03e6a2f..4e7a8333a0 100644 --- a/runtime/lua/vim/lsp/callbacks.lua +++ b/runtime/lua/vim/lsp/callbacks.lua @@ -229,16 +229,19 @@ M['textDocument/implementation'] = location_callback --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_signatureHelp M['textDocument/signatureHelp'] = function(_, method, result) + -- When use `autocmd CompleteDone <silent><buffer> lua vim.lsp.buf.signature_help()` to call signatureHelp callback + -- If the completion item doesn't have signatures It will make noise. Change to use `print` that can use `<silent>` to ignore + if not (result and result.signatures and result.signatures[1]) then + print('No signature help available') + return + end + local lines = util.convert_signature_help_to_markdown_lines(result) + lines = util.trim_empty_lines(lines) + if vim.tbl_isempty(lines) then + print('No signature help available') + return + end util.focusable_preview(method, function() - if not (result and result.signatures and result.signatures[1]) then - return { 'No signature available' } - end - -- TODO show popup when signatures is empty? - local lines = util.convert_signature_help_to_markdown_lines(result) - lines = util.trim_empty_lines(lines) - if vim.tbl_isempty(lines) then - return { 'No signature available' } - end return lines, util.try_trim_markdown_code_blocks(lines) end) end diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 64080cf4f2..749a51fecc 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -494,10 +494,13 @@ local function start(cmd, cmd_args, handlers, extra_spawn_params) decoded.error = convert_NIL(decoded.error) decoded.result = convert_NIL(decoded.result) - -- Do not surface RequestCancelled to users, it is RPC-internal. - if decoded.error - and decoded.error.code == protocol.ErrorCodes.RequestCancelled then - local _ = log.debug() and log.debug("Received cancellation ack", decoded) + -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal. + if decoded.error then + if decoded.error.code == protocol.ErrorCodes.RequestCancelled then + local _ = log.debug() and log.debug("Received cancellation ack", decoded) + elseif decoded.error.code == protocol.ErrorCodes.ContentModified then + local _ = log.debug() and log.debug("Received content modified ack", decoded) + end local result_id = tonumber(decoded.id) -- Clear any callback since this is cancelled now. -- This is safe to do assuming that these conditions hold: diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 24cb454e5b..d94a8bb774 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -505,13 +505,13 @@ function M.convert_signature_help_to_markdown_lines(signature_help) if signature.documentation then M.convert_input_to_markdown_lines(signature.documentation, contents) end - if signature_help.parameters then + if signature.parameters and #signature.parameters > 0 then local active_parameter = signature_help.activeParameter or 0 -- If the activeParameter is not inside the valid range, then clip it. - if active_parameter >= #signature_help.parameters then + if active_parameter >= #signature.parameters then active_parameter = 0 end - local parameter = signature.parameters and signature.parameters[active_parameter] + local parameter = signature.parameters[active_parameter + 1] if parameter then --[=[ --Represents a parameter of a callable-signature. A parameter can @@ -532,8 +532,8 @@ function M.convert_signature_help_to_markdown_lines(signature_help) } --]=] -- TODO highlight parameter - if parameter.documentation then - M.convert_input_help_to_markdown_lines(parameter.documentation, contents) + if parameter.documentation and parameter.documentation ~= vim.NIL then + M.convert_input_to_markdown_lines(parameter.documentation, contents) end end end @@ -668,7 +668,7 @@ function M.focusable_float(unique_name, fn) local bufnr = api.nvim_get_current_buf() do local win = find_window_by_var(unique_name, bufnr) - if win then + if win and api.nvim_win_is_valid(win) and not vim.fn.pumvisible() then api.nvim_set_current_win(win) api.nvim_command("stopinsert") return @@ -1465,11 +1465,46 @@ end function M.make_range_params() local position = make_position_param() return { - textDocument = { uri = vim.uri_from_bufnr(0) }, + textDocument = M.make_text_document_params(), range = { start = position; ["end"] = position; } } 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. +--@returns { textDocument = { uri = `current_file_uri` }, range = { start = +---`start_position`, end = `end_position` } } +function M.make_given_range_params(start_pos, end_pos) + validate { + start_pos = {start_pos, 't', true}; + end_pos = {end_pos, 't', true}; + } + local A = list_extend({}, start_pos or api.nvim_buf_get_mark(0, '<')) + local B = list_extend({}, end_pos or api.nvim_buf_get_mark(0, '>')) + -- convert to 0-index + A[1] = A[1] - 1 + B[1] = B[1] - 1 + -- account for encoding. + if A[2] > 0 then + A = {A[1], M.character_offset(0, A[1], A[2])} + end + if B[2] > 0 then + B = {B[1], M.character_offset(0, B[1], B[2])} + end + return { + textDocument = M.make_text_document_params(), + range = { + start = {line = A[1], character = A[2]}, + ['end'] = {line = B[1], character = B[2]} + } + } +end + --- Creates a `TextDocumentIdentifier` object for the current buffer. --- --@returns `TextDocumentIdentifier` |