diff --git a/capabilities_client.go b/capabilities_client.go index 03b4f32..c4aa098 100644 --- a/capabilities_client.go +++ b/capabilities_client.go @@ -10,19 +10,772 @@ type ShowDocumentClientCapabilities struct { Support bool `json:"support"` } +// ShowMessageRequestClientCapabilities - Capabilities for `window/showMessageRequest`. +// +// @since 3.16.0 +type ShowMessageRequestClientCapabilities struct { + // Capabilities specific to the message action item. + MessageActionItem *ShowMessageRequestClientCapabilitiesMessageActionItem `json:"messageActionItem,omitempty"` +} + +// ShowMessageRequestClientCapabilitiesMessageActionItem - Capabilities specific to message action items. +// +// @since 3.16.0 +type ShowMessageRequestClientCapabilitiesMessageActionItem struct { + // Whether the client supports additional attributes that are preserved + // and sent back to the server in the response. + AdditionalPropertiesSupport bool `json:"additionalPropertiesSupport,omitempty"` +} + // WindowClientCapabilities - Client capabilities for window features. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#windowClientCapabilities type WindowClientCapabilities struct { + // Whether client supports handling progress notifications from the server. + WorkDoneProgress bool `json:"workDoneProgress,omitempty"` + + // Capabilities for the show message request. + // + // @since 3.16.0 + ShowMessage *ShowMessageRequestClientCapabilities `json:"showMessage,omitempty"` + // It indicates whether the client supports the `window/showDocument` request. // // @since 3.16.0 ShowDocument *ShowDocumentClientCapabilities `json:"showDocument,omitempty"` } +// ResourceOperationKind - Resource operation kinds in workspace edits. +type ResourceOperationKind string + +const ( + // ResourceOperationCreate indicates support for creating files/folders. + ResourceOperationCreate ResourceOperationKind = "create" + // ResourceOperationRename indicates support for renaming files/folders. + ResourceOperationRename ResourceOperationKind = "rename" + // ResourceOperationDelete indicates support for deleting files/folders. + ResourceOperationDelete ResourceOperationKind = "delete" +) + +// FailureHandlingKind - Strategies for handling workspace edit failures. +type FailureHandlingKind string + +const ( + // FailureHandlingAbort applies the edit up to the first failure and aborts. + FailureHandlingAbort FailureHandlingKind = "abort" + // FailureHandlingTransactional applies all edits transactionally. + FailureHandlingTransactional FailureHandlingKind = "transactional" + // FailureHandlingTextOnlyTransactional applies text edits transactionally. + FailureHandlingTextOnlyTransactional FailureHandlingKind = "textOnlyTransactional" + // FailureHandlingUndo rolls back already-applied edits on failure. + FailureHandlingUndo FailureHandlingKind = "undo" +) + +// DynamicRegistrationClientCapabilities captures capabilities with `dynamicRegistration`. +type DynamicRegistrationClientCapabilities struct { + // DynamicRegistration indicates whether the client supports dynamic + // registration for the corresponding request/notification. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +} + +type ( + DidChangeConfigurationClientCapabilities = DynamicRegistrationClientCapabilities + DidChangeWatchedFilesClientCapabilities = DynamicRegistrationClientCapabilities + ExecuteCommandClientCapabilities = DynamicRegistrationClientCapabilities + ReferenceClientCapabilities = DynamicRegistrationClientCapabilities + DocumentHighlightClientCapabilities = DynamicRegistrationClientCapabilities + CodeLensClientCapabilities = DynamicRegistrationClientCapabilities + DocumentColorClientCapabilities = DynamicRegistrationClientCapabilities + DocumentFormattingClientCapabilities = DynamicRegistrationClientCapabilities + DocumentRangeFormattingClientCapabilities = DynamicRegistrationClientCapabilities + DocumentOnTypeFormattingClientCapabilities = DynamicRegistrationClientCapabilities + SelectionRangeClientCapabilities = DynamicRegistrationClientCapabilities + CallHierarchyClientCapabilities = DynamicRegistrationClientCapabilities + LinkedEditingRangeClientCapabilities = DynamicRegistrationClientCapabilities + MonikerClientCapabilities = DynamicRegistrationClientCapabilities + TypeHierarchyClientCapabilities = DynamicRegistrationClientCapabilities + InlineValueClientCapabilities = DynamicRegistrationClientCapabilities +) + +// WorkspaceEditClientCapabilities - Client capabilities for workspace edits. +type WorkspaceEditClientCapabilities struct { + // DocumentChanges indicates support for versioned document changes. + DocumentChanges bool `json:"documentChanges,omitempty"` + // ResourceOperations is the set of resource operations supported in + // `WorkspaceEdit.documentChanges`. + ResourceOperations []ResourceOperationKind `json:"resourceOperations,omitempty"` + // FailureHandling describes how the client handles failures in + // workspace edit application. + FailureHandling FailureHandlingKind `json:"failureHandling,omitempty"` + // NormalizesLineEndings indicates whether the client normalizes line endings + // when applying text edits. + NormalizesLineEndings bool `json:"normalizesLineEndings,omitempty"` + // ChangeAnnotationSupport describes support for change annotations in + // workspace edits. + ChangeAnnotationSupport *WorkspaceEditClientCapabilitiesChangeAnnotationSupport `json:"changeAnnotationSupport,omitempty"` +} + +// WorkspaceEditClientCapabilitiesChangeAnnotationSupport - Capabilities for change annotations. +type WorkspaceEditClientCapabilitiesChangeAnnotationSupport struct { + // GroupsOnLabel indicates whether the client can present change annotations + // grouped by their label. + GroupsOnLabel bool `json:"groupsOnLabel,omitempty"` +} + +// WorkspaceSymbolClientCapabilitiesSymbolKind - Supported workspace symbol kinds. +type WorkspaceSymbolClientCapabilitiesSymbolKind struct { + // ValueSet is the symbol kind values the client supports. + ValueSet []uint32 `json:"valueSet,omitempty"` +} + +// WorkspaceSymbolClientCapabilitiesTagSupport - Supported workspace symbol tags. +type WorkspaceSymbolClientCapabilitiesTagSupport struct { + // ValueSet is the symbol tag values the client supports. + ValueSet []uint32 `json:"valueSet,omitempty"` +} + +// WorkspaceSymbolClientCapabilities - Workspace symbol capabilities. +type WorkspaceSymbolClientCapabilities struct { + // DynamicRegistration indicates whether workspace symbol support can be + // dynamically registered. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // SymbolKind describes the symbol kinds the client supports. + SymbolKind *WorkspaceSymbolClientCapabilitiesSymbolKind `json:"symbolKind,omitempty"` + // TagSupport describes supported `SymbolTag` values. + TagSupport *WorkspaceSymbolClientCapabilitiesTagSupport `json:"tagSupport,omitempty"` + // ResolveSupport lists properties that can be resolved lazily. + ResolveSupport *WorkspaceSymbolClientCapabilitiesResolveSupport `json:"resolveSupport,omitempty"` +} + +// WorkspaceSymbolClientCapabilitiesResolveSupport - Workspace symbol resolve support capabilities. +type WorkspaceSymbolClientCapabilitiesResolveSupport struct { + // Properties are workspace symbol properties that can be resolved lazily. + Properties []string `json:"properties,omitempty"` +} + +// FileOperationClientCapabilities - File operation capabilities. +// +// @since 3.16.0 +type FileOperationClientCapabilities struct { + // DidCreate indicates support for `workspace/didCreateFiles` notifications. + DidCreate bool `json:"didCreate,omitempty"` + // WillCreate indicates support for `workspace/willCreateFiles` requests. + WillCreate bool `json:"willCreate,omitempty"` + // DidRename indicates support for `workspace/didRenameFiles` notifications. + DidRename bool `json:"didRename,omitempty"` + // WillRename indicates support for `workspace/willRenameFiles` requests. + WillRename bool `json:"willRename,omitempty"` + // DidDelete indicates support for `workspace/didDeleteFiles` notifications. + DidDelete bool `json:"didDelete,omitempty"` + // WillDelete indicates support for `workspace/willDeleteFiles` requests. + WillDelete bool `json:"willDelete,omitempty"` +} + +// SemanticTokensWorkspaceClientCapabilities - Workspace semantic tokens capabilities. +type SemanticTokensWorkspaceClientCapabilities struct { + // RefreshSupport indicates support for `workspace/semanticTokens/refresh`. + RefreshSupport bool `json:"refreshSupport,omitempty"` +} + +// CodeLensWorkspaceClientCapabilities - Workspace code lens capabilities. +type CodeLensWorkspaceClientCapabilities struct { + // RefreshSupport indicates support for `workspace/codeLens/refresh`. + RefreshSupport bool `json:"refreshSupport,omitempty"` +} + +// InlineValueWorkspaceClientCapabilities - Workspace inline value capabilities. +type InlineValueWorkspaceClientCapabilities struct { + // RefreshSupport indicates support for `workspace/inlineValue/refresh`. + RefreshSupport bool `json:"refreshSupport,omitempty"` +} + +// InlayHintWorkspaceClientCapabilities - Workspace inlay hint capabilities. +type InlayHintWorkspaceClientCapabilities struct { + // RefreshSupport indicates support for `workspace/inlayHint/refresh`. + RefreshSupport bool `json:"refreshSupport,omitempty"` +} + +// DiagnosticWorkspaceClientCapabilities - Workspace diagnostics capabilities. +type DiagnosticWorkspaceClientCapabilities struct { + // RefreshSupport indicates support for `workspace/diagnostic/refresh`. + RefreshSupport bool `json:"refreshSupport,omitempty"` +} + +// WorkspaceClientCapabilities - Workspace specific client capabilities. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspaceClientCapabilities +type WorkspaceClientCapabilities struct { + // ApplyEdit indicates whether the client accepts workspace/applyEdit requests. + ApplyEdit bool `json:"applyEdit,omitempty"` + // WorkspaceEdit describes supported `WorkspaceEdit` features. + WorkspaceEdit *WorkspaceEditClientCapabilities `json:"workspaceEdit,omitempty"` + // DidChangeConfiguration describes dynamic registration support for + // `workspace/didChangeConfiguration`. + DidChangeConfiguration *DidChangeConfigurationClientCapabilities `json:"didChangeConfiguration,omitempty"` + // DidChangeWatchedFiles describes dynamic registration support for + // `workspace/didChangeWatchedFiles`. + DidChangeWatchedFiles *DidChangeWatchedFilesClientCapabilities `json:"didChangeWatchedFiles,omitempty"` + // Symbol describes support for `workspace/symbol`. + Symbol *WorkspaceSymbolClientCapabilities `json:"symbol,omitempty"` + // ExecuteCommand describes dynamic registration support for + // `workspace/executeCommand`. + ExecuteCommand *ExecuteCommandClientCapabilities `json:"executeCommand,omitempty"` + // WorkspaceFolders indicates whether workspace folder support is available. + WorkspaceFolders bool `json:"workspaceFolders,omitempty"` + // Configuration indicates support for `workspace/configuration` requests. + Configuration bool `json:"configuration,omitempty"` + // SemanticTokens describes workspace semantic token refresh support. + SemanticTokens *SemanticTokensWorkspaceClientCapabilities `json:"semanticTokens,omitempty"` + // CodeLens describes workspace code lens refresh support. + CodeLens *CodeLensWorkspaceClientCapabilities `json:"codeLens,omitempty"` + // FileOperations describes file operation notification/request support. + FileOperations *FileOperationClientCapabilities `json:"fileOperations,omitempty"` + // InlineValue describes workspace inline value refresh support. + InlineValue *InlineValueWorkspaceClientCapabilities `json:"inlineValue,omitempty"` + // InlayHint describes workspace inlay hint refresh support. + InlayHint *InlayHintWorkspaceClientCapabilities `json:"inlayHint,omitempty"` + // Diagnostics describes workspace diagnostic refresh support. + Diagnostics *DiagnosticWorkspaceClientCapabilities `json:"diagnostics,omitempty"` +} + +// TextDocumentSyncClientCapabilities - Synchronization capabilities. +type TextDocumentSyncClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // WillSave indicates support for before-save notifications. + WillSave bool `json:"willSave,omitempty"` + // WillSaveWaitUntil indicates support for before-save requests that can + // return text edits. + WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"` + // DidSave indicates support for save notifications. + DidSave bool `json:"didSave,omitempty"` +} + +// CompletionItemTagSupportClientCapabilities - Completion item tag support. +type CompletionItemTagSupportClientCapabilities struct { + // ValueSet is the `CompletionItemTag` values supported by the client. + ValueSet []CompletionItemTag `json:"valueSet,omitempty"` +} + +// CompletionItemResolveSupportClientCapabilities - Completion item resolve support. +type CompletionItemResolveSupportClientCapabilities struct { + // Properties are completion item properties that can be lazily resolved. + Properties []string `json:"properties,omitempty"` +} + +// InsertTextModeSupportClientCapabilities - Insert text mode support. +type InsertTextModeSupportClientCapabilities struct { + // ValueSet is the supported insert text modes. + ValueSet []InsertTextMode `json:"valueSet,omitempty"` +} + +// CompletionItemClientCapabilities - Capabilities for completion items. +type CompletionItemClientCapabilities struct { + // SnippetSupport indicates whether snippets are supported. + SnippetSupport bool `json:"snippetSupport,omitempty"` + // CommitCharactersSupport indicates support for commit characters. + CommitCharactersSupport bool `json:"commitCharactersSupport,omitempty"` + // DocumentationFormat lists preferred documentation formats. + DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"` + // DeprecatedSupport indicates support for deprecated completion items. + DeprecatedSupport bool `json:"deprecatedSupport,omitempty"` + // PreselectSupport indicates support for preselected completion items. + PreselectSupport bool `json:"preselectSupport,omitempty"` + // TagSupport describes supported completion item tags. + TagSupport *CompletionItemTagSupportClientCapabilities `json:"tagSupport,omitempty"` + // InsertReplaceSupport indicates support for insert/replace edits. + InsertReplaceSupport bool `json:"insertReplaceSupport,omitempty"` + // ResolveSupport describes lazily resolvable completion item properties. + ResolveSupport *CompletionItemResolveSupportClientCapabilities `json:"resolveSupport,omitempty"` + // InsertTextModeSupport describes supported insert text modes. + InsertTextModeSupport *InsertTextModeSupportClientCapabilities `json:"insertTextModeSupport,omitempty"` + // LabelDetailsSupport indicates support for completion item label details. + LabelDetailsSupport bool `json:"labelDetailsSupport,omitempty"` +} + +// CompletionItemKindClientCapabilities - Supported completion item kinds. +type CompletionItemKindClientCapabilities struct { + // ValueSet is the completion item kinds the client supports. + ValueSet []CompletionItemKind `json:"valueSet,omitempty"` +} + +// CompletionListClientCapabilities - Completion list capabilities. +// +// @since 3.17.0 +type CompletionListClientCapabilities struct { + // ItemDefaults lists supported defaults in completion list responses. + ItemDefaults []string `json:"itemDefaults,omitempty"` +} + +// CompletionClientCapabilities - Completion request capabilities. +type CompletionClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // CompletionItem describes completion item-specific capabilities. + CompletionItem *CompletionItemClientCapabilities `json:"completionItem,omitempty"` + // CompletionItemKind describes supported completion item kinds. + CompletionItemKind *CompletionItemKindClientCapabilities `json:"completionItemKind,omitempty"` + // ContextSupport indicates support for additional completion context. + ContextSupport bool `json:"contextSupport,omitempty"` + // InsertTextMode is the default insertion mode used by the client. + InsertTextMode InsertTextMode `json:"insertTextMode,omitempty"` + // CompletionList describes completion list-level capabilities. + CompletionList *CompletionListClientCapabilities `json:"completionList,omitempty"` +} + +// HoverClientCapabilities - Hover request capabilities. +type HoverClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // ContentFormat lists preferred markup formats for hover content. + ContentFormat []MarkupKind `json:"contentFormat,omitempty"` +} + +// ParameterInformationClientCapabilities - Parameter information capabilities. +type ParameterInformationClientCapabilities struct { + // LabelOffsetSupport indicates support for tuple label offsets. + LabelOffsetSupport bool `json:"labelOffsetSupport,omitempty"` +} + +// SignatureInformationClientCapabilities - Signature information capabilities. +type SignatureInformationClientCapabilities struct { + // DocumentationFormat lists preferred formats for signature docs. + DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"` + // ParameterInformation describes parameter info capabilities. + ParameterInformation *ParameterInformationClientCapabilities `json:"parameterInformation,omitempty"` + // ActiveParameterSupport indicates support for active parameter info. + ActiveParameterSupport bool `json:"activeParameterSupport,omitempty"` +} + +// SignatureHelpClientCapabilities - Signature help capabilities. +type SignatureHelpClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // SignatureInformation describes signature information support. + SignatureInformation *SignatureInformationClientCapabilities `json:"signatureInformation,omitempty"` + // ContextSupport indicates support for signature help context. + ContextSupport bool `json:"contextSupport,omitempty"` +} + +// DefinitionClientCapabilities - Definition request capabilities. +type DefinitionClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // LinkSupport indicates support for link-based definitions. + LinkSupport bool `json:"linkSupport,omitempty"` +} + +type ( + DeclarationClientCapabilities = DefinitionClientCapabilities + TypeDefinitionClientCapabilities = DefinitionClientCapabilities + ImplementationClientCapabilities = DefinitionClientCapabilities +) + +// DocumentSymbolClientCapabilities - Document symbol capabilities. +type DocumentSymbolClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // SymbolKind lists symbol kinds supported by the client. + SymbolKind *DocumentSymbolClientCapabilitiesSymbolKind `json:"symbolKind,omitempty"` + // HierarchicalDocumentSymbolSupport indicates support for hierarchical + // symbols in the document symbol response. + HierarchicalDocumentSymbolSupport bool `json:"hierarchicalDocumentSymbolSupport,omitempty"` + // TagSupport lists supported `SymbolTag` values. + TagSupport *DocumentSymbolClientCapabilitiesTagSupport `json:"tagSupport,omitempty"` + // LabelSupport indicates whether labels for symbols are supported. + LabelSupport bool `json:"labelSupport,omitempty"` +} + +type ( + DocumentSymbolClientCapabilitiesSymbolKind = WorkspaceSymbolClientCapabilitiesSymbolKind + DocumentSymbolClientCapabilitiesTagSupport = WorkspaceSymbolClientCapabilitiesTagSupport +) + +// CodeActionKindClientCapabilities - Supported code action kinds. +type CodeActionKindClientCapabilities struct { + // ValueSet is the `CodeActionKind` values supported by the client. + ValueSet []CodeActionKind `json:"valueSet,omitempty"` +} + +// CodeActionLiteralSupportClientCapabilities - Literal support for code actions. +type CodeActionLiteralSupportClientCapabilities struct { + // CodeActionKind describes supported code action kinds. + CodeActionKind CodeActionKindClientCapabilities `json:"codeActionKind"` +} + +// CodeActionResolveSupportClientCapabilities - Code action resolve support. +type CodeActionResolveSupportClientCapabilities struct { + // Properties are code action properties that can be lazily resolved. + Properties []string `json:"properties,omitempty"` +} + +// CodeActionClientCapabilities - Code action request capabilities. +type CodeActionClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // CodeActionLiteralSupport describes literal code action support. + CodeActionLiteralSupport *CodeActionLiteralSupportClientCapabilities `json:"codeActionLiteralSupport,omitempty"` + // IsPreferredSupport indicates support for the `isPreferred` flag. + IsPreferredSupport bool `json:"isPreferredSupport,omitempty"` + // DisabledSupport indicates support for disabled code actions. + DisabledSupport bool `json:"disabledSupport,omitempty"` + // DataSupport indicates support for preserving code action data between + // request and resolve. + DataSupport bool `json:"dataSupport,omitempty"` + // ResolveSupport describes lazily resolvable code action properties. + ResolveSupport *CodeActionResolveSupportClientCapabilities `json:"resolveSupport,omitempty"` + // HonorsChangeAnnotations indicates whether UI respects change annotations + // in incoming workspace edits. + HonorsChangeAnnotations bool `json:"honorsChangeAnnotations,omitempty"` +} + +// RenameClientCapabilities - Rename request capabilities. +type RenameClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // PrepareSupport indicates support for prepare rename requests. + PrepareSupport bool `json:"prepareSupport,omitempty"` + // PrepareSupportDefaultBehavior indicates the default behavior when + // prepare support is enabled. + PrepareSupportDefaultBehavior uint32 `json:"prepareSupportDefaultBehavior,omitempty"` + // HonorsChangeAnnotations indicates whether rename applies change + // annotation semantics in UI. + HonorsChangeAnnotations bool `json:"honorsChangeAnnotations,omitempty"` +} + +// PublishDiagnosticsTagSupportClientCapabilities - Diagnostic tag support. +type PublishDiagnosticsTagSupportClientCapabilities struct { + // ValueSet is the `DiagnosticTag` values supported by the client. + ValueSet []DiagnosticTag `json:"valueSet,omitempty"` +} + +// PublishDiagnosticsClientCapabilities - Publish diagnostics capabilities. +type PublishDiagnosticsClientCapabilities struct { + // RelatedInformation indicates support for related diagnostic locations. + RelatedInformation bool `json:"relatedInformation,omitempty"` + // TagSupport lists supported diagnostic tag values. + TagSupport *PublishDiagnosticsTagSupportClientCapabilities `json:"tagSupport,omitempty"` + // VersionSupport indicates whether diagnostics can be versioned. + VersionSupport bool `json:"versionSupport,omitempty"` + // CodeDescriptionSupport indicates support for code descriptions. + CodeDescriptionSupport bool `json:"codeDescriptionSupport,omitempty"` + // DataSupport indicates support for preserving diagnostic data between + // publish and code action requests. + DataSupport bool `json:"dataSupport,omitempty"` +} + +// FoldingRangeKindClientCapabilities - Folding range kind support. +type FoldingRangeKindClientCapabilities struct { + // ValueSet is the folding range kinds supported by the client. + ValueSet []string `json:"valueSet,omitempty"` +} + +// FoldingRangeClientCapabilities - Folding range capabilities. +type FoldingRangeClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // RangeLimit is the maximum number of folding ranges preferred. + RangeLimit uint32 `json:"rangeLimit,omitempty"` + // LineFoldingOnly indicates whether only whole-line folds are supported. + LineFoldingOnly bool `json:"lineFoldingOnly,omitempty"` + // FoldingRangeKind describes supported folding range kinds. + FoldingRangeKind *FoldingRangeClientCapabilitiesFoldingRangeKind `json:"foldingRangeKind,omitempty"` + // FoldingRange contains additional folding range specific support. + FoldingRange *FoldingRangeClientCapabilitiesFoldingRange `json:"foldingRange,omitempty"` +} + +type FoldingRangeClientCapabilitiesFoldingRangeKind = FoldingRangeKindClientCapabilities + +type FoldingRangeClientCapabilitiesFoldingRange struct { + // CollapsedText indicates support for custom collapsed text in ranges. + CollapsedText bool `json:"collapsedText,omitempty"` +} + +// TokenFormat - Semantic tokens format kinds. +type TokenFormat string + +const ( + // TokenFormatRelative denotes relative token encoding. + TokenFormatRelative TokenFormat = "relative" +) + +// SemanticTokensRequestsClientCapabilities - Semantic token request modes. +type SemanticTokensRequestsClientCapabilities struct { + // Range indicates support for range semantic token requests. + Range LSPAny `json:"range,omitempty"` + // Full indicates support for full document semantic token requests. + Full LSPAny `json:"full,omitempty"` +} + +type SemanticTokensClientCapabilitiesRequests = SemanticTokensRequestsClientCapabilities + +// SemanticTokensClientCapabilities - Semantic token capabilities. +type SemanticTokensClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // Requests describes range/full request support. + Requests SemanticTokensClientCapabilitiesRequests `json:"requests"` + // TokenTypes is the complete set of supported token types. + TokenTypes []string `json:"tokenTypes"` + // TokenModifiers is the complete set of supported token modifiers. + TokenModifiers []string `json:"tokenModifiers"` + // Formats lists supported semantic token encodings. + Formats []TokenFormat `json:"formats"` + // OverlappingTokenSupport indicates support for overlapping tokens. + OverlappingTokenSupport bool `json:"overlappingTokenSupport,omitempty"` + // MultilineTokenSupport indicates support for multiline tokens. + MultilineTokenSupport bool `json:"multilineTokenSupport,omitempty"` + // ServerCancelSupport indicates support for server-side cancellation. + ServerCancelSupport bool `json:"serverCancelSupport,omitempty"` + // AugmentsSyntaxTokens indicates whether semantic tokens augment syntax + // tokens instead of replacing them. + AugmentsSyntaxTokens bool `json:"augmentsSyntaxTokens,omitempty"` +} + +// InlayHintClientCapabilities - Inlay hint capabilities. +// +// @since 3.17.0 +type InlayHintClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // ResolveSupport lists inlay hint properties that can be resolved lazily. + ResolveSupport *InlayHintClientCapabilitiesResolveSupport `json:"resolveSupport,omitempty"` +} + +type InlayHintClientCapabilitiesResolveSupport = WorkspaceSymbolClientCapabilitiesResolveSupport + +// DiagnosticClientCapabilities - Pull diagnostic capabilities. +// +// @since 3.17.0 +type DiagnosticClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // RelatedDocumentSupport indicates whether diagnostics can be reported + // with related document data. + RelatedDocumentSupport bool `json:"relatedDocumentSupport,omitempty"` +} + +// TextDocumentClientCapabilities - Text document specific client capabilities. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentClientCapabilities +type TextDocumentClientCapabilities struct { + Synchronization *TextDocumentSyncClientCapabilities `json:"synchronization,omitempty"` + + // Capabilities specific to the `textDocument/completion` request. + Completion *CompletionClientCapabilities `json:"completion,omitempty"` + + // Capabilities specific to the `textDocument/hover` request. + Hover *HoverClientCapabilities `json:"hover,omitempty"` + + // Capabilities specific to the `textDocument/signatureHelp` request. + SignatureHelp *SignatureHelpClientCapabilities `json:"signatureHelp,omitempty"` + + // Capabilities specific to the `textDocument/declaration` request. + // + // @since 3.14.0 + Declaration *DeclarationClientCapabilities `json:"declaration,omitempty"` + + // Capabilities specific to the `textDocument/definition` request. + Definition *DefinitionClientCapabilities `json:"definition,omitempty"` + + // Capabilities specific to the `textDocument/typeDefinition` request. + // + // @since 3.6.0 + TypeDefinition *TypeDefinitionClientCapabilities `json:"typeDefinition,omitempty"` + + // Capabilities specific to the `textDocument/implementation` request. + // + // @since 3.6.0 + Implementation *ImplementationClientCapabilities `json:"implementation,omitempty"` + + // Capabilities specific to the `textDocument/references` request. + References *ReferenceClientCapabilities `json:"references,omitempty"` + + // Capabilities specific to the `textDocument/documentHighlight` request. + DocumentHighlight *DocumentHighlightClientCapabilities `json:"documentHighlight,omitempty"` + + // Capabilities specific to the `textDocument/documentSymbol` request. + DocumentSymbol *DocumentSymbolClientCapabilities `json:"documentSymbol,omitempty"` + + // Capabilities specific to the `textDocument/codeAction` request. + CodeAction *CodeActionClientCapabilities `json:"codeAction,omitempty"` + + // Capabilities specific to the `textDocument/codeLens` request. + CodeLens *CodeLensClientCapabilities `json:"codeLens,omitempty"` + + // Capabilities specific to the `textDocument/documentLink` request. + DocumentLink *DocumentLinkClientCapabilities `json:"documentLink,omitempty"` + + // Capabilities specific to the `textDocument/documentColor` and the + // `textDocument/colorPresentation` request. + // + // @since 3.6.0 + ColorProvider *DocumentColorClientCapabilities `json:"colorProvider,omitempty"` + + // Capabilities specific to the `textDocument/formatting` request. + Formatting *DocumentFormattingClientCapabilities `json:"formatting,omitempty"` + + // Capabilities specific to the `textDocument/rangeFormatting` request. + RangeFormatting *DocumentRangeFormattingClientCapabilities `json:"rangeFormatting,omitempty"` + + // Capabilities specific to the `textDocument/onTypeFormatting` request. + OnTypeFormatting *DocumentOnTypeFormattingClientCapabilities `json:"onTypeFormatting,omitempty"` + + // Capabilities specific to the `textDocument/rename` request. + Rename *RenameClientCapabilities `json:"rename,omitempty"` + + // Capabilities specific to the `textDocument/publishDiagnostics` + // notification. + PublishDiagnostics *PublishDiagnosticsClientCapabilities `json:"publishDiagnostics,omitempty"` + + // Capabilities specific to the `textDocument/foldingRange` request. + // + // @since 3.10.0 + FoldingRange *FoldingRangeClientCapabilities `json:"foldingRange,omitempty"` + + // Capabilities specific to the `textDocument/selectionRange` request. + // + // @since 3.15.0 + SelectionRange *SelectionRangeClientCapabilities `json:"selectionRange,omitempty"` + + // Capabilities specific to the `textDocument/linkedEditingRange` request. + // + // @since 3.16.0 + LinkedEditingRange *LinkedEditingRangeClientCapabilities `json:"linkedEditingRange,omitempty"` + + // Capabilities specific to the various call hierarchy requests. + // + // @since 3.16.0 + CallHierarchy *CallHierarchyClientCapabilities `json:"callHierarchy,omitempty"` + + // Capabilities specific to the various semantic token requests. + // + // @since 3.16.0 + SemanticTokens *SemanticTokensClientCapabilities `json:"semanticTokens,omitempty"` + + // Capabilities specific to the `textDocument/moniker` request. + // + // @since 3.16.0 + Moniker *MonikerClientCapabilities `json:"moniker,omitempty"` + + // Capabilities specific to the various type hierarchy requests. + // + // @since 3.17.0 + TypeHierarchy *TypeHierarchyClientCapabilities `json:"typeHierarchy,omitempty"` + + // Capabilities specific to the `textDocument/inlineValue` request. + // + // @since 3.17.0 + InlineValue *InlineValueClientCapabilities `json:"inlineValue,omitempty"` + + // Capabilities specific to the `textDocument/inlayHint` request. + // + // @since 3.17.0 + InlayHint *InlayHintClientCapabilities `json:"inlayHint,omitempty"` + + // Capabilities specific to the diagnostic pull model. + // + // @since 3.17.0 + Diagnostic *DiagnosticClientCapabilities `json:"diagnostic,omitempty"` +} + +type DocumentLinkClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // TooltipSupport indicates support for the tooltip field on document links. + TooltipSupport bool `json:"tooltipSupport,omitempty"` +} + +// NotebookDocumentSyncClientCapabilities - Notebook synchronization capabilities. +// +// @since 3.17.0 +type NotebookDocumentSyncClientCapabilities struct { + // DynamicRegistration indicates support for dynamic registration. + DynamicRegistration bool `json:"dynamicRegistration,omitempty"` + // ExecutionSummarySupport indicates support for notebook cell execution + // summary synchronization. + ExecutionSummarySupport bool `json:"executionSummarySupport,omitempty"` +} + +// NotebookDocumentClientCapabilities - Notebook document specific client capabilities. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#notebookDocumentClientCapabilities +// +// @since 3.17.0 +type NotebookDocumentClientCapabilities struct { + // Synchronization describes notebook synchronization support. + Synchronization *NotebookDocumentSyncClientCapabilities `json:"synchronization,omitempty"` +} + +// StaleRequestSupportClientCapabilities - Stale request support details. +// +// @since 3.17.0 +type StaleRequestSupportClientCapabilities struct { + // Cancel indicates whether stale requests should be canceled. + Cancel bool `json:"cancel,omitempty"` + // RetryOnContentModified lists request methods that should be retried when + // content changed. + RetryOnContentModified []string `json:"retryOnContentModified,omitempty"` +} + +// RegularExpressionsClientCapabilities - Regular expression engine details. +// +// @since 3.16.0 +type RegularExpressionsClientCapabilities struct { + // Engine is the regular expression engine name (for example `ECMAScript`). + Engine string `json:"engine"` + // Version is the engine version when available. + Version string `json:"version,omitempty"` +} + +// MarkdownClientCapabilities - Markdown parser details. +// +// @since 3.16.0 +type MarkdownClientCapabilities struct { + // Parser is the markdown parser name. + Parser string `json:"parser"` + // Version is the parser version when available. + Version string `json:"version,omitempty"` + // AllowedTags are HTML tags allowed in markdown rendering. + AllowedTags []string `json:"allowedTags,omitempty"` +} + +// GeneralClientCapabilities - General client capabilities. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#generalClientCapabilities +type GeneralClientCapabilities struct { + // StaleRequestSupport describes support for stale request handling. + StaleRequestSupport *StaleRequestSupportClientCapabilities `json:"staleRequestSupport,omitempty"` + // RegularExpressions describes regex engine capabilities. + RegularExpressions *RegularExpressionsClientCapabilities `json:"regularExpressions,omitempty"` + // Markdown describes markdown parser capabilities. + Markdown *MarkdownClientCapabilities `json:"markdown,omitempty"` + // PositionEncodings lists position encodings supported by the client. + PositionEncodings []PositionEncodingKind `json:"positionEncodings,omitempty"` +} + // ClientCapabilities defines the capabilities of the client (e.g., editor or IDE). // It tells the language server what features the client supports. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#clientCapabilities type ClientCapabilities struct { + // Workspace specific client capabilities. + Workspace *WorkspaceClientCapabilities `json:"workspace,omitempty"` + + // Text document specific client capabilities. + TextDocument *TextDocumentClientCapabilities `json:"textDocument,omitempty"` + + // Notebook document specific client capabilities. + // + // @since 3.17.0 + NotebookDocument *NotebookDocumentClientCapabilities `json:"notebookDocument,omitempty"` + // Window specific client capabilities. Window *WindowClientCapabilities `json:"window,omitempty"` + + // General client capabilities. + General *GeneralClientCapabilities `json:"general,omitempty"` + + // Experimental client capabilities. The value can be any JSON type. + Experimental LSPAny `json:"experimental,omitempty"` } diff --git a/capabilities_client_test.go b/capabilities_client_test.go index eb82934..00a1594 100644 --- a/capabilities_client_test.go +++ b/capabilities_client_test.go @@ -56,3 +56,63 @@ func Test_CapabilitiesClient_MarshalOmitEmptyWindow(t *testing.T) { t.Fatalf("expected window to be omitted, got payload: %s", string(data)) } } + +func Test_CapabilitiesClient_UnmarshalTopLevelCapabilities(t *testing.T) { + data := []byte(`{ + "workspace": {"applyEdit": true}, + "textDocument": {"hover": {"dynamicRegistration": true}}, + "notebookDocument": {"synchronization": {"dynamicRegistration": true}}, + "general": {"positionEncodings": ["utf-16", "utf-8"]}, + "experimental": {"myFeature": true}, + "window": {"showDocument": {"support": true}} + }`) + + var decoded protocol.ClientCapabilities + if err := json.Unmarshal(data, &decoded); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + if decoded.Workspace == nil { + t.Fatalf("expected workspace capabilities to be present") + } + + if decoded.TextDocument == nil { + t.Fatalf("expected textDocument capabilities to be present") + } + + if decoded.NotebookDocument == nil { + t.Fatalf("expected notebookDocument capabilities to be present") + } + + if decoded.General == nil { + t.Fatalf("expected general capabilities to be present") + } + + if decoded.Experimental == nil { + t.Fatalf("expected experimental capabilities to be present") + } + + if decoded.Window == nil || decoded.Window.ShowDocument == nil || !decoded.Window.ShowDocument.Support { + t.Fatalf("expected window.showDocument.support to be true") + } +} + +func Test_CapabilitiesClient_MarshalOmitEmptyTopLevelFields(t *testing.T) { + original := protocol.ClientCapabilities{} + + data, err := json.Marshal(original) + if err != nil { + t.Fatalf("marshal failed: %v", err) + } + + var payload map[string]any + if err := json.Unmarshal(data, &payload); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + for _, key := range []string{"workspace", "textDocument", "notebookDocument", "general", "experimental", "window"} { + if _, ok := payload[key]; ok { + t.Fatalf("expected %q to be omitted, got payload: %s", key, string(data)) + } + } +} diff --git a/capabilities_server.go b/capabilities_server.go index b06851e..d74f32e 100644 --- a/capabilities_server.go +++ b/capabilities_server.go @@ -1,51 +1,161 @@ package protocol // ServerCapabilities defines the capabilities of the language server. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#serverCapabilities type ServerCapabilities struct { - // The position encoding the server picked from the encodings offered - // by the client via the client capability `general.positionEncodings`. + // The position encoding the server picked from the encodings offered by the + // client via the client capability `general.positionEncodings`. // - // If the client didn't provide any position encodings the only valid - // value that a server can return is 'utf-16'. + // If the client didn't provide any position encodings the only valid value + // that a server can return is `utf-16`. // - // If omitted it defaults to 'utf-16'. + // If omitted it defaults to `utf-16`. // // @since 3.17.0 PositionEncoding *PositionEncodingKind `json:"positionEncoding,omitempty"` - // 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 any `json:"textDocumentSync,omitempty"` // *TextDocumentSyncOptions | TextDocumentSyncKind + // Defines how text documents are synced. + // + // This can be either: + // - `TextDocumentSyncOptions`, or + // - `TextDocumentSyncKind` (for backwards compatibility). + TextDocumentSync any `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | TextDocumentSyncKind + + // Defines notebook document synchronization support. + // + // @since 3.17.0 + NotebookDocumentSync any `json:"notebookDocumentSync,omitempty"` // NotebookDocumentSyncOptions | NotebookDocumentSyncRegistrationOptions // The server provides completion support. CompletionProvider *CompletionOptions `json:"completionProvider,omitempty"` // The server provides hover support. - HoverProvider bool `json:"hoverProvider,omitempty"` + HoverProvider any `json:"hoverProvider,omitempty"` // bool | HoverOptions // The server provides signature help support. SignatureHelpProvider *SignatureHelpOptions `json:"signatureHelpProvider,omitempty"` - // The server provides goto definition support. - DefinitionProvider bool `json:"definitionProvider,omitempty"` + // The server provides goto declaration support. + // + // @since 3.14.0 + DeclarationProvider any `json:"declarationProvider,omitempty"` // bool | DeclarationOptions | DeclarationRegistrationOptions - // 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 bool `json:"codeActionProvider,omitempty"` + // The server provides goto definition support. + DefinitionProvider any `json:"definitionProvider,omitempty"` // bool | DefinitionOptions + + // The server provides goto type definition support. + // + // @since 3.6.0 + TypeDefinitionProvider any `json:"typeDefinitionProvider,omitempty"` // bool | TypeDefinitionOptions | TypeDefinitionRegistrationOptions + + // The server provides goto implementation support. + // + // @since 3.6.0 + ImplementationProvider any `json:"implementationProvider,omitempty"` // bool | ImplementationOptions | ImplementationRegistrationOptions + + // The server provides find references support. + ReferencesProvider any `json:"referencesProvider,omitempty"` // bool | ReferenceOptions + + // The server provides document highlight support. + DocumentHighlightProvider any `json:"documentHighlightProvider,omitempty"` // bool | DocumentHighlightOptions + + // The server provides document symbol support. + DocumentSymbolProvider any `json:"documentSymbolProvider,omitempty"` // bool | DocumentSymbolOptions + + // The server provides code action support. + CodeActionProvider any `json:"codeActionProvider,omitempty"` // bool | CodeActionOptions + + // The server provides code lens support. + CodeLensProvider *CodeLensOptions `json:"codeLensProvider,omitempty"` + + // The server provides document link support. + DocumentLinkProvider *DocumentLinkOptions `json:"documentLinkProvider,omitempty"` + + // The server provides color provider support. + // + // @since 3.6.0 + ColorProvider any `json:"colorProvider,omitempty"` // bool | DocumentColorOptions | DocumentColorRegistrationOptions + + // The server provides document formatting support. + DocumentFormattingProvider any `json:"documentFormattingProvider,omitempty"` // bool | DocumentFormattingOptions + + // The server provides document range formatting support. + DocumentRangeFormattingProvider any `json:"documentRangeFormattingProvider,omitempty"` // bool | DocumentRangeFormattingOptions + + // The server provides document on type formatting support. + DocumentOnTypeFormattingProvider *DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"` + + // The server provides rename support. + RenameProvider any `json:"renameProvider,omitempty"` // bool | RenameOptions + + // The server provides folding range support. + // + // @since 3.10.0 + FoldingRangeProvider any `json:"foldingRangeProvider,omitempty"` // bool | FoldingRangeOptions | FoldingRangeRegistrationOptions + + // The server provides execute command support. + ExecuteCommandProvider *ExecuteCommandOptions `json:"executeCommandProvider,omitempty"` + + // The server provides selection range support. + // + // @since 3.15.0 + SelectionRangeProvider any `json:"selectionRangeProvider,omitempty"` // bool | SelectionRangeOptions | SelectionRangeRegistrationOptions + + // The server provides linked editing range support. + // + // @since 3.16.0 + LinkedEditingRangeProvider any `json:"linkedEditingRangeProvider,omitempty"` // bool | LinkedEditingRangeOptions | LinkedEditingRangeRegistrationOptions + + // The server provides call hierarchy support. + // + // @since 3.16.0 + CallHierarchyProvider any `json:"callHierarchyProvider,omitempty"` // bool | CallHierarchyOptions | CallHierarchyRegistrationOptions + + // The server provides semantic tokens support. + // + // @since 3.16.0 + SemanticTokensProvider any `json:"semanticTokensProvider,omitempty"` // SemanticTokensOptions | SemanticTokensRegistrationOptions + + // The server provides moniker support. + // + // @since 3.16.0 + MonikerProvider any `json:"monikerProvider,omitempty"` // bool | MonikerOptions | MonikerRegistrationOptions + + // The server provides type hierarchy support. + // + // @since 3.17.0 + TypeHierarchyProvider any `json:"typeHierarchyProvider,omitempty"` // bool | TypeHierarchyOptions | TypeHierarchyRegistrationOptions + + // The server provides inline value support. + // + // @since 3.17.0 + InlineValueProvider any `json:"inlineValueProvider,omitempty"` // bool | InlineValueOptions | InlineValueRegistrationOptions + + // The server provides inlay hint support. + // + // @since 3.17.0 + InlayHintProvider any `json:"inlayHintProvider,omitempty"` // bool | InlayHintOptions | InlayHintRegistrationOptions // The server has support for pull model diagnostics. // // @since 3.17.0 DiagnosticProvider any `json:"diagnosticProvider,omitempty"` // DiagnosticOptions | DiagnosticRegistrationOptions - // Experimental server capabilities. + // The server provides workspace symbol support. + // + // @since 3.17.0 + WorkspaceSymbolProvider any `json:"workspaceSymbolProvider,omitempty"` // bool | WorkspaceSymbolOptions + + // Workspace-specific server capabilities. + Workspace *WorkspaceServerCapabilities `json:"workspace,omitempty"` + + // Experimental server capabilities. The value can be any JSON type. Experimental *LSPAny `json:"experimental,omitempty"` } -// TextDocumentSyncKind Defines how the host (editor) should sync document changes to the language server. +// TextDocumentSyncKind defines how the host (editor) should sync document +// changes to the language server. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentSyncKind type TextDocumentSyncKind int @@ -57,75 +167,222 @@ const ( // Documents are synced by always sending the full content of the document. TextDocumentSyncKindFull TextDocumentSyncKind = 1 - // Documents are synced by sending the full content on open and close. - // After that only incremental updates to the document are sent. + // Documents are synced by sending the full content on open and close. After + // that only incremental updates to the document are sent. TextDocumentSyncKindIncremental TextDocumentSyncKind = 2 ) -// CompletionOptions used during `initialize` or server capabilities registration. +// TextDocumentSyncOptions defines detailed text document synchronization +// options. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentSyncOptions +type TextDocumentSyncOptions struct { + OpenClose bool `json:"openClose,omitempty"` + Change TextDocumentSyncKind `json:"change,omitempty"` + WillSave bool `json:"willSave,omitempty"` + WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"` + Save any `json:"save,omitempty"` // bool | SaveOptions +} + +// SaveOptions options for save notifications. +type SaveOptions struct { + IncludeText bool `json:"includeText,omitempty"` +} + +// CompletionOptions used during `initialize` or server capabilities +// registration. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionOptions type CompletionOptions struct { WorkDoneProgressOptions - // The additional characters, beyond the defaults provided by the client (typically - // [a-zA-Z]), that should automatically trigger a completion request. For example - // `.` in JavaScript represents the beginning of an object property or method and is - // thus a good candidate for triggering a completion request. - // - // Most tools trigger a completion request automatically without explicitly - // requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they - // do so when the user starts to type an identifier. For example if the user - // types `c` in a JavaScript file code complete will automatically pop up - // present `console` besides others as a completion item. Characters that - // make up identifiers don't need to be listed here. + // The additional characters that should trigger completion. TriggerCharacters []string `json:"triggerCharacters,omitempty"` - // The list of all possible characters that commit a completion. This field - // can be used if clients don't support individual commit characters per - // completion item. See client capability - // `completion.completionItem.commitCharactersSupport`. - // - // If a server provides both `allCommitCharacters` and commit characters on - // an individual completion item the ones on the completion item win. + // Characters that commit a completion item. // // @since 3.2.0 AllCommitCharacters []string `json:"allCommitCharacters,omitempty"` - // The server provides support to resolve additional - // information for a completion item. + // The server supports completion item resolve. ResolveProvider *bool `json:"resolveProvider,omitempty"` - // The server supports the following `CompletionItem` specific - // capabilities. + // Completion item-specific server capabilities. // // @since 3.17.0 - CompletionItem *CompletionItemCapability `json:"completionItem,omitempty"` + CompletionItem *CompletionOptionsCompletionItem `json:"completionItem,omitempty"` } -// CompletionItemCapability Capabilities specific to the `CompletionItem`. +// CompletionOptionsCompletionItem capabilities specific to completion items. // // @since 3.17.0 -type CompletionItemCapability struct { - // The server has support for completion item label details (see also `CompletionItemLabelDetails`) - // when receiving a completion item in a resolve call. - // @since 3.17.0 +type CompletionOptionsCompletionItem struct { + // The server supports `CompletionItemLabelDetails` in resolve responses. LabelDetailsSupport *bool `json:"labelDetailsSupport,omitempty"` } -// SignatureHelpOptions Server capabilities for signature help requests. +// Backward compatible alias. +type CompletionItemCapability = CompletionOptionsCompletionItem + +// SignatureHelpOptions server capabilities for signature help requests. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#signatureHelpOptions type SignatureHelpOptions struct { - // The characters that trigger signature help automatically. - TriggerCharacters []string `json:"triggerCharacters,omitempty"` - - // List of characters that re-trigger signature help. - // These are typically the same as `triggerCharacters`, but may contain additional characters. - // @since 3.2.0 + TriggerCharacters []string `json:"triggerCharacters,omitempty"` RetriggerCharacters []string `json:"retriggerCharacters,omitempty"` } +// WorkDoneProgressOptions indicates if a request supports work-done progress +// reporting. +type WorkDoneProgressOptions struct { + WorkDoneProgress bool `json:"workDoneProgress,omitempty"` +} + +// HoverOptions describes hover support details. +type HoverOptions = WorkDoneProgressOptions + +// DeclarationOptions describes declaration support details. +// +// @since 3.14.0 +type DeclarationOptions = WorkDoneProgressOptions + +// DefinitionOptions describes definition support details. +type DefinitionOptions = WorkDoneProgressOptions + +// TypeDefinitionOptions describes type definition support details. +// +// @since 3.6.0 +type TypeDefinitionOptions = WorkDoneProgressOptions + +// ImplementationOptions describes implementation support details. +// +// @since 3.6.0 +type ImplementationOptions = WorkDoneProgressOptions + +// ReferenceOptions describes references support details. +type ReferenceOptions = WorkDoneProgressOptions + +// DocumentHighlightOptions describes document highlight support details. +type DocumentHighlightOptions = WorkDoneProgressOptions + +// DocumentSymbolOptions describes document symbol support details. +type DocumentSymbolOptions = WorkDoneProgressOptions + +// CodeActionOptions server capability for code actions. +type CodeActionOptions struct { + WorkDoneProgressOptions + + CodeActionKinds []CodeActionKind `json:"codeActionKinds,omitempty"` + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// CodeLensOptions server capability for code lenses. +type CodeLensOptions struct { + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// DocumentLinkOptions server capability for document links. +type DocumentLinkOptions struct { + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// DocumentColorOptions describes document color support details. +// +// @since 3.6.0 +type DocumentColorOptions = WorkDoneProgressOptions + +// DocumentFormattingOptions describes formatting support details. +type DocumentFormattingOptions = WorkDoneProgressOptions + +// DocumentRangeFormattingOptions describes range formatting support details. +type DocumentRangeFormattingOptions = WorkDoneProgressOptions + +// DocumentOnTypeFormattingOptions server capability for on-type formatting. +type DocumentOnTypeFormattingOptions struct { + FirstTriggerCharacter string `json:"firstTriggerCharacter"` + MoreTriggerCharacter []string `json:"moreTriggerCharacter,omitempty"` +} + +// RenameOptions server capability for rename. +type RenameOptions struct { + WorkDoneProgressOptions + PrepareProvider bool `json:"prepareProvider,omitempty"` +} + +// FoldingRangeOptions describes folding range support details. +// +// @since 3.10.0 +type FoldingRangeOptions = WorkDoneProgressOptions + +// ExecuteCommandOptions server capability for execute command. +type ExecuteCommandOptions struct { + WorkDoneProgressOptions + Commands []string `json:"commands"` +} + +// SelectionRangeOptions describes selection range support details. +// +// @since 3.15.0 +type SelectionRangeOptions = WorkDoneProgressOptions + +// LinkedEditingRangeOptions describes linked editing range support details. +// +// @since 3.16.0 +type LinkedEditingRangeOptions = WorkDoneProgressOptions + +// CallHierarchyOptions describes call hierarchy support details. +// +// @since 3.16.0 +type CallHierarchyOptions = WorkDoneProgressOptions + +// SemanticTokensLegend describes token types and token modifiers a server uses. +// +// @since 3.16.0 +type SemanticTokensLegend struct { + TokenTypes []string `json:"tokenTypes"` + TokenModifiers []string `json:"tokenModifiers"` +} + +// SemanticTokensOptionsFull indicates support for full document semantic tokens. +// +// @since 3.16.0 +type SemanticTokensOptionsFull struct { + Delta bool `json:"delta,omitempty"` +} + +// SemanticTokensOptions server capability for semantic tokens. +// +// @since 3.16.0 +type SemanticTokensOptions struct { + WorkDoneProgressOptions + Legend SemanticTokensLegend `json:"legend"` + Range any `json:"range,omitempty"` // bool | map[string]any + Full any `json:"full,omitempty"` // bool | SemanticTokensOptionsFull +} + +// MonikerOptions describes moniker support details. +// +// @since 3.16.0 +type MonikerOptions = WorkDoneProgressOptions + +// TypeHierarchyOptions describes type hierarchy support details. +// +// @since 3.17.0 +type TypeHierarchyOptions = WorkDoneProgressOptions + +// InlineValueOptions describes inline value support details. +// +// @since 3.17.0 +type InlineValueOptions = WorkDoneProgressOptions + +// InlayHintOptions server capability for inlay hints. +// +// @since 3.17.0 +type InlayHintOptions struct { + WorkDoneProgressOptions + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + // DiagnosticOptions registration options to configure pull diagnostics. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticOptions @@ -134,22 +391,139 @@ type SignatureHelpOptions struct { type DiagnosticOptions struct { WorkDoneProgressOptions - // An optional identifier under which the diagnostics are - // managed by the client. - Identifier string `json:"identifier,omitempty"` - - // Whether the language has inter file dependencies meaning that - // editing code in one file can result in a different diagnostic - // set in another file. Inter file dependencies are common for - // most programming languages and typically uncommon for linters. - InterFileDependencies bool `json:"interFileDependencies"` - - // The server provides support for workspace diagnostics as well. - WorkspaceDiagnostics bool `json:"workspaceDiagnostics"` + Identifier string `json:"identifier,omitempty"` + InterFileDependencies bool `json:"interFileDependencies"` + WorkspaceDiagnostics bool `json:"workspaceDiagnostics"` } -// WorkDoneProgressOptions indicates if a request supports work-done progress reporting. -type WorkDoneProgressOptions struct { - // WorkDoneProgress is a flag that indicates whether progress reporting is supported. - WorkDoneProgress bool `json:"workDoneProgress,omitempty"` +// WorkspaceSymbolOptions server capability for workspace symbols. +// +// @since 3.17.0 +type WorkspaceSymbolOptions struct { + WorkDoneProgressOptions + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// WorkspaceServerCapabilities workspace-level server capabilities. +type WorkspaceServerCapabilities struct { + WorkspaceFolders *WorkspaceFoldersServerCapabilities `json:"workspaceFolders,omitempty"` + FileOperations *FileOperationOptions `json:"fileOperations,omitempty"` +} + +// WorkspaceFoldersServerCapabilities server support for workspace folders. +type WorkspaceFoldersServerCapabilities struct { + Supported bool `json:"supported,omitempty"` + ChangeNotifications any `json:"changeNotifications,omitempty"` // string | bool +} + +// FileOperationOptions server support for file operation requests/notifications. +// +// @since 3.16.0 +type FileOperationOptions struct { + DidCreate *FileOperationRegistrationOptions `json:"didCreate,omitempty"` + WillCreate *FileOperationRegistrationOptions `json:"willCreate,omitempty"` + DidRename *FileOperationRegistrationOptions `json:"didRename,omitempty"` + WillRename *FileOperationRegistrationOptions `json:"willRename,omitempty"` + DidDelete *FileOperationRegistrationOptions `json:"didDelete,omitempty"` + WillDelete *FileOperationRegistrationOptions `json:"willDelete,omitempty"` +} + +// FileOperationRegistrationOptions registration options for file operations. +// +// @since 3.16.0 +type FileOperationRegistrationOptions struct { + Filters []FileOperationFilter `json:"filters"` +} + +// FileOperationFilter describes a filter for file operation events. +// +// @since 3.16.0 +type FileOperationFilter struct { + Scheme string `json:"scheme,omitempty"` + Pattern FileOperationPattern `json:"pattern"` +} + +// FileOperationPatternKind describes whether a file operation pattern applies +// to files or folders. +// +// @since 3.16.0 +type FileOperationPatternKind string + +const ( + FileOperationPatternKindFile FileOperationPatternKind = "file" + FileOperationPatternKindFolder FileOperationPatternKind = "folder" +) + +// FileOperationPatternOptions options for file operation patterns. +// +// @since 3.16.0 +type FileOperationPatternOptions struct { + IgnoreCase bool `json:"ignoreCase,omitempty"` +} + +// FileOperationPattern glob pattern for file operations. +// +// @since 3.16.0 +type FileOperationPattern struct { + Glob string `json:"glob"` + Matches FileOperationPatternKind `json:"matches,omitempty"` + Options *FileOperationPatternOptions `json:"options,omitempty"` +} + +// Registration option aliases with spec names. +type ( + DeclarationRegistrationOptions = TextDocumentRegistrationOptions + TypeDefinitionRegistrationOptions = TextDocumentRegistrationOptions + ImplementationRegistrationOptions = TextDocumentRegistrationOptions + ColorProviderRegistrationOptions = TextDocumentRegistrationOptions + FoldingRangeRegistrationOptions = TextDocumentRegistrationOptions + SelectionRangeRegistrationOptions = TextDocumentRegistrationOptions + LinkedEditingRangeRegistrationOptions = TextDocumentRegistrationOptions + CallHierarchyRegistrationOptions = TextDocumentRegistrationOptions + MonikerRegistrationOptions = TextDocumentRegistrationOptions + TypeHierarchyRegistrationOptions = TextDocumentRegistrationOptions + InlineValueRegistrationOptions = TextDocumentRegistrationOptions + InlayHintRegistrationOptions = TextDocumentRegistrationOptions + SemanticTokensRegistrationOptions = TextDocumentRegistrationOptions + DiagnosticRegistrationOptions = TextDocumentRegistrationOptions + NotebookDocumentSyncRegistrationOptions = TextDocumentRegistrationOptions +) + +// TextDocumentRegistrationOptions registration options for text document scoped +// capabilities. +type TextDocumentRegistrationOptions struct { + DocumentSelector LSPAny `json:"documentSelector,omitempty"` +} + +// NotebookDocumentSyncOptions server options for notebook synchronization. +// +// @since 3.17.0 +type NotebookDocumentSyncOptions struct { + NotebookSelector []NotebookDocumentSyncOptionsNotebookSelector `json:"notebookSelector"` + Save bool `json:"save,omitempty"` +} + +// NotebookDocumentSyncOptionsNotebookSelector selects matching notebooks and +// cell languages. +// +// @since 3.17.0 +type NotebookDocumentSyncOptionsNotebookSelector struct { + Notebook any `json:"notebook,omitempty"` // string | NotebookDocumentFilter + Cells []NotebookDocumentSyncOptionsNotebookSelectorCells `json:"cells,omitempty"` +} + +// NotebookDocumentSyncOptionsNotebookSelectorCells cell language selector. +// +// @since 3.17.0 +type NotebookDocumentSyncOptionsNotebookSelectorCells struct { + Language string `json:"language"` +} + +// NotebookDocumentFilter selects notebooks by type, scheme and pattern. +// +// @since 3.17.0 +type NotebookDocumentFilter struct { + NotebookType string `json:"notebookType,omitempty"` + Scheme string `json:"scheme,omitempty"` + Pattern string `json:"pattern,omitempty"` } diff --git a/capabilities_server_test.go b/capabilities_server_test.go index c345436..7deb521 100644 --- a/capabilities_server_test.go +++ b/capabilities_server_test.go @@ -93,3 +93,229 @@ func Test_CapabilitiesServer_MarshalOmitEmptyFields(t *testing.T) { t.Fatalf("expected empty JSON object from zero-value capabilities, got: %s", string(data)) } } + +func Test_CapabilitiesServer_UnmarshalExtendedFields(t *testing.T) { + data := []byte(`{ + "textDocumentSync": { + "openClose": true, + "change": 2, + "save": {"includeText": true} + }, + "notebookDocumentSync": { + "notebookSelector": [ + { + "notebook": {"notebookType": "jupyter-notebook"}, + "cells": [{"language": "python"}] + } + ], + "save": true + }, + "hoverProvider": {"workDoneProgress": true}, + "declarationProvider": true, + "typeDefinitionProvider": {"workDoneProgress": true}, + "implementationProvider": true, + "referencesProvider": {"workDoneProgress": true}, + "documentHighlightProvider": true, + "documentSymbolProvider": {"workDoneProgress": true}, + "codeActionProvider": {"codeActionKinds": ["quickfix"], "resolveProvider": true}, + "codeLensProvider": {"resolveProvider": true}, + "documentLinkProvider": {"resolveProvider": true}, + "colorProvider": true, + "documentFormattingProvider": true, + "documentRangeFormattingProvider": true, + "documentOnTypeFormattingProvider": {"firstTriggerCharacter": ";", "moreTriggerCharacter": [","]}, + "renameProvider": {"prepareProvider": true}, + "foldingRangeProvider": true, + "executeCommandProvider": {"commands": ["laravel.run"], "workDoneProgress": true}, + "selectionRangeProvider": {"workDoneProgress": true}, + "linkedEditingRangeProvider": true, + "callHierarchyProvider": true, + "semanticTokensProvider": { + "legend": {"tokenTypes": ["class"], "tokenModifiers": ["declaration"]}, + "full": true + }, + "monikerProvider": true, + "typeHierarchyProvider": true, + "inlineValueProvider": true, + "inlayHintProvider": {"resolveProvider": true}, + "workspaceSymbolProvider": {"resolveProvider": true}, + "workspace": { + "workspaceFolders": {"supported": true, "changeNotifications": "workspaceFolders"}, + "fileOperations": { + "didCreate": { + "filters": [ + {"scheme": "file", "pattern": {"glob": "**/*.go"}} + ] + } + } + } + }`) + + var decoded protocol.ServerCapabilities + if err := json.Unmarshal(data, &decoded); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + if decoded.CodeLensProvider == nil || !decoded.CodeLensProvider.ResolveProvider { + t.Fatalf("expected codeLensProvider.resolveProvider=true") + } + + if decoded.DocumentLinkProvider == nil || !decoded.DocumentLinkProvider.ResolveProvider { + t.Fatalf("expected documentLinkProvider.resolveProvider=true") + } + + if decoded.DocumentOnTypeFormattingProvider == nil || decoded.DocumentOnTypeFormattingProvider.FirstTriggerCharacter != ";" { + t.Fatalf("expected documentOnTypeFormattingProvider.firstTriggerCharacter=';' got %#v", decoded.DocumentOnTypeFormattingProvider) + } + + if decoded.ExecuteCommandProvider == nil || len(decoded.ExecuteCommandProvider.Commands) != 1 || decoded.ExecuteCommandProvider.Commands[0] != "laravel.run" { + t.Fatalf("expected executeCommandProvider.commands to contain laravel.run") + } + + if decoded.Workspace == nil || decoded.Workspace.WorkspaceFolders == nil || !decoded.Workspace.WorkspaceFolders.Supported { + t.Fatalf("expected workspace.workspaceFolders.supported=true") + } + + tds, ok := decoded.TextDocumentSync.(map[string]any) + if !ok { + t.Fatalf("expected textDocumentSync object, got %#v", decoded.TextDocumentSync) + } + + if openClose, ok := tds["openClose"].(bool); !ok || !openClose { + t.Fatalf("expected textDocumentSync.openClose=true, got %#v", tds["openClose"]) + } + + hover, ok := decoded.HoverProvider.(map[string]any) + if !ok { + t.Fatalf("expected hoverProvider object, got %#v", decoded.HoverProvider) + } + + if wdp, ok := hover["workDoneProgress"].(bool); !ok || !wdp { + t.Fatalf("expected hoverProvider.workDoneProgress=true, got %#v", hover["workDoneProgress"]) + } + + if decl, ok := decoded.DeclarationProvider.(bool); !ok || !decl { + t.Fatalf("expected declarationProvider=true, got %#v", decoded.DeclarationProvider) + } + + if sem, ok := decoded.SemanticTokensProvider.(map[string]any); !ok || sem["legend"] == nil { + t.Fatalf("expected semanticTokensProvider.legend, got %#v", decoded.SemanticTokensProvider) + } +} + +func Test_CapabilitiesServer_MarshalExtendedFields(t *testing.T) { + resolve := true + original := protocol.ServerCapabilities{ + PositionEncoding: &[]protocol.PositionEncodingKind{protocol.PositionEncodingKindUTF16}[0], + TextDocumentSync: protocol.TextDocumentSyncOptions{ + OpenClose: true, + Change: protocol.TextDocumentSyncKindIncremental, + Save: protocol.SaveOptions{IncludeText: true}, + }, + HoverProvider: protocol.HoverOptions{WorkDoneProgress: true}, + CompletionProvider: &protocol.CompletionOptions{ + ResolveProvider: &resolve, + CompletionItem: &protocol.CompletionOptionsCompletionItem{ + LabelDetailsSupport: &resolve, + }, + }, + DeclarationProvider: protocol.DeclarationOptions{WorkDoneProgress: true}, + DefinitionProvider: true, + CodeActionProvider: protocol.CodeActionOptions{ + CodeActionKinds: []protocol.CodeActionKind{protocol.CodeActionQuickFix}, + ResolveProvider: true, + }, + CodeLensProvider: &protocol.CodeLensOptions{ResolveProvider: true}, + DocumentLinkProvider: &protocol.DocumentLinkOptions{ + ResolveProvider: true, + }, + DocumentOnTypeFormattingProvider: &protocol.DocumentOnTypeFormattingOptions{ + FirstTriggerCharacter: ";", + MoreTriggerCharacter: []string{","}, + }, + RenameProvider: protocol.RenameOptions{PrepareProvider: true}, + ExecuteCommandProvider: &protocol.ExecuteCommandOptions{ + Commands: []string{"laravel.run"}, + }, + SemanticTokensProvider: protocol.SemanticTokensOptions{ + Legend: protocol.SemanticTokensLegend{ + TokenTypes: []string{"class"}, + TokenModifiers: []string{"declaration"}, + }, + Full: true, + }, + DiagnosticProvider: protocol.DiagnosticOptions{ + InterFileDependencies: true, + WorkspaceDiagnostics: true, + }, + WorkspaceSymbolProvider: protocol.WorkspaceSymbolOptions{ResolveProvider: true}, + Workspace: &protocol.WorkspaceServerCapabilities{ + WorkspaceFolders: &protocol.WorkspaceFoldersServerCapabilities{ + Supported: true, + ChangeNotifications: "workspaceFolders", + }, + FileOperations: &protocol.FileOperationOptions{ + DidCreate: &protocol.FileOperationRegistrationOptions{ + Filters: []protocol.FileOperationFilter{{ + Scheme: "file", + Pattern: protocol.FileOperationPattern{ + Glob: "**/*.go", + }, + }}, + }, + }, + }, + } + + data, err := json.Marshal(original) + if err != nil { + t.Fatalf("marshal failed: %v", err) + } + + var payload map[string]any + if err := json.Unmarshal(data, &payload); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + if _, ok := payload["textDocumentSync"]; !ok { + t.Fatalf("expected textDocumentSync in payload: %s", string(data)) + } + + if _, ok := payload["hoverProvider"]; !ok { + t.Fatalf("expected hoverProvider in payload: %s", string(data)) + } + + if _, ok := payload["declarationProvider"]; !ok { + t.Fatalf("expected declarationProvider in payload: %s", string(data)) + } + + if _, ok := payload["codeLensProvider"]; !ok { + t.Fatalf("expected codeLensProvider in payload: %s", string(data)) + } + + if _, ok := payload["documentOnTypeFormattingProvider"]; !ok { + t.Fatalf("expected documentOnTypeFormattingProvider in payload: %s", string(data)) + } + + if _, ok := payload["semanticTokensProvider"]; !ok { + t.Fatalf("expected semanticTokensProvider in payload: %s", string(data)) + } + + workspace, ok := payload["workspace"].(map[string]any) + if !ok { + t.Fatalf("expected workspace object, got %#v", payload["workspace"]) + } + + if _, ok := workspace["workspaceFolders"]; !ok { + t.Fatalf("expected workspace.workspaceFolders in payload: %s", string(data)) + } + + fileOps, ok := workspace["fileOperations"].(map[string]any) + if !ok { + t.Fatalf("expected workspace.fileOperations object, got %#v", workspace["fileOperations"]) + } + + if _, ok := fileOps["didCreate"]; !ok { + t.Fatalf("expected workspace.fileOperations.didCreate in payload: %s", string(data)) + } +} diff --git a/document_diagnostic.go b/document_diagnostic.go index 5f3a1f7..cecd39f 100644 --- a/document_diagnostic.go +++ b/document_diagnostic.go @@ -6,7 +6,8 @@ import ( ) const ( - MethodTextDocumentDiagnostic = "textDocument/diagnostic" + MethodTextDocumentDiagnostic = "textDocument/diagnostic" + MethodTextDocumentPublishDiagnostics = "textDocument/publishDiagnostics" ) // DocumentDiagnosticParams - Parameters of the document diagnostic request. @@ -29,6 +30,24 @@ type DocumentDiagnosticParams struct { PreviousResultID string `json:"previousResultId,omitempty"` } +// PublishDiagnosticsParams - The parameters of a publish diagnostics notification. +// +// @since 3.0.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#publishDiagnosticsParams +type PublishDiagnosticsParams struct { + // The URI for which diagnostic information is reported. + URI DocumentURI `json:"uri"` + + // Optional the version number of the document the diagnostics are published for. + // + // @since 3.15.0 + Version int `json:"version,omitempty"` + + // An array of diagnostic information items. + Diagnostics []Diagnostic `json:"diagnostics"` +} + // DocumentDiagnosticReport is either a full or an unchanged diagnostic report. // // @since 3.17.0 diff --git a/document_diagnostic_test.go b/document_diagnostic_test.go index e6fb2b5..1e2c140 100644 --- a/document_diagnostic_test.go +++ b/document_diagnostic_test.go @@ -24,3 +24,26 @@ func Test_DocumentDiagnostic_StructsUnmarshalValidJSON(t *testing.T) { t.Fatalf("unexpected DocumentDiagnosticReport: %+v", report) } } + +func Test_PublishDiagnosticsParams_UnmarshalValidJSON(t *testing.T) { + var params protocol.PublishDiagnosticsParams + if err := json.Unmarshal([]byte(`{ + "uri":"file:///tmp/main.go", + "version":2, + "diagnostics":[{"range":{"start":{"line":1,"character":1},"end":{"line":1,"character":3}},"message":"example diagnostic"}] + }`), ¶ms); err != nil { + t.Fatalf("unmarshal PublishDiagnosticsParams failed: %v", err) + } + + if params.URI != "file:///tmp/main.go" { + t.Fatalf("unexpected URI: %q", params.URI) + } + + if params.Version != 2 { + t.Fatalf("unexpected Version: %d", params.Version) + } + + if len(params.Diagnostics) != 1 || params.Diagnostics[0].Message != "example diagnostic" { + t.Fatalf("unexpected Diagnostics: %+v", params.Diagnostics) + } +} diff --git a/inlay_hints.go b/inlay_hints.go new file mode 100644 index 0000000..a294657 --- /dev/null +++ b/inlay_hints.go @@ -0,0 +1,207 @@ +package protocol + +import ( + "encoding/json" + "errors" +) + +const ( + // MethodTextDocumentInlayHint method name of `textDocument/inlayHint`. + MethodTextDocumentInlayHint = "textDocument/inlayHint" +) + +// InlayHintParams - Parameters for a `textDocument/inlayHint` request. +// +// @since 3.17.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintParams +type InlayHintParams struct { + WorkDoneProgressParams + PartialResultParams + + // The text document. + TextDocument TextDocumentIdentifier `json:"textDocument"` + + // The visible range for which inlay hints should be computed. + Range Range `json:"range"` +} + +// InlayHintKind - The kind of an inlay hint. +// +// @since 3.17.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintKind +type InlayHintKind int + +const ( + // InlayHintKindType - An inlay hint that shows a type annotation. + InlayHintKindType InlayHintKind = 1 + + // InlayHintKindParameter - An inlay hint that shows a parameter name. + InlayHintKindParameter InlayHintKind = 2 +) + +// InlayHintTooltip can be a plain string or a MarkupContent object. +// +// @since 3.17.0 +type InlayHintTooltip struct { + String *string + MarkupContent *MarkupContent +} + +func (t InlayHintTooltip) MarshalJSON() ([]byte, error) { + if t.String != nil { + return json.Marshal(*t.String) + } + if t.MarkupContent != nil { + return json.Marshal(t.MarkupContent) + } + return []byte("null"), nil +} + +func (t *InlayHintTooltip) UnmarshalJSON(data []byte) error { + *t = InlayHintTooltip{} + + if string(data) == "null" { + return nil + } + + var str string + if err := json.Unmarshal(data, &str); err == nil { + t.String = &str + return nil + } + + var markup MarkupContent + if err := json.Unmarshal(data, &markup); err == nil && markup.Kind != "" { + t.MarkupContent = &markup + return nil + } + + return errors.New("invalid InlayHintTooltip: not string, MarkupContent, or null") +} + +// InlayHintLabelPart - A segment of an inlay hint label. +// +// @since 3.17.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHintLabelPart +type InlayHintLabelPart struct { + // The mandatory label value. + Value string `json:"value"` + + // The tooltip text or markup shown when hovering this label part. + Tooltip *InlayHintTooltip `json:"tooltip,omitempty"` + + // A source location for this label part. + Location *Location `json:"location,omitempty"` + + // A command associated with this label part. + Command *Command `json:"command,omitempty"` +} + +// InlayHintLabel can be either a string or a list of label parts. +// +// @since 3.17.0 +type InlayHintLabel struct { + String *string + Parts []InlayHintLabelPart +} + +func (l InlayHintLabel) MarshalJSON() ([]byte, error) { + if l.String != nil { + return json.Marshal(*l.String) + } + if l.Parts != nil { + return json.Marshal(l.Parts) + } + return nil, errors.New("one of InlayHintLabel.String or InlayHintLabel.Parts needs to be set") +} + +func (l *InlayHintLabel) UnmarshalJSON(data []byte) error { + *l = InlayHintLabel{} + + var str string + if err := json.Unmarshal(data, &str); err == nil { + l.String = &str + return nil + } + + var parts []InlayHintLabelPart + if err := json.Unmarshal(data, &parts); err == nil { + l.Parts = parts + return nil + } + + return errors.New("invalid InlayHintLabel: not string or []InlayHintLabelPart") +} + +// InlayHint represents an inlay hint item. +// +// @since 3.17.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint +type InlayHint struct { + // The position of this hint. + Position Position `json:"position"` + + // The label of this hint. A human readable string or an array of label parts. + Label InlayHintLabel `json:"label"` + + // The kind of this hint. + Kind *InlayHintKind `json:"kind,omitempty"` + + // Optional text edits that are performed when accepting this hint. + TextEdits []TextEdit `json:"textEdits,omitempty"` + + // The tooltip text when hovering over this hint. + Tooltip *InlayHintTooltip `json:"tooltip,omitempty"` + + // Render padding before this hint. + PaddingLeft *bool `json:"paddingLeft,omitempty"` + + // Render padding after this hint. + PaddingRight *bool `json:"paddingRight,omitempty"` + + // A data entry field preserved between a hint request and resolve request. + Data LSPAny `json:"data,omitempty"` +} + +// InlayHintResponse - Result for a `textDocument/inlayHint` request. +// +// It is either an array of `InlayHint` or `null`. +// +// @since 3.17.0 +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#inlayHint +type InlayHintResponse struct { + Hints []InlayHint + Null bool +} + +func (r InlayHintResponse) MarshalJSON() ([]byte, error) { + if r.Null { + return []byte("null"), nil + } + if r.Hints == nil { + return []byte("null"), nil + } + return json.Marshal(r.Hints) +} + +func (r *InlayHintResponse) UnmarshalJSON(data []byte) error { + *r = InlayHintResponse{} + + if string(data) == "null" { + r.Null = true + return nil + } + + var hints []InlayHint + if err := json.Unmarshal(data, &hints); err == nil { + r.Hints = hints + return nil + } + + return errors.New("invalid inlay hint response: not null or []InlayHint") +} diff --git a/inlay_hints_test.go b/inlay_hints_test.go new file mode 100644 index 0000000..02b2fc8 --- /dev/null +++ b/inlay_hints_test.go @@ -0,0 +1,158 @@ +package protocol_test + +import ( + "encoding/json" + "testing" + + "github.com/laravel-ls/protocol" +) + +func Test_InlayHint_ParamsUnmarshalValidJSON(t *testing.T) { + data := []byte(`{"textDocument":{"uri":"file:///tmp/main.go"},"range":{"start":{"line":1,"character":2},"end":{"line":1,"character":8}}}`) + + var params protocol.InlayHintParams + if err := json.Unmarshal(data, ¶ms); err != nil { + t.Fatalf("unmarshal InlayHintParams failed: %v", err) + } + + if params.TextDocument.URI != "file:///tmp/main.go" { + t.Fatalf("unexpected textDocument URI: %q", params.TextDocument.URI) + } + + if params.Range.Start.Line != 1 || params.Range.End.Character != 8 { + t.Fatalf("unexpected range: %+v", params.Range) + } +} + +func Test_InlayHintLabel_UnmarshalString(t *testing.T) { + var label protocol.InlayHintLabel + if err := json.Unmarshal([]byte(`"x:"`), &label); err != nil { + t.Fatalf("unmarshal InlayHintLabel string failed: %v", err) + } + + if label.String == nil || *label.String != "x:" { + t.Fatalf("expected string label 'x:', got %+v", label) + } + + if label.Parts != nil { + t.Fatalf("expected parts to be nil for string label") + } +} + +func Test_InlayHintLabel_UnmarshalParts(t *testing.T) { + data := []byte(`[{"value":"name"},{"value":":","tooltip":"separator"}]`) + + var label protocol.InlayHintLabel + if err := json.Unmarshal(data, &label); err != nil { + t.Fatalf("unmarshal InlayHintLabel parts failed: %v", err) + } + + if len(label.Parts) != 2 { + t.Fatalf("expected 2 label parts, got %d", len(label.Parts)) + } + + if label.Parts[1].Tooltip == nil || label.Parts[1].Tooltip.String == nil || *label.Parts[1].Tooltip.String != "separator" { + t.Fatalf("expected second part tooltip string to be set, got %+v", label.Parts[1].Tooltip) + } +} + +func Test_InlayHintTooltip_UnmarshalMarkupContent(t *testing.T) { + data := []byte(`{"kind":"markdown","value":"**hint**"}`) + + var tooltip protocol.InlayHintTooltip + if err := json.Unmarshal(data, &tooltip); err != nil { + t.Fatalf("unmarshal InlayHintTooltip markup failed: %v", err) + } + + if tooltip.MarkupContent == nil || tooltip.MarkupContent.Kind != protocol.MarkupKindMarkdown { + t.Fatalf("expected markdown tooltip, got %+v", tooltip) + } +} + +func Test_InlayHint_UnmarshalTypedObject(t *testing.T) { + data := []byte(`{ + "position": {"line": 2, "character": 10}, + "label": [{"value":"x"},{"value":":","tooltip":{"kind":"plaintext","value":"type separator"}}], + "kind": 1, + "textEdits": [{"range":{"start":{"line":2,"character":8},"end":{"line":2,"character":9}},"newText":"value"}], + "tooltip": "inferred type", + "paddingLeft": true, + "paddingRight": false, + "data": {"id": 42} + }`) + + var hint protocol.InlayHint + if err := json.Unmarshal(data, &hint); err != nil { + t.Fatalf("unmarshal InlayHint failed: %v", err) + } + + if hint.Position.Line != 2 || hint.Position.Character != 10 { + t.Fatalf("unexpected position: %+v", hint.Position) + } + + if hint.Kind == nil || *hint.Kind != protocol.InlayHintKindType { + t.Fatalf("expected kind=InlayHintKindType, got %+v", hint.Kind) + } + + if hint.Tooltip == nil || hint.Tooltip.String == nil || *hint.Tooltip.String != "inferred type" { + t.Fatalf("expected tooltip string 'inferred type', got %+v", hint.Tooltip) + } + + if len(hint.TextEdits) != 1 { + t.Fatalf("expected 1 text edit, got %d", len(hint.TextEdits)) + } +} + +func Test_InlayHintResponse_UnmarshalArrayAndNull(t *testing.T) { + var list protocol.InlayHintResponse + if err := json.Unmarshal([]byte(`[{"position":{"line":0,"character":1},"label":"x:"}]`), &list); err != nil { + t.Fatalf("unmarshal InlayHintResponse array failed: %v", err) + } + + if list.Null { + t.Fatalf("expected non-null response for array") + } + + if len(list.Hints) != 1 { + t.Fatalf("expected 1 hint, got %d", len(list.Hints)) + } + + var nullRes protocol.InlayHintResponse + if err := json.Unmarshal([]byte(`null`), &nullRes); err != nil { + t.Fatalf("unmarshal InlayHintResponse null failed: %v", err) + } + + if !nullRes.Null { + t.Fatalf("expected null response flag to be true") + } +} + +func Test_InlayHintResponse_MarshalArrayAndNull(t *testing.T) { + response := protocol.InlayHintResponse{ + Hints: []protocol.InlayHint{{ + Position: protocol.Position{Line: 0, Character: 0}, + Label: func() protocol.InlayHintLabel { + label := "a" + return protocol.InlayHintLabel{String: &label} + }(), + }}, + } + + data, err := json.Marshal(response) + if err != nil { + t.Fatalf("marshal InlayHintResponse array failed: %v", err) + } + + if string(data) == "null" { + t.Fatalf("expected array JSON, got null") + } + + nullData, err := json.Marshal(protocol.InlayHintResponse{Null: true}) + if err != nil { + t.Fatalf("marshal InlayHintResponse null failed: %v", err) + } + + if string(nullData) != "null" { + t.Fatalf("expected null JSON, got %s", string(nullData)) + } +}