diff options
Diffstat (limited to 'runtime/lua/vim/lsp')
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 5 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/codelens.lua | 6 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/diagnostic.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/rpc.lua | 29 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 21 |
6 files changed, 49 insertions, 17 deletions
diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index 245f29943e..128f0b01ad 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -480,11 +480,11 @@ local function on_code_action_results(results, ctx) end if action.command then local command = type(action.command) == 'table' and action.command or action - local fn = vim.lsp.commands[command.command] + local fn = client.commands[command.command] or vim.lsp.commands[command.command] if fn then local enriched_ctx = vim.deepcopy(ctx) enriched_ctx.client_id = client.id - fn(command, ctx) + fn(command, enriched_ctx) else M.execute_command(command) end @@ -529,6 +529,7 @@ local function on_code_action_results(results, ctx) vim.ui.select(action_tuples, { prompt = 'Code actions:', + kind = 'codeaction', format_item = function(action_tuple) local title = action_tuple[2].title:gsub('\r\n', '\\r\\n') return title:gsub('\n', '\\n') diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua index 63fcbe430b..9eb64c9a2e 100644 --- a/runtime/lua/vim/lsp/codelens.lua +++ b/runtime/lua/vim/lsp/codelens.lua @@ -31,15 +31,15 @@ local function execute_lens(lens, bufnr, client_id) local line = lens.range.start.line api.nvim_buf_clear_namespace(bufnr, namespaces[client_id], line, line + 1) + local client = vim.lsp.get_client_by_id(client_id) + assert(client, 'Client is required to execute lens, client_id=' .. client_id) local command = lens.command - local fn = vim.lsp.commands[command.command] + local fn = client.commands[command.command] or vim.lsp.commands[command.command] if fn then fn(command, { bufnr = bufnr, client_id = client_id }) return end -- Need to use the client that returned the lens → must not use buf_request - local client = vim.lsp.get_client_by_id(client_id) - assert(client, 'Client is required to execute lens, client_id=' .. client_id) local command_provider = client.server_capabilities.executeCommandProvider local commands = type(command_provider) == 'table' and command_provider.commands or {} if not vim.tbl_contains(commands, command.command) then diff --git a/runtime/lua/vim/lsp/diagnostic.lua b/runtime/lua/vim/lsp/diagnostic.lua index bea0e44aca..1e6f83c1ba 100644 --- a/runtime/lua/vim/lsp/diagnostic.lua +++ b/runtime/lua/vim/lsp/diagnostic.lua @@ -146,7 +146,8 @@ local _client_namespaces = {} function M.get_namespace(client_id) vim.validate { client_id = { client_id, 'n' } } if not _client_namespaces[client_id] then - local name = string.format("vim.lsp.client-%d", client_id) + local client = vim.lsp.get_client_by_id(client_id) + local name = string.format("vim.lsp.%s.%d", client and client.name or "unknown", client_id) _client_namespaces[client_id] = vim.api.nvim_create_namespace(name) end return _client_namespaces[client_id] diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua index eff27807be..01d7102e8f 100644 --- a/runtime/lua/vim/lsp/handlers.lua +++ b/runtime/lua/vim/lsp/handlers.lua @@ -185,7 +185,7 @@ local function response_to_list(map_result, entity) title = 'Language Server'; items = map_result(result, ctx.bufnr); }) - api.nvim_command("copen") + api.nvim_command("botright copen") end end end diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index d9a684a738..bce1e9f35d 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -297,6 +297,7 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) local message_index = 0 local message_callbacks = {} + local notify_reply_callbacks = {} local handle, pid do @@ -309,8 +310,9 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) stdout:close() stderr:close() handle:close() - -- Make sure that message_callbacks can be gc'd. + -- Make sure that message_callbacks/notify_reply_callbacks can be gc'd. message_callbacks = nil + notify_reply_callbacks = nil dispatchers.on_exit(code, signal) end local spawn_params = { @@ -375,10 +377,12 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) ---@param method (string) The invoked LSP method ---@param params (table) Parameters for the invoked LSP method ---@param callback (function) Callback to invoke + ---@param notify_reply_callback (function) Callback to invoke as soon as a request is no longer pending ---@returns (bool, number) `(true, message_id)` if request could be sent, `false` if not - local function request(method, params, callback) + local function request(method, params, callback, notify_reply_callback) validate { callback = { callback, 'f' }; + notify_reply_callback = { notify_reply_callback, 'f', true }; } message_index = message_index + 1 local message_id = message_index @@ -388,8 +392,15 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) method = method; params = params; } - if result and message_callbacks then - message_callbacks[message_id] = schedule_wrap(callback) + if result then + if message_callbacks then + message_callbacks[message_id] = schedule_wrap(callback) + else + return false + end + if notify_reply_callback and notify_reply_callbacks then + notify_reply_callbacks[message_id] = schedule_wrap(notify_reply_callback) + end return result, message_id else return false @@ -466,6 +477,16 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) -- We sent a number, so we expect a number. local result_id = tonumber(decoded.id) + -- Notify the user that a response was received for the request + local notify_reply_callback = notify_reply_callbacks and notify_reply_callbacks[result_id] + if notify_reply_callback then + validate { + notify_reply_callback = { notify_reply_callback, 'f' }; + } + notify_reply_callback(result_id) + notify_reply_callbacks[result_id] = nil + end + -- Do not surface RequestCancelled to users, it is RPC-internal. if decoded.error then local mute_error = false diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua index 7a0ac458f3..a5bf0efcb1 100644 --- a/runtime/lua/vim/lsp/util.lua +++ b/runtime/lua/vim/lsp/util.lua @@ -152,6 +152,7 @@ end --- Returns a zero-indexed column, since set_lines() does the conversion to --- 1-indexed local function get_line_byte_from_position(bufnr, position) + -- TODO handle offset_encoding -- LSP's line and characters are 0-indexed -- Vim's line and columns are 1-indexed local col = position.character @@ -165,7 +166,7 @@ local function get_line_byte_from_position(bufnr, position) local line = position.line local lines = api.nvim_buf_get_lines(bufnr, line, line + 1, false) if #lines > 0 then - local ok, result = pcall(vim.str_byteindex, lines[1], col) + local ok, result = pcall(vim.str_byteindex, lines[1], col, true) if ok then return result @@ -276,7 +277,8 @@ function M.apply_text_edits(text_edits, bufnr) -- Some LSP servers may return +1 range of the buffer content but nvim_buf_set_text can't accept it so we should fix it here. local has_eol_text_edit = false local max = vim.api.nvim_buf_line_count(bufnr) - local len = vim.str_utfindex(vim.api.nvim_buf_get_lines(bufnr, -2, -1, false)[1] or '') + -- TODO handle offset_encoding + local _, len = vim.str_utfindex(vim.api.nvim_buf_get_lines(bufnr, -2, -1, false)[1] or '') text_edits = vim.tbl_map(function(text_edit) if max <= text_edit.range.start.line then text_edit.range.start.line = max - 1 @@ -1720,7 +1722,9 @@ function M.symbols_to_items(symbols, bufnr) }) if symbol.children then for _, v in ipairs(_symbols_to_items(symbol.children, _items, _bufnr)) do - vim.list_extend(_items, v) + for _, s in ipairs(v) do + table.insert(_items, s) + end end end end @@ -1788,7 +1792,9 @@ local function make_position_param() if not line then return { line = 0; character = 0; } end - col = str_utfindex(line, col) + -- TODO handle offset_encoding + local _ + _, col = str_utfindex(line, col) return { line = row; character = col; } end @@ -1838,11 +1844,14 @@ function M.make_given_range_params(start_pos, end_pos) A[1] = A[1] - 1 B[1] = B[1] - 1 -- account for encoding. + -- TODO handle offset_encoding if A[2] > 0 then - A = {A[1], M.character_offset(0, A[1], A[2])} + local _, char = M.character_offset(0, A[1], A[2]) + A = {A[1], char} end if B[2] > 0 then - B = {B[1], M.character_offset(0, B[1], B[2])} + local _, char = M.character_offset(0, B[1], B[2]) + B = {B[1], char} end -- we need to offset the end character position otherwise we loose the last -- character of the selection, as LSP end position is exclusive |