mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	 ec4731d982
			
		
	
	ec4731d982
	
	
	
		
			
			Closes https://github.com/neovim/neovim/issues/15339 and https://github.com/neovim/neovim/issues/15828
		
			
				
	
	
		
			1083 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			1083 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- Protocol for the Microsoft Language Server Protocol (mslsp)
 | ||
| 
 | ||
| local if_nil = vim.F.if_nil
 | ||
| 
 | ||
| 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)();
 | ||
|           };
 | ||
|         };
 | ||
|         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
 | ||
| 
 | ||
| --[=[
 | ||
| export interface DocumentFilter {
 | ||
|   --A language id, like `typescript`.
 | ||
|   language?: string;
 | ||
|   --A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
 | ||
|   scheme?: string;
 | ||
|   --A glob pattern, like `*.{ts,js}`.
 | ||
|   --
 | ||
|   --Glob patterns can have the following syntax:
 | ||
|   --- `*` to match one or more characters in a path segment
 | ||
|   --- `?` to match on one character in a path segment
 | ||
|   --- `**` to match any number of path segments, including none
 | ||
|   --- `{}` to group conditions (e.g. `**/*.{ts,js}` matches all TypeScript and JavaScript files)
 | ||
|   --- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
 | ||
|   --- `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
 | ||
|   pattern?: string;
 | ||
| }
 | ||
| --]=]
 | ||
| 
 | ||
| --[[
 | ||
| --Static registration options to be returned in the initialize request.
 | ||
| interface StaticRegistrationOptions {
 | ||
|   --The id used to register the request. The id can be used to deregister
 | ||
|   --the request again. See also Registration#id.
 | ||
|   id?: string;
 | ||
| }
 | ||
| 
 | ||
| export interface DocumentFilter {
 | ||
|   --A language id, like `typescript`.
 | ||
|   language?: string;
 | ||
|   --A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
 | ||
|   scheme?: string;
 | ||
|   --A glob pattern, like `*.{ts,js}`.
 | ||
|   --
 | ||
|   --Glob patterns can have the following syntax:
 | ||
|   --- `*` to match one or more characters in a path segment
 | ||
|   --- `?` to match on one character in a path segment
 | ||
|   --- `**` to match any number of path segments, including none
 | ||
|   --- `{}` to group conditions (e.g. `**/*.{ts,js}` matches all TypeScript and JavaScript files)
 | ||
|   --- `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
 | ||
|   --- `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
 | ||
|   pattern?: string;
 | ||
| }
 | ||
| export type DocumentSelector = DocumentFilter[];
 | ||
| export interface TextDocumentRegistrationOptions {
 | ||
|   --A document selector to identify the scope of the registration. If set to null
 | ||
|   --the document selector provided on the client side will be used.
 | ||
|   documentSelector: DocumentSelector | null;
 | ||
| }
 | ||
| 
 | ||
| --Code Action options.
 | ||
| export interface CodeActionOptions {
 | ||
|   --CodeActionKinds that this server may return.
 | ||
|   --
 | ||
|   --The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server
 | ||
|   --may list out every specific kind they provide.
 | ||
|   codeActionKinds?: CodeActionKind[];
 | ||
| }
 | ||
| 
 | ||
| interface ServerCapabilities {
 | ||
|   --Defines how text documents are synced. Is either a detailed structure defining each notification or
 | ||
|   --for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
 | ||
|   textDocumentSync?: TextDocumentSyncOptions | number;
 | ||
|   --The server provides hover support.
 | ||
|   hoverProvider?: boolean;
 | ||
|   --The server provides completion support.
 | ||
|   completionProvider?: CompletionOptions;
 | ||
|   --The server provides signature help support.
 | ||
|   signatureHelpProvider?: SignatureHelpOptions;
 | ||
|   --The server provides goto definition support.
 | ||
|   definitionProvider?: boolean;
 | ||
|   --The server provides Goto Type Definition support.
 | ||
|   --
 | ||
|   --Since 3.6.0
 | ||
|   typeDefinitionProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
 | ||
|   --The server provides Goto Implementation support.
 | ||
|   --
 | ||
|   --Since 3.6.0
 | ||
|   implementationProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
 | ||
|   --The server provides find references support.
 | ||
|   referencesProvider?: boolean;
 | ||
|   --The server provides document highlight support.
 | ||
|   documentHighlightProvider?: boolean;
 | ||
|   --The server provides document symbol support.
 | ||
|   documentSymbolProvider?: boolean;
 | ||
|   --The server provides workspace symbol support.
 | ||
|   workspaceSymbolProvider?: boolean;
 | ||
|   --The server provides code actions. The `CodeActionOptions` return type is only
 | ||
|   --valid if the client signals code action literal support via the property
 | ||
|   --`textDocument.codeAction.codeActionLiteralSupport`.
 | ||
|   codeActionProvider?: boolean | CodeActionOptions;
 | ||
|   --The server provides code lens.
 | ||
|   codeLensProvider?: CodeLensOptions;
 | ||
|   --The server provides document formatting.
 | ||
|   documentFormattingProvider?: boolean;
 | ||
|   --The server provides document range formatting.
 | ||
|   documentRangeFormattingProvider?: boolean;
 | ||
|   --The server provides document formatting on typing.
 | ||
|   documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;
 | ||
|   --The server provides rename support. RenameOptions may only be
 | ||
|   --specified if the client states that it supports
 | ||
|   --`prepareSupport` in its initial `initialize` request.
 | ||
|   renameProvider?: boolean | RenameOptions;
 | ||
|   --The server provides document link support.
 | ||
|   documentLinkProvider?: DocumentLinkOptions;
 | ||
|   --The server provides color provider support.
 | ||
|   --
 | ||
|   --Since 3.6.0
 | ||
|   colorProvider?: boolean | ColorProviderOptions | (ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions);
 | ||
|   --The server provides folding provider support.
 | ||
|   --
 | ||
|   --Since 3.10.0
 | ||
|   foldingRangeProvider?: boolean | FoldingRangeProviderOptions | (FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions);
 | ||
|   --The server provides go to declaration support.
 | ||
|   --
 | ||
|   --Since 3.14.0
 | ||
|   declarationProvider?: boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions);
 | ||
|   --The server provides execute command support.
 | ||
|   executeCommandProvider?: ExecuteCommandOptions;
 | ||
|   --Workspace specific server capabilities
 | ||
|   workspace?: {
 | ||
|     --The server supports workspace folder.
 | ||
|     --
 | ||
|     --Since 3.6.0
 | ||
|     workspaceFolders?: {
 | ||
|       * The server has support for workspace folders
 | ||
|       supported?: boolean;
 | ||
|       * Whether the server wants to receive workspace folder
 | ||
|       * change notifications.
 | ||
|       *
 | ||
|       * If a strings is provided the string is treated as a ID
 | ||
|       * under which the notification is registered on the client
 | ||
|       * side. The ID can be used to unregister for these events
 | ||
|       * using the `client/unregisterCapability` request.
 | ||
|       changeNotifications?: string | boolean;
 | ||
|     }
 | ||
|   }
 | ||
|   --Experimental server capabilities.
 | ||
|   experimental?: any;
 | ||
| }
 | ||
| --]]
 | ||
| 
 | ||
| --- Creates a normalized object describing LSP server capabilities.
 | ||
| function protocol.resolve_capabilities(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
 | ||
| 
 | ||
|   return vim.tbl_extend("error"
 | ||
|       , text_document_sync_properties
 | ||
|       , signature_help_properties
 | ||
|       , workspace_properties
 | ||
|       , general_properties
 | ||
|       )
 | ||
| end
 | ||
| 
 | ||
| return protocol
 | ||
| -- vim:sw=2 ts=2 et
 |