diff options
Diffstat (limited to 'runtime/lua/vim/lsp.lua')
-rw-r--r-- | runtime/lua/vim/lsp.lua | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua index e5b6653346..17135e078c 100644 --- a/runtime/lua/vim/lsp.lua +++ b/runtime/lua/vim/lsp.lua @@ -101,7 +101,7 @@ local function for_each_buffer_client(bufnr, callback) for client_id in pairs(client_ids) do local client = active_clients[client_id] if client then - callback(client, client_id) + callback(client, client_id, bufnr) end end end @@ -154,7 +154,7 @@ local function validate_client_config(config) callbacks = { config.callbacks, "t", true }; capabilities = { config.capabilities, "t", true }; cmd_cwd = { config.cmd_cwd, optional_validator(is_dir), "directory" }; - cmd_env = { config.cmd_env, "f", true }; + cmd_env = { config.cmd_env, "t", true }; name = { config.name, 's', true }; on_error = { config.on_error, "f", true }; on_exit = { config.on_exit, "f", true }; @@ -198,6 +198,7 @@ local function text_document_did_open_handler(bufnr, client) } } client.notify('textDocument/didOpen', params) + util.buf_versions[bufnr] = params.textDocument.version end --- LSP client object. @@ -520,23 +521,24 @@ function lsp.start_client(config) end --- Checks capabilities before rpc.request-ing. - function client.request(method, params, callback) + function client.request(method, params, callback, bufnr) if not callback then callback = resolve_callback(method) or error("not found: request callback for client "..client.name) end - local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, callback) + local _ = log.debug() and log.debug(log_prefix, "client.request", client_id, method, params, callback, bufnr) -- TODO keep these checks or just let it go anyway? if (not client.resolved_capabilities.hover and method == 'textDocument/hover') or (not client.resolved_capabilities.signature_help and method == 'textDocument/signatureHelp') or (not client.resolved_capabilities.goto_definition and method == 'textDocument/definition') or (not client.resolved_capabilities.implementation and method == 'textDocument/implementation') + or (not client.resolved_capabilities.document_symbol and method == 'textDocument/documentSymbol') then - callback(unsupported_method(method), method, nil, client_id) + callback(unsupported_method(method), method, nil, client_id, bufnr) return end return rpc.request(method, params, function(err, result) - callback(err, method, result, client_id) + callback(err, method, result, client_id, bufnr) end) end @@ -613,6 +615,8 @@ do if tbl_isempty(all_buffer_active_clients[bufnr] or {}) then return end + + util.buf_versions[bufnr] = changedtick -- Lazy initialize these because clients may not even need them. local incremental_changes = once(function(client) local size_index = encoding_index[client.offset_encoding] @@ -719,6 +723,7 @@ function lsp.buf_attach_client(bufnr, client_id) client.notify('textDocument/didClose', params) end end) + util.buf_versions[bufnr] = nil all_buffer_active_clients[bufnr] = nil end; -- TODO if we know all of the potential clients ahead of time, then we @@ -836,8 +841,8 @@ function lsp.buf_request(bufnr, method, params, callback) callback = { callback, 'f', true }; } local client_request_ids = {} - for_each_buffer_client(bufnr, function(client, client_id) - local request_success, request_id = client.request(method, params, callback) + for_each_buffer_client(bufnr, function(client, client_id, resolved_bufnr) + local request_success, request_id = client.request(method, params, callback, resolved_bufnr) -- This could only fail if the client shut down in the time since we looked -- it up and we did the request, which should be rare. @@ -893,21 +898,22 @@ function lsp.buf_request_sync(bufnr, method, params, timeout_ms) return request_results end ---- Sends a notification to all servers attached to the buffer. ---- ---@param bufnr (optional, number) Buffer handle, or 0 for current ---@param method (string) LSP method name ---@param params (string) Parameters to send to the server ---- ---@returns nil +--- Send a notification to a server +-- @param bufnr [number] (optional): The number of the buffer +-- @param method [string]: Name of the request method +-- @param params [string]: Arguments to send to the server +-- +-- @returns true if any client returns true; false otherwise function lsp.buf_notify(bufnr, method, params) validate { bufnr = { bufnr, 'n', true }; method = { method, 's' }; } - for_each_buffer_client(bufnr, function(client, _client_id) - client.rpc.notify(method, params) + local resp = false + for_each_buffer_client(bufnr, function(client, _client_id, _resolved_bufnr) + if client.rpc.notify(method, params) then resp = true end end) + return resp end --- Implements 'omnifunc' compatible LSP completion. @@ -945,12 +951,14 @@ function lsp.omnifunc(findstart, base) -- Get the start position of the current keyword local textMatch = vim.fn.match(line_to_cursor, '\\k*$') + local prefix = line_to_cursor:sub(textMatch+1) + local params = util.make_position_params() local items = {} lsp.buf_request(bufnr, 'textDocument/completion', params, function(err, _, result) if err or not result then return end - local matches = util.text_document_completion_list_to_complete_items(result) + local matches = util.text_document_completion_list_to_complete_items(result, prefix) -- TODO(ashkan): is this the best way to do this? vim.list_extend(items, matches) vim.fn.complete(textMatch+1, items) |