chore(lsp): remove capabilities sanitization (#17814)

* feat(lsp)!: remove capabilities sanitization

Users must now access client.server_capabilities which matches the same
structure as the protocol.

https://microsoft.github.io/language-server-protocol/specification

client.resolved_capabilities is no longer used to gate capabilities, and
will be removed in a future release.

BREAKING CHANGE


Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>
This commit is contained in:
Michael Lingelbach
2022-04-30 02:22:30 -07:00
committed by GitHub
parent df09e03cf7
commit c618b314c6
8 changed files with 183 additions and 98 deletions

View File

@@ -653,9 +653,6 @@ client() *vim.lsp.client*
user to |vim.lsp.start_client()|. user to |vim.lsp.start_client()|.
• {server_capabilities} (table): Response from the server • {server_capabilities} (table): Response from the server
sent on `initialize` describing the server's capabilities. sent on `initialize` describing the server's capabilities.
• {resolved_capabilities} (table): Normalized table of
capabilities that we have detected based on the initialize
response from the server in `server_capabilities`.
client_is_stopped({client_id}) *vim.lsp.client_is_stopped()* client_is_stopped({client_id}) *vim.lsp.client_is_stopped()*
Checks whether a client is stopped. Checks whether a client is stopped.
@@ -1875,8 +1872,8 @@ request({method}, {params}, {callback}, {notify_reply_callback})
{params} (table) Parameters for the {params} (table) Parameters for the
invoked LSP method invoked LSP method
{callback} (function) Callback to invoke {callback} (function) Callback to invoke
{notify_reply_callback} (function) Callback to invoke as {notify_reply_callback} (function|nil) Callback to invoke
soon as a request is no longer as soon as a request is no longer
pending pending
Return: ~ Return: ~

View File

@@ -31,28 +31,28 @@ local lsp = {
rpc_response_error = lsp_rpc.rpc_response_error; rpc_response_error = lsp_rpc.rpc_response_error;
} }
-- maps request name to the required resolved_capability in the client. -- maps request name to the required server_capability in the client.
lsp._request_name_to_capability = { lsp._request_name_to_capability = {
['textDocument/hover'] = 'hover'; ['textDocument/hover'] = { 'hoverProvider' };
['textDocument/signatureHelp'] = 'signature_help'; ['textDocument/signatureHelp'] = { 'signatureHelpProvider' };
['textDocument/definition'] = 'goto_definition'; ['textDocument/definition'] = { 'definitionProvider' };
['textDocument/implementation'] = 'implementation'; ['textDocument/implementation'] = { 'implementationProvider' };
['textDocument/declaration'] = 'declaration'; ['textDocument/declaration'] = { 'declarationProvider' };
['textDocument/typeDefinition'] = 'type_definition'; ['textDocument/typeDefinition'] = { 'typeDefinitionProvider' };
['textDocument/documentSymbol'] = 'document_symbol'; ['textDocument/documentSymbol'] = { 'documentSymbolProvider' };
['textDocument/prepareCallHierarchy'] = 'call_hierarchy'; ['textDocument/prepareCallHierarchy'] = { 'callHierarchyProvider' };
['textDocument/rename'] = 'rename'; ['textDocument/rename'] = { 'renameProvider' };
['textDocument/prepareRename'] = 'rename'; ['textDocument/prepareRename'] = { 'renameProvider', 'prepareProvider'} ;
['textDocument/codeAction'] = 'code_action'; ['textDocument/codeAction'] = { 'codeActionProvider' };
['textDocument/codeLens'] = 'code_lens'; ['textDocument/codeLens'] = { 'codeLensProvider' };
['codeLens/resolve'] = 'code_lens_resolve'; ['codeLens/resolve'] = { 'codeLensProvider', 'resolveProvider' };
['workspace/executeCommand'] = 'execute_command'; ['workspace/executeCommand'] = { 'executeCommandProvider' };
['workspace/symbol'] = 'workspace_symbol'; ['workspace/symbol'] = { 'workspaceSymbolProvider' };
['textDocument/references'] = 'find_references'; ['textDocument/references'] = { 'referencesProvider' };
['textDocument/rangeFormatting'] = 'document_range_formatting'; ['textDocument/rangeFormatting'] = { 'documentRangeFormattingProvider' };
['textDocument/formatting'] = 'document_formatting'; ['textDocument/formatting'] = { 'documentFormattingProvider' };
['textDocument/completion'] = 'completion'; ['textDocument/completion'] = { 'completionProvider' };
['textDocument/documentHighlight'] = 'document_highlight'; ['textDocument/documentHighlight'] = { 'documentHighlightProvider' };
} }
-- TODO improve handling of scratch buffers with LSP attached. -- TODO improve handling of scratch buffers with LSP attached.
@@ -328,7 +328,7 @@ do
function changetracking.init(client, bufnr) function changetracking.init(client, bufnr)
local use_incremental_sync = ( local use_incremental_sync = (
if_nil(client.config.flags.allow_incremental_sync, true) if_nil(client.config.flags.allow_incremental_sync, true)
and client.resolved_capabilities.text_document_did_change == protocol.TextDocumentSyncKind.Incremental and vim.tbl_get(client.server_capabilities, "textDocumentSync", "change") == protocol.TextDocumentSyncKind.Incremental
) )
local state = state_by_client[client.id] local state = state_by_client[client.id]
if not state then if not state then
@@ -447,7 +447,7 @@ do
end) end)
local uri = vim.uri_from_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr)
return function(client) return function(client)
if client.resolved_capabilities.text_document_did_change == protocol.TextDocumentSyncKind.None then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "change") == protocol.TextDocumentSyncKind.None then
return return
end end
local state = state_by_client[client.id] local state = state_by_client[client.id]
@@ -526,7 +526,7 @@ end
---@param client Client object ---@param client Client object
local function text_document_did_open_handler(bufnr, client) local function text_document_did_open_handler(bufnr, client)
changetracking.init(client, bufnr) changetracking.init(client, bufnr)
if not client.resolved_capabilities.text_document_open_close then if not vim.tbl_get(client.server_capabilities, "textDocumentSync", "openClose") then
return return
end end
if not vim.api.nvim_buf_is_loaded(bufnr) then if not vim.api.nvim_buf_is_loaded(bufnr) then
@@ -632,10 +632,6 @@ end
--- ---
--- - {server_capabilities} (table): Response from the server sent on --- - {server_capabilities} (table): Response from the server sent on
--- `initialize` describing the server's capabilities. --- `initialize` describing the server's capabilities.
---
--- - {resolved_capabilities} (table): Normalized table of
--- capabilities that we have detected based on the initialize
--- response from the server in `server_capabilities`.
function lsp.client() function lsp.client()
error() error()
end end
@@ -884,6 +880,7 @@ function lsp.start_client(config)
messages = { name = name, messages = {}, progress = {}, status = {} }; messages = { name = name, messages = {}, progress = {}, status = {} };
} }
-- Store the uninitialized_clients for cleanup in case we exit before initialize finishes. -- Store the uninitialized_clients for cleanup in case we exit before initialize finishes.
uninitialized_clients[client_id] = client; uninitialized_clients[client_id] = client;
@@ -960,27 +957,48 @@ function lsp.start_client(config)
client.workspace_folders = workspace_folders client.workspace_folders = workspace_folders
-- TODO(mjlbach): Backwards compatibility, to be removed in 0.7 -- TODO(mjlbach): Backwards compatibility, to be removed in 0.7
client.workspaceFolders = client.workspace_folders client.workspaceFolders = client.workspace_folders
client.server_capabilities = assert(result.capabilities, "initialize result doesn't contain capabilities")
-- These are the cleaned up capabilities we use for dynamically deciding -- These are the cleaned up capabilities we use for dynamically deciding
-- when to send certain events to clients. -- when to send certain events to clients.
client.resolved_capabilities = protocol.resolve_capabilities(client.server_capabilities) client.server_capabilities = assert(result.capabilities, "initialize result doesn't contain capabilities")
client.server_capabilities = protocol.resolve_capabilities(client.server_capabilities)
-- Deprecation wrapper: this will be removed in 0.8
local mt = {}
mt.__index = function(table, key)
if key == 'resolved_capabilities' then
vim.notify_once("[LSP] Accessing client.resolved_capabilities is deprecated, " ..
"update your plugins or configuration to access client.server_capabilities instead." ..
"The new key/value pairs in server_capabilities directly match those " ..
"defined in the language server protocol", vim.log.levels.WARN)
table[key] = protocol._resolve_capabilities_compat(client.server_capabilities)
return table[key]
else
return table[key]
end
end
setmetatable(client, mt)
client.supports_method = function(method) client.supports_method = function(method)
local required_capability = lsp._request_name_to_capability[method] local required_capability = lsp._request_name_to_capability[method]
-- if we don't know about the method, assume that the client supports it. -- if we don't know about the method, assume that the client supports it.
if not required_capability then if not required_capability then
return true return true
end end
if vim.tbl_get(client.server_capabilities, unpack(required_capability)) then
return client.resolved_capabilities[required_capability] return true
else
return false
end
end end
if config.on_init then if config.on_init then
local status, err = pcall(config.on_init, client, result) local status, err = pcall(config.on_init, client, result)
if not status then if not status then
pcall(handlers.on_error, lsp.client_errors.ON_INIT_CALLBACK_ERROR, err) pcall(handlers.on_error, lsp.client_errors.ON_INIT_CALLBACK_ERROR, err)
end end
end end
local _ = log.debug() and log.debug(log_prefix, "server_capabilities", client.server_capabilities) local _ = log.info() and log.info(log_prefix, "server_capabilities", { server_capabilities = client.server_capabilities })
local _ = log.info() and log.info(log_prefix, "initialized", { resolved_capabilities = client.resolved_capabilities })
-- Only assign after initialized. -- Only assign after initialized.
active_clients[client_id] = client active_clients[client_id] = client
@@ -1191,9 +1209,9 @@ function lsp._text_document_did_save_handler(bufnr)
local uri = vim.uri_from_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr)
local text = once(buf_get_full_text) local text = once(buf_get_full_text)
for_each_buffer_client(bufnr, function(client, _client_id) for_each_buffer_client(bufnr, function(client, _client_id)
if client.resolved_capabilities.text_document_save then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "save") then
local included_text local included_text
if client.resolved_capabilities.text_document_save_include_text then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "save", "includeText") then
included_text = text(bufnr) included_text = text(bufnr)
end end
client.notify('textDocument/didSave', { client.notify('textDocument/didSave', {
@@ -1246,7 +1264,7 @@ function lsp.buf_attach_client(bufnr, client_id)
local params = { textDocument = { uri = uri; } } local params = { textDocument = { uri = uri; } }
for_each_buffer_client(bufnr, function(client, _) for_each_buffer_client(bufnr, function(client, _)
changetracking.reset_buf(client, bufnr) changetracking.reset_buf(client, bufnr)
if client.resolved_capabilities.text_document_open_close then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "openClose") then
client.notify('textDocument/didClose', params) client.notify('textDocument/didClose', params)
end end
text_document_did_open_handler(bufnr, client) text_document_did_open_handler(bufnr, client)
@@ -1256,7 +1274,7 @@ function lsp.buf_attach_client(bufnr, client_id)
local params = { textDocument = { uri = uri; } } local params = { textDocument = { uri = uri; } }
for_each_buffer_client(bufnr, function(client, _) for_each_buffer_client(bufnr, function(client, _)
changetracking.reset_buf(client, bufnr) changetracking.reset_buf(client, bufnr)
if client.resolved_capabilities.text_document_open_close then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "openClose") then
client.notify('textDocument/didClose', params) client.notify('textDocument/didClose', params)
end end
end) end)
@@ -1306,7 +1324,7 @@ function lsp.buf_detach_client(bufnr, client_id)
changetracking.reset_buf(client, bufnr) changetracking.reset_buf(client, bufnr)
if client.resolved_capabilities.text_document_open_close then if vim.tbl_get(client.server_capabilities, "textDocumentSync", "openClose") then
local uri = vim.uri_from_bufnr(bufnr) local uri = vim.uri_from_bufnr(bufnr)
local params = { textDocument = { uri = uri; } } local params = { textDocument = { uri = uri; } }
client.notify('textDocument/didClose', params) client.notify('textDocument/didClose', params)

View File

@@ -224,7 +224,7 @@ function M.formatting_seq_sync(options, timeout_ms, order)
-- loop through the clients and make synchronous formatting requests -- loop through the clients and make synchronous formatting requests
for _, client in pairs(clients) do for _, client in pairs(clients) do
if client.resolved_capabilities.document_formatting then if vim.tbl_get(client.server_capabilities, "documentFormattingProvider") then
local params = util.make_formatting_params(options) local params = util.make_formatting_params(options)
local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, vim.api.nvim_get_current_buf()) local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, vim.api.nvim_get_current_buf())
if result and result.result then if result and result.result then
@@ -545,8 +545,7 @@ local function on_code_action_results(results, ctx, options)
local action = action_tuple[2] local action = action_tuple[2]
if not action.edit if not action.edit
and client and client
and type(client.resolved_capabilities.code_action) == 'table' and vim.tbl_get(client.server_capabilities, "codeActionProvider", "resolveProvider") then
and client.resolved_capabilities.code_action.resolveProvider then
client.request('codeAction/resolve', action, function(err, resolved_action) client.request('codeAction/resolve', action, function(err, resolved_action)
if err then if err then

View File

@@ -379,7 +379,7 @@ function M.signature_help(_, result, ctx, config)
return return
end end
local client = vim.lsp.get_client_by_id(ctx.client_id) local client = vim.lsp.get_client_by_id(ctx.client_id)
local triggers = client.resolved_capabilities.signature_help_trigger_characters local triggers = vim.tbl_get(client.server_capabilities, "signatureHelpProvider", "triggerCharacters")
local ft = api.nvim_buf_get_option(ctx.bufnr, 'filetype') local ft = api.nvim_buf_get_option(ctx.bufnr, 'filetype')
local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers) local lines, hl = util.convert_signature_help_to_markdown_lines(result, ft, triggers)
lines = util.trim_empty_lines(lines) lines = util.trim_empty_lines(lines)

View File

@@ -1,7 +1,5 @@
-- Protocol for the Microsoft Language Server Protocol (mslsp) -- Protocol for the Microsoft Language Server Protocol (mslsp)
local if_nil = vim.F.if_nil
local protocol = {} local protocol = {}
--[=[ --[=[
@@ -777,10 +775,50 @@ function protocol.make_client_capabilities()
} }
end end
local if_nil = vim.F.if_nil
--- Creates a normalized object describing LSP server capabilities. --- Creates a normalized object describing LSP server capabilities.
---@param server_capabilities table Table of capabilities supported by the server ---@param server_capabilities table Table of capabilities supported by the server
---@return table Normalized table of capabilities ---@return table Normalized table of capabilities
function protocol.resolve_capabilities(server_capabilities) function protocol.resolve_capabilities(server_capabilities)
local TextDocumentSyncKind = protocol.TextDocumentSyncKind
local textDocumentSync = server_capabilities.textDocumentSync
if textDocumentSync == nil then
-- Defaults if omitted.
server_capabilities.textDocumentSync = {
openClose = false,
change = TextDocumentSyncKind.None,
willSave = false,
willSaveWaitUntil = false,
save = {
includeText = false,
}
}
elseif type(textDocumentSync) == 'number' then
-- Backwards compatibility
if not TextDocumentSyncKind[textDocumentSync] then
return nil, "Invalid server TextDocumentSyncKind for textDocumentSync"
end
server_capabilities.textDocumentSync = {
openClose = true,
change = textDocumentSync,
willSave = false,
willSaveWaitUntil = false,
save = {
includeText = false,
}
}
elseif type(textDocumentSync) ~= 'table' then
return nil, string.format("Invalid type for textDocumentSync: %q", type(textDocumentSync))
end
return server_capabilities
end
---@private
--- Creates a normalized object describing LSP server capabilities.
-- @deprecated access resolved_capabilities instead
---@param server_capabilities table Table of capabilities supported by the server
---@return table Normalized table of capabilities
function protocol._resolve_capabilities_compat(server_capabilities)
local general_properties = {} local general_properties = {}
local text_document_sync_properties local text_document_sync_properties
do do
@@ -931,12 +969,14 @@ function protocol.resolve_capabilities(server_capabilities)
error("The server sent invalid signatureHelpProvider") error("The server sent invalid signatureHelpProvider")
end end
return vim.tbl_extend("error" local capabilities = vim.tbl_extend("error"
, text_document_sync_properties , text_document_sync_properties
, signature_help_properties , signature_help_properties
, workspace_properties , workspace_properties
, general_properties , general_properties
) )
return capabilities
end end
return protocol return protocol

View File

@@ -385,7 +385,7 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
---@param method (string) The invoked LSP method ---@param method (string) The invoked LSP method
---@param params (table) Parameters for the invoked LSP method ---@param params (table) Parameters for the invoked LSP method
---@param callback (function) Callback to invoke ---@param callback (function) Callback to invoke
---@param notify_reply_callback (function) Callback to invoke as soon as a request is no longer pending ---@param notify_reply_callback (function|nil) 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 ---@returns (bool, number) `(true, message_id)` if request could be sent, `false` if not
local function request(method, params, callback, notify_reply_callback) local function request(method, params, callback, notify_reply_callback)
validate { validate {

View File

@@ -100,8 +100,12 @@ local tests = {}
function tests.basic_init() function tests.basic_init()
skeleton { skeleton {
on_init = function(_params) on_init = function(_)
return { capabilities = {} } return {
capabilities = {
textDocumentSync = protocol.TextDocumentSyncKind.None;
}
}
end; end;
body = function() body = function()
notify('test') notify('test')
@@ -132,8 +136,11 @@ function tests.prepare_rename_nil()
skeleton { skeleton {
on_init = function() on_init = function()
return { capabilities = { return { capabilities = {
renameProvider = true, renameProvider = {
} } prepareProvider = true
}
}
}
end; end;
body = function() body = function()
notify('start') notify('start')
@@ -149,8 +156,11 @@ function tests.prepare_rename_placeholder()
skeleton { skeleton {
on_init = function() on_init = function()
return { capabilities = { return { capabilities = {
renameProvider = true, renameProvider = {
} } prepareProvider = true
}
}
}
end; end;
body = function() body = function()
notify('start') notify('start')
@@ -170,8 +180,11 @@ function tests.prepare_rename_range()
skeleton { skeleton {
on_init = function() on_init = function()
return { capabilities = { return { capabilities = {
renameProvider = true, renameProvider = {
} } prepareProvider = true
}
}
}
end; end;
body = function() body = function()
notify('start') notify('start')
@@ -193,9 +206,13 @@ end
function tests.prepare_rename_error() function tests.prepare_rename_error()
skeleton { skeleton {
on_init = function() on_init = function()
return { capabilities = { return {
renameProvider = true, capabilities = {
} } renameProvider = {
prepareProvider = true
},
}
}
end; end;
body = function() body = function()
notify('start') notify('start')
@@ -219,6 +236,7 @@ function tests.basic_check_capabilities()
return { return {
capabilities = { capabilities = {
textDocumentSync = protocol.TextDocumentSyncKind.Full; textDocumentSync = protocol.TextDocumentSyncKind.Full;
codeLensProvider = false
} }
} }
end; end;
@@ -237,6 +255,7 @@ function tests.capabilities_for_client_supports_method()
textDocumentSync = protocol.TextDocumentSyncKind.Full; textDocumentSync = protocol.TextDocumentSyncKind.Full;
completionProvider = true; completionProvider = true;
hoverProvider = true; hoverProvider = true;
renameProvider = false;
definitionProvider = false; definitionProvider = false;
referencesProvider = false; referencesProvider = false;
codeLensProvider = { resolveProvider = true; }; codeLensProvider = { resolveProvider = true; };
@@ -544,7 +563,15 @@ function tests.basic_check_buffer_open_and_change_incremental()
assert_eq(params.capabilities, expected_capabilities) assert_eq(params.capabilities, expected_capabilities)
return { return {
capabilities = { capabilities = {
textDocumentSync = protocol.TextDocumentSyncKind.Incremental; textDocumentSync = {
openClose = true,
change = protocol.TextDocumentSyncKind.Incremental,
willSave = true,
willSaveWaitUntil = true,
save = {
includeText = true,
}
}
} }
} }
end; end;

View File

@@ -289,7 +289,7 @@ describe('LSP', function()
test_rpc_server { test_rpc_server {
test_name = "basic_init"; test_name = "basic_init";
on_init = function(client) on_init = function(client)
eq(0, client.resolved_capabilities().text_document_did_change) eq(0, client.server_capabilities().textDocumentSync.change)
client.request('shutdown') client.request('shutdown')
client.notify('exit') client.notify('exit')
client.stop() client.stop()
@@ -407,10 +407,9 @@ describe('LSP', function()
on_init = function(client) on_init = function(client)
client.stop() client.stop()
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_save) eq({includeText = false}, client.server_capabilities().textDocumentSync.save)
eq(false, client.resolved_capabilities().code_lens) eq(false, client.server_capabilities().codeLensProvider)
eq(false, client.resolved_capabilities().code_lens_resolve)
end; end;
on_exit = function(code, signal) on_exit = function(code, signal)
eq(0, code, "exit code", fake_lsp_logfile) eq(0, code, "exit code", fake_lsp_logfile)
@@ -430,14 +429,19 @@ describe('LSP', function()
test_name = "capabilities_for_client_supports_method"; test_name = "capabilities_for_client_supports_method";
on_init = function(client) on_init = function(client)
client.stop() client.stop()
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local expected_sync_capabilities = {
eq(full_kind, client.resolved_capabilities().text_document_did_change) change = 1,
eq(true, client.resolved_capabilities().completion) openClose = true,
eq(true, client.resolved_capabilities().hover) save = { includeText = false },
eq(false, client.resolved_capabilities().goto_definition) willSave = false,
eq(false, client.resolved_capabilities().rename) willSaveWaitUntil = false,
eq(true, client.resolved_capabilities().code_lens) }
eq(true, client.resolved_capabilities().code_lens_resolve) eq(expected_sync_capabilities, client.server_capabilities().textDocumentSync)
eq(true, client.server_capabilities().completionProvider)
eq(true, client.server_capabilities().hoverProvider)
eq(false, client.server_capabilities().definitionProvider)
eq(false, client.server_capabilities().renameProvider)
eq(true, client.server_capabilities().codeLensProvider.resolveProvider)
-- known methods for resolved capabilities -- known methods for resolved capabilities
eq(true, client.supports_method("textDocument/hover")) eq(true, client.supports_method("textDocument/hover"))
@@ -720,8 +724,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
client.notify('finish') client.notify('finish')
end; end;
on_exit = function(code, signal) on_exit = function(code, signal)
@@ -761,8 +765,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(not lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID), "Shouldn't attach twice") assert(not lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID), "Shouldn't attach twice")
]] ]]
@@ -804,8 +808,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -847,8 +851,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -896,8 +900,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local full_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(full_kind, client.resolved_capabilities().text_document_did_change) eq(full_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -947,8 +951,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental")
eq(sync_kind, client.resolved_capabilities().text_document_did_change) eq(sync_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -998,8 +1002,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental")
eq(sync_kind, client.resolved_capabilities().text_document_did_change) eq(sync_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -1047,8 +1051,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental") local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Incremental")
eq(sync_kind, client.resolved_capabilities().text_document_did_change) eq(sync_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -1091,8 +1095,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(sync_kind, client.resolved_capabilities().text_document_did_change) eq(sync_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -1142,8 +1146,8 @@ describe('LSP', function()
on_init = function(_client) on_init = function(_client)
client = _client client = _client
local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full") local sync_kind = exec_lua("return require'vim.lsp.protocol'.TextDocumentSyncKind.Full")
eq(sync_kind, client.resolved_capabilities().text_document_did_change) eq(sync_kind, client.server_capabilities().textDocumentSync.change)
eq(true, client.resolved_capabilities().text_document_open_close) eq(true, client.server_capabilities().textDocumentSync.openClose)
exec_lua [[ exec_lua [[
assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID)) assert(lsp.buf_attach_client(BUFFER, TEST_RPC_CLIENT_ID))
]] ]]
@@ -2583,7 +2587,7 @@ describe('LSP', function()
test_name = test.name; test_name = test.name;
on_init = function(_client) on_init = function(_client)
client = _client client = _client
eq(true, client.resolved_capabilities().rename) eq(true, client.server_capabilities().renameProvider.prepareProvider)
end; end;
on_setup = function() on_setup = function()
exec_lua([=[ exec_lua([=[