mirror of
https://github.com/neovim/neovim.git
synced 2024-12-31 17:13:26 -07:00
9f035559de
* credit to @smolck and @theHamsta for their contributions in laying the groundwork for this feature and for their work on some of the helper utility functions and tests
1062 lines
35 KiB
Lua
1062 lines
35 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
|
|
--]=]
|
|
|
|
---@class lsp.ShowMessageRequestParams
|
|
---@field type lsp.MessageType
|
|
---@field message string
|
|
---@field actions nil|lsp.MessageActionItem[]
|
|
|
|
---@class lsp.MessageActionItem
|
|
---@field title string
|
|
|
|
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,
|
|
},
|
|
|
|
---@enum lsp.MessageType
|
|
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.
|
|
---@enum lsp.TextDocumentSaveReason
|
|
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 = {
|
|
semanticTokens = {
|
|
dynamicRegistration = false,
|
|
tokenTypes = {
|
|
'namespace',
|
|
'type',
|
|
'class',
|
|
'enum',
|
|
'interface',
|
|
'struct',
|
|
'typeParameter',
|
|
'parameter',
|
|
'variable',
|
|
'property',
|
|
'enumMember',
|
|
'event',
|
|
'function',
|
|
'method',
|
|
'macro',
|
|
'keyword',
|
|
'modifier',
|
|
'comment',
|
|
'string',
|
|
'number',
|
|
'regexp',
|
|
'operator',
|
|
'decorator',
|
|
},
|
|
tokenModifiers = {
|
|
'declaration',
|
|
'definition',
|
|
'readonly',
|
|
'static',
|
|
'deprecated',
|
|
'abstract',
|
|
'async',
|
|
'modification',
|
|
'documentation',
|
|
'defaultLibrary',
|
|
},
|
|
formats = { 'relative' },
|
|
requests = {
|
|
-- TODO(jdrouhard): Add support for this
|
|
range = false,
|
|
full = { delta = true },
|
|
},
|
|
|
|
overlappingTokenSupport = true,
|
|
-- TODO(jdrouhard): Add support for this
|
|
multilineTokenSupport = false,
|
|
serverCancelSupport = false,
|
|
augmentsSyntaxTokens = true,
|
|
},
|
|
synchronization = {
|
|
dynamicRegistration = false,
|
|
|
|
willSave = true,
|
|
willSaveWaitUntil = true,
|
|
|
|
-- Send textDocument/didSave after saving (BufWritePost)
|
|
didSave = true,
|
|
},
|
|
codeAction = {
|
|
dynamicRegistration = false,
|
|
|
|
codeActionLiteralSupport = {
|
|
codeActionKind = {
|
|
valueSet = (function()
|
|
local res = vim.tbl_values(constants.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,
|
|
},
|
|
configuration = true,
|
|
workspaceFolders = true,
|
|
applyEdit = true,
|
|
workspaceEdit = {
|
|
resourceOperations = { 'rename', 'create', 'delete' },
|
|
},
|
|
semanticTokens = {
|
|
refreshSupport = true,
|
|
},
|
|
},
|
|
callHierarchy = {
|
|
dynamicRegistration = false,
|
|
},
|
|
experimental = nil,
|
|
window = {
|
|
workDoneProgress = true,
|
|
showMessage = {
|
|
messageActionItem = {
|
|
additionalPropertiesSupport = false,
|
|
},
|
|
},
|
|
showDocument = {
|
|
support = true,
|
|
},
|
|
},
|
|
}
|
|
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, true),
|
|
text_document_will_save_wait_until = if_nil(textDocumentSync.willSaveWaitUntil, true),
|
|
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
|