Files
neovim/runtime/lua/vim/lsp/protocol.lua
Michael Lingelbach c618b314c6 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>
2022-04-30 11:22:30 +02:00

984 lines
34 KiB
Lua

-- Protocol for the Microsoft Language Server Protocol (mslsp)
local protocol = {}
--[=[
---@private
--- Useful for interfacing with:
--- https://github.com/microsoft/language-server-protocol/raw/gh-pages/_specifications/specification-3-14.md
function transform_schema_comments()
nvim.command [[silent! '<,'>g/\/\*\*\|\*\/\|^$/d]]
nvim.command [[silent! '<,'>s/^\(\s*\) \* \=\(.*\)/\1--\2/]]
end
---@private
function transform_schema_to_table()
transform_schema_comments()
nvim.command [[silent! '<,'>s/: \S\+//]]
nvim.command [[silent! '<,'>s/export const //]]
nvim.command [[silent! '<,'>s/export namespace \(\S*\)\s*{/protocol.\1 = {/]]
nvim.command [[silent! '<,'>s/namespace \(\S*\)\s*{/protocol.\1 = {/]]
end
--]=]
local constants = {
DiagnosticSeverity = {
-- Reports an error.
Error = 1;
-- Reports a warning.
Warning = 2;
-- Reports an information.
Information = 3;
-- Reports a hint.
Hint = 4;
};
DiagnosticTag = {
-- Unused or unnecessary code
Unnecessary = 1;
-- Deprecated or obsolete code
Deprecated = 2;
};
MessageType = {
-- An error message.
Error = 1;
-- A warning message.
Warning = 2;
-- An information message.
Info = 3;
-- A log message.
Log = 4;
};
-- The file event type.
FileChangeType = {
-- The file got created.
Created = 1;
-- The file got changed.
Changed = 2;
-- The file got deleted.
Deleted = 3;
};
-- The kind of a completion entry.
CompletionItemKind = {
Text = 1;
Method = 2;
Function = 3;
Constructor = 4;
Field = 5;
Variable = 6;
Class = 7;
Interface = 8;
Module = 9;
Property = 10;
Unit = 11;
Value = 12;
Enum = 13;
Keyword = 14;
Snippet = 15;
Color = 16;
File = 17;
Reference = 18;
Folder = 19;
EnumMember = 20;
Constant = 21;
Struct = 22;
Event = 23;
Operator = 24;
TypeParameter = 25;
};
-- How a completion was triggered
CompletionTriggerKind = {
-- Completion was triggered by typing an identifier (24x7 code
-- complete), manual invocation (e.g Ctrl+Space) or via API.
Invoked = 1;
-- Completion was triggered by a trigger character specified by
-- the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
TriggerCharacter = 2;
-- Completion was re-triggered as the current completion list is incomplete.
TriggerForIncompleteCompletions = 3;
};
-- A document highlight kind.
DocumentHighlightKind = {
-- A textual occurrence.
Text = 1;
-- Read-access of a symbol, like reading a variable.
Read = 2;
-- Write-access of a symbol, like writing to a variable.
Write = 3;
};
-- A symbol kind.
SymbolKind = {
File = 1;
Module = 2;
Namespace = 3;
Package = 4;
Class = 5;
Method = 6;
Property = 7;
Field = 8;
Constructor = 9;
Enum = 10;
Interface = 11;
Function = 12;
Variable = 13;
Constant = 14;
String = 15;
Number = 16;
Boolean = 17;
Array = 18;
Object = 19;
Key = 20;
Null = 21;
EnumMember = 22;
Struct = 23;
Event = 24;
Operator = 25;
TypeParameter = 26;
};
-- Represents reasons why a text document is saved.
TextDocumentSaveReason = {
-- Manually triggered, e.g. by the user pressing save, by starting debugging,
-- or by an API call.
Manual = 1;
-- Automatic after a delay.
AfterDelay = 2;
-- When the editor lost focus.
FocusOut = 3;
};
ErrorCodes = {
-- Defined by JSON RPC
ParseError = -32700;
InvalidRequest = -32600;
MethodNotFound = -32601;
InvalidParams = -32602;
InternalError = -32603;
serverErrorStart = -32099;
serverErrorEnd = -32000;
ServerNotInitialized = -32002;
UnknownErrorCode = -32001;
-- Defined by the protocol.
RequestCancelled = -32800;
ContentModified = -32801;
};
-- Describes the content type that a client supports in various
-- result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
--
-- Please note that `MarkupKinds` must not start with a `$`. This kinds
-- are reserved for internal usage.
MarkupKind = {
-- Plain text is supported as a content format
PlainText = 'plaintext';
-- Markdown is supported as a content format
Markdown = 'markdown';
};
ResourceOperationKind = {
-- Supports creating new files and folders.
Create = 'create';
-- Supports renaming existing files and folders.
Rename = 'rename';
-- Supports deleting existing files and folders.
Delete = 'delete';
};
FailureHandlingKind = {
-- Applying the workspace change is simply aborted if one of the changes provided
-- fails. All operations executed before the failing operation stay executed.
Abort = 'abort';
-- All operations are executed transactionally. That means they either all
-- succeed or no changes at all are applied to the workspace.
Transactional = 'transactional';
-- If the workspace edit contains only textual file changes they are executed transactionally.
-- If resource changes (create, rename or delete file) are part of the change the failure
-- handling strategy is abort.
TextOnlyTransactional = 'textOnlyTransactional';
-- The client tries to undo the operations already executed. But there is no
-- guarantee that this succeeds.
Undo = 'undo';
};
-- Known error codes for an `InitializeError`;
InitializeError = {
-- If the protocol version provided by the client can't be handled by the server.
-- @deprecated This initialize error got replaced by client capabilities. There is
-- no version handshake in version 3.0x
unknownProtocolVersion = 1;
};
-- Defines how the host (editor) should sync document changes to the language server.
TextDocumentSyncKind = {
-- Documents should not be synced at all.
None = 0;
-- Documents are synced by always sending the full content
-- of the document.
Full = 1;
-- Documents are synced by sending the full content on open.
-- After that only incremental updates to the document are
-- send.
Incremental = 2;
};
WatchKind = {
-- Interested in create events.
Create = 1;
-- Interested in change events
Change = 2;
-- Interested in delete events
Delete = 4;
};
-- Defines whether the insert text in a completion item should be interpreted as
-- plain text or a snippet.
InsertTextFormat = {
-- The primary text to be inserted is treated as a plain string.
PlainText = 1;
-- The primary text to be inserted is treated as a snippet.
--
-- A snippet can define tab stops and placeholders with `$1`, `$2`
-- and `${3:foo};`. `$0` defines the final tab stop, it defaults to
-- the end of the snippet. Placeholders with equal identifiers are linked,
-- that is typing in one will update others too.
Snippet = 2;
};
-- A set of predefined code action kinds
CodeActionKind = {
-- Empty kind.
Empty = '';
-- Base kind for quickfix actions
QuickFix = 'quickfix';
-- Base kind for refactoring actions
Refactor = 'refactor';
-- Base kind for refactoring extraction actions
--
-- Example extract actions:
--
-- - Extract method
-- - Extract function
-- - Extract variable
-- - Extract interface from class
-- - ...
RefactorExtract = 'refactor.extract';
-- Base kind for refactoring inline actions
--
-- Example inline actions:
--
-- - Inline function
-- - Inline variable
-- - Inline constant
-- - ...
RefactorInline = 'refactor.inline';
-- Base kind for refactoring rewrite actions
--
-- Example rewrite actions:
--
-- - Convert JavaScript function to class
-- - Add or remove parameter
-- - Encapsulate field
-- - Make method static
-- - Move method to base class
-- - ...
RefactorRewrite = 'refactor.rewrite';
-- Base kind for source actions
--
-- Source code actions apply to the entire file.
Source = 'source';
-- Base kind for an organize imports source action
SourceOrganizeImports = 'source.organizeImports';
};
}
for k, v in pairs(constants) do
local tbl = vim.deepcopy(v)
vim.tbl_add_reverse_lookup(tbl)
protocol[k] = tbl
end
--[=[
--Text document specific client capabilities.
export interface TextDocumentClientCapabilities {
synchronization?: {
--Whether text document synchronization supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports sending will save notifications.
willSave?: boolean;
--The client supports sending a will save request and
--waits for a response providing text edits which will
--be applied to the document before it is saved.
willSaveWaitUntil?: boolean;
--The client supports did save notifications.
didSave?: boolean;
}
--Capabilities specific to the `textDocument/completion`
completion?: {
--Whether completion supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports the following `CompletionItem` specific
--capabilities.
completionItem?: {
--The client supports snippets as insert text.
--
--A snippet can define tab stops and placeholders with `$1`, `$2`
--and `${3:foo}`. `$0` defines the final tab stop, it defaults to
--the end of the snippet. Placeholders with equal identifiers are linked,
--that is typing in one will update others too.
snippetSupport?: boolean;
--The client supports commit characters on a completion item.
commitCharactersSupport?: boolean
--The client supports the following content formats for the documentation
--property. The order describes the preferred format of the client.
documentationFormat?: MarkupKind[];
--The client supports the deprecated property on a completion item.
deprecatedSupport?: boolean;
--The client supports the preselect property on a completion item.
preselectSupport?: boolean;
}
completionItemKind?: {
--The completion item kind values the client supports. When this
--property exists the client also guarantees that it will
--handle values outside its set gracefully and falls back
--to a default value when unknown.
--
--If this property is not present the client only supports
--the completion items kinds from `Text` to `Reference` as defined in
--the initial version of the protocol.
valueSet?: CompletionItemKind[];
},
--The client supports to send additional context information for a
--`textDocument/completion` request.
contextSupport?: boolean;
};
--Capabilities specific to the `textDocument/hover`
hover?: {
--Whether hover supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports the follow content formats for the content
--property. The order describes the preferred format of the client.
contentFormat?: MarkupKind[];
};
--Capabilities specific to the `textDocument/signatureHelp`
signatureHelp?: {
--Whether signature help supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports the following `SignatureInformation`
--specific properties.
signatureInformation?: {
--The client supports the follow content formats for the documentation
--property. The order describes the preferred format of the client.
documentationFormat?: MarkupKind[];
--Client capabilities specific to parameter information.
parameterInformation?: {
--The client supports processing label offsets instead of a
--simple label string.
--
--Since 3.14.0
labelOffsetSupport?: boolean;
}
};
};
--Capabilities specific to the `textDocument/references`
references?: {
--Whether references supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/documentHighlight`
documentHighlight?: {
--Whether document highlight supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/documentSymbol`
documentSymbol?: {
--Whether document symbol supports dynamic registration.
dynamicRegistration?: boolean;
--Specific capabilities for the `SymbolKind`.
symbolKind?: {
--The symbol kind values the client supports. When this
--property exists the client also guarantees that it will
--handle values outside its set gracefully and falls back
--to a default value when unknown.
--
--If this property is not present the client only supports
--the symbol kinds from `File` to `Array` as defined in
--the initial version of the protocol.
valueSet?: SymbolKind[];
}
--The client supports hierarchical document symbols.
hierarchicalDocumentSymbolSupport?: boolean;
};
--Capabilities specific to the `textDocument/formatting`
formatting?: {
--Whether formatting supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/rangeFormatting`
rangeFormatting?: {
--Whether range formatting supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/onTypeFormatting`
onTypeFormatting?: {
--Whether on type formatting supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/declaration`
declaration?: {
--Whether declaration supports dynamic registration. If this is set to `true`
--the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
--return value for the corresponding server capability as well.
dynamicRegistration?: boolean;
--The client supports additional metadata in the form of declaration links.
--
--Since 3.14.0
linkSupport?: boolean;
};
--Capabilities specific to the `textDocument/definition`.
--
--Since 3.14.0
definition?: {
--Whether definition supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports additional metadata in the form of definition links.
linkSupport?: boolean;
};
--Capabilities specific to the `textDocument/typeDefinition`
--
--Since 3.6.0
typeDefinition?: {
--Whether typeDefinition supports dynamic registration. If this is set to `true`
--the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
--return value for the corresponding server capability as well.
dynamicRegistration?: boolean;
--The client supports additional metadata in the form of definition links.
--
--Since 3.14.0
linkSupport?: boolean;
};
--Capabilities specific to the `textDocument/implementation`.
--
--Since 3.6.0
implementation?: {
--Whether implementation supports dynamic registration. If this is set to `true`
--the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
--return value for the corresponding server capability as well.
dynamicRegistration?: boolean;
--The client supports additional metadata in the form of definition links.
--
--Since 3.14.0
linkSupport?: boolean;
};
--Capabilities specific to the `textDocument/codeAction`
codeAction?: {
--Whether code action supports dynamic registration.
dynamicRegistration?: boolean;
--The client support code action literals as a valid
--response of the `textDocument/codeAction` request.
--
--Since 3.8.0
codeActionLiteralSupport?: {
--The code action kind is support with the following value
--set.
codeActionKind: {
--The code action kind values the client supports. When this
--property exists the client also guarantees that it will
--handle values outside its set gracefully and falls back
--to a default value when unknown.
valueSet: CodeActionKind[];
};
};
};
--Capabilities specific to the `textDocument/codeLens`
codeLens?: {
--Whether code lens supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/documentLink`
documentLink?: {
--Whether document link supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `textDocument/documentColor` and the
--`textDocument/colorPresentation` request.
--
--Since 3.6.0
colorProvider?: {
--Whether colorProvider supports dynamic registration. If this is set to `true`
--the client supports the new `(ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
--return value for the corresponding server capability as well.
dynamicRegistration?: boolean;
}
--Capabilities specific to the `textDocument/rename`
rename?: {
--Whether rename supports dynamic registration.
dynamicRegistration?: boolean;
--The client supports testing for validity of rename operations
--before execution.
prepareSupport?: boolean;
};
--Capabilities specific to `textDocument/publishDiagnostics`.
publishDiagnostics?: {
--Whether the clients accepts diagnostics with related information.
relatedInformation?: boolean;
--Client supports the tag property to provide meta data about a diagnostic.
--Clients supporting tags have to handle unknown tags gracefully.
--Since 3.15.0
tagSupport?: {
--The tags supported by this client
valueSet: DiagnosticTag[];
};
};
--Capabilities specific to `textDocument/foldingRange` requests.
--
--Since 3.10.0
foldingRange?: {
--Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
--the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
--return value for the corresponding server capability as well.
dynamicRegistration?: boolean;
--The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
--hint, servers are free to follow the limit.
rangeLimit?: number;
--If set, the client signals that it only supports folding complete lines. If set, client will
--ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
lineFoldingOnly?: boolean;
};
}
--]=]
--[=[
--Workspace specific client capabilities.
export interface WorkspaceClientCapabilities {
--The client supports applying batch edits to the workspace by supporting
--the request 'workspace/applyEdit'
applyEdit?: boolean;
--Capabilities specific to `WorkspaceEdit`s
workspaceEdit?: {
--The client supports versioned document changes in `WorkspaceEdit`s
documentChanges?: boolean;
--The resource operations the client supports. Clients should at least
--support 'create', 'rename' and 'delete' files and folders.
resourceOperations?: ResourceOperationKind[];
--The failure handling strategy of a client if applying the workspace edit
--fails.
failureHandling?: FailureHandlingKind;
};
--Capabilities specific to the `workspace/didChangeConfiguration` notification.
didChangeConfiguration?: {
--Did change configuration notification supports dynamic registration.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
didChangeWatchedFiles?: {
--Did change watched files notification supports dynamic registration. Please note
--that the current protocol doesn't support static configuration for file changes
--from the server side.
dynamicRegistration?: boolean;
};
--Capabilities specific to the `workspace/symbol` request.
symbol?: {
--Symbol request supports dynamic registration.
dynamicRegistration?: boolean;
--Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
symbolKind?: {
--The symbol kind values the client supports. When this
--property exists the client also guarantees that it will
--handle values outside its set gracefully and falls back
--to a default value when unknown.
--
--If this property is not present the client only supports
--the symbol kinds from `File` to `Array` as defined in
--the initial version of the protocol.
valueSet?: SymbolKind[];
}
};
--Capabilities specific to the `workspace/executeCommand` request.
executeCommand?: {
--Execute command supports dynamic registration.
dynamicRegistration?: boolean;
};
--The client has support for workspace folders.
--
--Since 3.6.0
workspaceFolders?: boolean;
--The client supports `workspace/configuration` requests.
--
--Since 3.6.0
configuration?: boolean;
}
--]=]
--- Gets a new ClientCapabilities object describing the LSP client
--- capabilities.
function protocol.make_client_capabilities()
return {
textDocument = {
synchronization = {
dynamicRegistration = false;
-- TODO(ashkan) Send textDocument/willSave before saving (BufWritePre)
willSave = false;
-- TODO(ashkan) Implement textDocument/willSaveWaitUntil
willSaveWaitUntil = false;
-- Send textDocument/didSave after saving (BufWritePost)
didSave = true;
};
codeAction = {
dynamicRegistration = false;
codeActionLiteralSupport = {
codeActionKind = {
valueSet = (function()
local res = vim.tbl_values(protocol.CodeActionKind)
table.sort(res)
return res
end)();
};
};
isPreferredSupport = true;
dataSupport = true;
resolveSupport = {
properties = { 'edit', }
};
};
completion = {
dynamicRegistration = false;
completionItem = {
-- Until we can actually expand snippet, move cursor and allow for true snippet experience,
-- this should be disabled out of the box.
-- However, users can turn this back on if they have a snippet plugin.
snippetSupport = false;
commitCharactersSupport = false;
preselectSupport = false;
deprecatedSupport = false;
documentationFormat = { protocol.MarkupKind.Markdown; protocol.MarkupKind.PlainText };
};
completionItemKind = {
valueSet = (function()
local res = {}
for k in ipairs(protocol.CompletionItemKind) do
if type(k) == 'number' then table.insert(res, k) end
end
return res
end)();
};
-- TODO(tjdevries): Implement this
contextSupport = false;
};
declaration = {
linkSupport = true;
};
definition = {
linkSupport = true;
};
implementation = {
linkSupport = true;
};
typeDefinition = {
linkSupport = true;
};
hover = {
dynamicRegistration = false;
contentFormat = { protocol.MarkupKind.Markdown; protocol.MarkupKind.PlainText };
};
signatureHelp = {
dynamicRegistration = false;
signatureInformation = {
activeParameterSupport = true;
documentationFormat = { protocol.MarkupKind.Markdown; protocol.MarkupKind.PlainText };
parameterInformation = {
labelOffsetSupport = true;
};
};
};
references = {
dynamicRegistration = false;
};
documentHighlight = {
dynamicRegistration = false
};
documentSymbol = {
dynamicRegistration = false;
symbolKind = {
valueSet = (function()
local res = {}
for k in ipairs(protocol.SymbolKind) do
if type(k) == 'number' then table.insert(res, k) end
end
return res
end)();
};
hierarchicalDocumentSymbolSupport = true;
};
rename = {
dynamicRegistration = false;
prepareSupport = true;
};
publishDiagnostics = {
relatedInformation = true;
tagSupport = {
valueSet = (function()
local res = {}
for k in ipairs(protocol.DiagnosticTag) do
if type(k) == 'number' then table.insert(res, k) end
end
return res
end)();
};
};
};
workspace = {
symbol = {
dynamicRegistration = false;
symbolKind = {
valueSet = (function()
local res = {}
for k in ipairs(protocol.SymbolKind) do
if type(k) == 'number' then table.insert(res, k) end
end
return res
end)();
};
hierarchicalWorkspaceSymbolSupport = true;
};
workspaceFolders = true;
applyEdit = true;
workspaceEdit = {
resourceOperations = {'rename', 'create', 'delete',},
};
};
callHierarchy = {
dynamicRegistration = false;
};
experimental = nil;
window = {
workDoneProgress = true;
showMessage = {
messageActionItem = {
additionalPropertiesSupport = false;
};
};
showDocument = {
support = false;
};
};
}
end
local if_nil = vim.F.if_nil
--- Creates a normalized object describing LSP server capabilities.
---@param server_capabilities table Table of capabilities supported by the server
---@return table Normalized table of 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 text_document_sync_properties
do
local TextDocumentSyncKind = protocol.TextDocumentSyncKind
local textDocumentSync = server_capabilities.textDocumentSync
if textDocumentSync == nil then
-- Defaults if omitted.
text_document_sync_properties = {
text_document_open_close = false;
text_document_did_change = TextDocumentSyncKind.None;
-- text_document_did_change = false;
text_document_will_save = false;
text_document_will_save_wait_until = false;
text_document_save = false;
text_document_save_include_text = false;
}
elseif type(textDocumentSync) == 'number' then
-- Backwards compatibility
if not TextDocumentSyncKind[textDocumentSync] then
return nil, "Invalid server TextDocumentSyncKind for textDocumentSync"
end
text_document_sync_properties = {
text_document_open_close = true;
text_document_did_change = textDocumentSync;
text_document_will_save = false;
text_document_will_save_wait_until = false;
text_document_save = true;
text_document_save_include_text = false;
}
elseif type(textDocumentSync) == 'table' then
text_document_sync_properties = {
text_document_open_close = if_nil(textDocumentSync.openClose, false);
text_document_did_change = if_nil(textDocumentSync.change, TextDocumentSyncKind.None);
text_document_will_save = if_nil(textDocumentSync.willSave, false);
text_document_will_save_wait_until = if_nil(textDocumentSync.willSaveWaitUntil, false);
text_document_save = if_nil(textDocumentSync.save, false);
text_document_save_include_text = if_nil(type(textDocumentSync.save) == 'table'
and textDocumentSync.save.includeText, false);
}
else
return nil, string.format("Invalid type for textDocumentSync: %q", type(textDocumentSync))
end
end
general_properties.completion = server_capabilities.completionProvider ~= nil
general_properties.hover = server_capabilities.hoverProvider or false
general_properties.goto_definition = server_capabilities.definitionProvider or false
general_properties.find_references = server_capabilities.referencesProvider or false
general_properties.document_highlight = server_capabilities.documentHighlightProvider or false
general_properties.document_symbol = server_capabilities.documentSymbolProvider or false
general_properties.workspace_symbol = server_capabilities.workspaceSymbolProvider or false
general_properties.document_formatting = server_capabilities.documentFormattingProvider or false
general_properties.document_range_formatting = server_capabilities.documentRangeFormattingProvider or false
general_properties.call_hierarchy = server_capabilities.callHierarchyProvider or false
general_properties.execute_command = server_capabilities.executeCommandProvider ~= nil
if server_capabilities.renameProvider == nil then
general_properties.rename = false
elseif type(server_capabilities.renameProvider) == 'boolean' then
general_properties.rename = server_capabilities.renameProvider
else
general_properties.rename = true
end
if server_capabilities.codeLensProvider == nil then
general_properties.code_lens = false
general_properties.code_lens_resolve = false
elseif type(server_capabilities.codeLensProvider) == 'table' then
general_properties.code_lens = true
general_properties.code_lens_resolve = server_capabilities.codeLensProvider.resolveProvider or false
else
error("The server sent invalid codeLensProvider")
end
if server_capabilities.codeActionProvider == nil then
general_properties.code_action = false
elseif type(server_capabilities.codeActionProvider) == 'boolean'
or type(server_capabilities.codeActionProvider) == 'table' then
general_properties.code_action = server_capabilities.codeActionProvider
else
error("The server sent invalid codeActionProvider")
end
if server_capabilities.declarationProvider == nil then
general_properties.declaration = false
elseif type(server_capabilities.declarationProvider) == 'boolean' then
general_properties.declaration = server_capabilities.declarationProvider
elseif type(server_capabilities.declarationProvider) == 'table' then
general_properties.declaration = server_capabilities.declarationProvider
else
error("The server sent invalid declarationProvider")
end
if server_capabilities.typeDefinitionProvider == nil then
general_properties.type_definition = false
elseif type(server_capabilities.typeDefinitionProvider) == 'boolean' then
general_properties.type_definition = server_capabilities.typeDefinitionProvider
elseif type(server_capabilities.typeDefinitionProvider) == 'table' then
general_properties.type_definition = server_capabilities.typeDefinitionProvider
else
error("The server sent invalid typeDefinitionProvider")
end
if server_capabilities.implementationProvider == nil then
general_properties.implementation = false
elseif type(server_capabilities.implementationProvider) == 'boolean' then
general_properties.implementation = server_capabilities.implementationProvider
elseif type(server_capabilities.implementationProvider) == 'table' then
general_properties.implementation = server_capabilities.implementationProvider
else
error("The server sent invalid implementationProvider")
end
local workspace = server_capabilities.workspace
local workspace_properties = {}
if workspace == nil or workspace.workspaceFolders == nil then
-- Defaults if omitted.
workspace_properties = {
workspace_folder_properties = {
supported = false;
changeNotifications=false;
}
}
elseif type(workspace.workspaceFolders) == 'table' then
workspace_properties = {
workspace_folder_properties = {
supported = if_nil(workspace.workspaceFolders.supported, false);
changeNotifications = if_nil(workspace.workspaceFolders.changeNotifications, false);
}
}
else
error("The server sent invalid workspace")
end
local signature_help_properties
if server_capabilities.signatureHelpProvider == nil then
signature_help_properties = {
signature_help = false;
signature_help_trigger_characters = {};
}
elseif type(server_capabilities.signatureHelpProvider) == 'table' then
signature_help_properties = {
signature_help = true;
-- The characters that trigger signature help automatically.
signature_help_trigger_characters = server_capabilities.signatureHelpProvider.triggerCharacters or {};
}
else
error("The server sent invalid signatureHelpProvider")
end
local capabilities = vim.tbl_extend("error"
, text_document_sync_properties
, signature_help_properties
, workspace_properties
, general_properties
)
return capabilities
end
return protocol
-- vim:sw=2 ts=2 et