diff --git a/src/source_language_protocol.cpp b/src/source_language_protocol.cpp index 3a4c997..92504e4 100644 --- a/src/source_language_protocol.cpp +++ b/src/source_language_protocol.cpp @@ -216,6 +216,7 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize() { nullptr, "initialize", "\"processId\":" + std::to_string(process_id) + ",\"rootPath\":\"" + JSON::escape_string(root_path.string()) + "\",\"rootUri\":\"" + JSON::escape_string(filesystem::get_uri_from_path(root_path)) + R"(","capabilities": { "workspace": { "symbol": { "dynamicRegistration": false }, + "executeCommand": { "dynamicRegistration": false }, "workspaceFolders": true }, "textDocument": { @@ -246,10 +247,6 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize() { "references": { "dynamicRegistration": false }, "documentHighlight": { "dynamicRegistration": false }, "documentSymbol": { "dynamicRegistration": false }, - "formatting": { "dynamicRegistration": false }, - "rangeFormatting": { "dynamicRegistration": false }, - "rename": { "dynamicRegistration": false }, - "publishDiagnostics": { "relatedInformation":true }, "codeAction": { "dynamicRegistration": false, "resolveSupport": { @@ -270,7 +267,10 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize() { } } }, - "executeCommand": { "dynamicRegistration": false } + "formatting": { "dynamicRegistration": false }, + "rangeFormatting": { "dynamicRegistration": false }, + "rename": { "dynamicRegistration": false }, + "publishDiagnostics": { "relatedInformation":true } } }, "initializationOptions": { @@ -286,31 +286,39 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize() { else capabilities.text_document_sync = static_cast(child->integer_or("change", 0)); } - capabilities.hover = static_cast(object->child_optional("hoverProvider")); if(auto child = object->child_optional("completionProvider")) { capabilities.completion = true; capabilities.completion_resolve = child->boolean_or("resolveProvider", false); } + /// Some server capabilities are reported as either boolean or objects + auto boolean_or_object = [&object](const std::string &provider) { + if(auto child = object->child_optional(provider)) + return child->boolean_or(true); + return false; + }; + capabilities.hover = boolean_or_object("hoverProvider"); capabilities.signature_help = static_cast(object->child_optional("signatureHelpProvider")); - capabilities.definition = static_cast(object->child_optional("definitionProvider")); - capabilities.type_definition = static_cast(object->child_optional("typeDefinitionProvider")); - capabilities.implementation = static_cast(object->child_optional("implementationProvider")); - capabilities.references = static_cast(object->child_optional("referencesProvider")); - capabilities.document_highlight = static_cast(object->child_optional("documentHighlightProvider")); - capabilities.workspace_symbol = static_cast(object->child_optional("workspaceSymbolProvider")); - capabilities.document_symbol = static_cast(object->child_optional("documentSymbolProvider")); - capabilities.document_formatting = static_cast(object->child_optional("documentFormattingProvider")); - capabilities.document_range_formatting = static_cast(object->child_optional("documentRangeFormattingProvider")); - capabilities.rename = static_cast(object->child_optional("renameProvider")); + capabilities.definition = boolean_or_object("definitionProvider"); + capabilities.type_definition = boolean_or_object("typeDefinitionProvider"); + capabilities.implementation = boolean_or_object("implementationProvider"); + capabilities.references = boolean_or_object("referencesProvider"); + capabilities.document_highlight = boolean_or_object("documentHighlightProvider"); + capabilities.document_symbol = boolean_or_object("documentSymbolProvider"); if(auto child = object->child_optional("codeActionProvider")) { - capabilities.code_action = true; + capabilities.code_action = child->boolean_or(true); // Can be object as well capabilities.code_action_resolve = child->boolean_or("resolveProvider", false); } + capabilities.document_formatting = boolean_or_object("documentFormattingProvider"); + capabilities.document_range_formatting = boolean_or_object("documentRangeFormattingProvider"); + capabilities.rename = boolean_or_object("renameProvider"); capabilities.execute_command = static_cast(object->child_optional("executeCommandProvider")); capabilities.type_coverage = static_cast(object->child_optional("typeCoverageProvider")); + capabilities.workspace_symbol = boolean_or_object("workspaceSymbolProvider"); if(auto workspace = object->object_optional("workspace")) { - if(auto workspace_folders = workspace->object_optional("workspaceFolders")) - capabilities.workspace_folders = static_cast(workspace_folders->child_optional("changeNotifications")); + if(auto workspace_folders = workspace->object_optional("workspaceFolders")) { + if(auto change_notifications = workspace_folders->child_optional("changeNotifications")) + capabilities.workspace_folders = change_notifications->boolean_or(true); // Can be string as well + } } }