Index: clangd/ClangdLSPServer.h =================================================================== --- clangd/ClangdLSPServer.h +++ clangd/ClangdLSPServer.h @@ -69,6 +69,8 @@ void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) override; void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) override; void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) override; + void onChangeConfiguration(Ctx C, + DidChangeConfigurationParams &Params) override; std::vector getFixIts(StringRef File, const clangd::Diagnostic &D); Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -47,7 +47,8 @@ "codeActionProvider": true, "completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">",":"]}, "signatureHelpProvider": {"triggerCharacters": ["(",","]}, - "definitionProvider": true + "definitionProvider": true, + "configurationChangeProvider": true }})"); if (Params.rootUri && !Params.rootUri->file.empty()) Server.setRootPath(Params.rootUri->file); @@ -193,6 +194,20 @@ C.reply(Result ? URI::unparse(URI::fromFile(*Result)) : R"("")"); } +void ClangdLSPServer::onChangeConfiguration( + Ctx C, DidChangeConfigurationParams &Params) { + std::map SettingsMap; + SettingsMap.insert(std::pair( + "CDBPath", Params.settings.compilationDatabasePath.getValue())); + CDB.setCompileCommandsDir(Params.settings.compilationDatabasePath.getValue()); + CDB.getCompilationDatabase(StringRef(CDB.getCompileCommandsDir().getValue())); + + // There is nothing in this function yet but any change in settings that needs + // to be trickled down to the ClangdServer instance needs to be added to the + // map and sent with this function call. + Server.changeConfiguration(SettingsMap); +} + ClangdLSPServer::ClangdLSPServer(JSONOutput &Out, unsigned AsyncThreadsCount, bool SnippetCompletions, llvm::Optional ResourceDir, Index: clangd/ClangdServer.h =================================================================== --- clangd/ClangdServer.h +++ clangd/ClangdServer.h @@ -284,6 +284,10 @@ /// given a header file and vice versa. llvm::Optional switchSourceHeader(PathRef Path); + /// Modify configuration settings based on what is contained inside + /// ChangedSettings + void changeConfiguration(std::map ChangedSettings); + /// Run formatting for \p Rng inside \p File. std::vector formatRange(PathRef File, Range Rng); /// Run formatting for the whole \p File. Index: clangd/ClangdServer.cpp =================================================================== --- clangd/ClangdServer.cpp +++ clangd/ClangdServer.cpp @@ -434,6 +434,14 @@ return llvm::None; } +// Empty function for now. Once more settings can be handled by server instance they will be processed here. + +void ClangdServer::changeConfiguration( + std::map ChangedSettings) { + if (!ChangedSettings.empty()) { + } +} + std::future ClangdServer::scheduleReparseAndDiags( PathRef File, VersionedDraft Contents, std::shared_ptr Resources, Tagged> TaggedFS) { Index: clangd/GlobalCompilationDatabase.h =================================================================== --- clangd/GlobalCompilationDatabase.h +++ clangd/GlobalCompilationDatabase.h @@ -52,11 +52,14 @@ std::vector getCompileCommands(PathRef File) override; + llvm::Optional getCompileCommandsDir() { return CompileCommandsDir; } + void setCompileCommandsDir(Path P) { CompileCommandsDir = P; } + + tooling::CompilationDatabase *getCompilationDatabase(PathRef File); void setExtraFlagsForFile(PathRef File, std::vector ExtraFlags); private: - tooling::CompilationDatabase *getCompilationDatabase(PathRef File); tooling::CompilationDatabase *tryLoadDatabaseFromPath(PathRef File); std::mutex Mutex; Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -273,6 +273,27 @@ parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger); }; +struct ClangdConfigurationParams { + + llvm::Optional compilationDatabasePath; + static llvm::Optional + parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger); +}; + +struct DidChangeConfigurationParams { + + DidChangeConfigurationParams() {} + + DidChangeConfigurationParams(ClangdConfigurationParams settings) + : settings(settings) {} + + ClangdConfigurationParams settings; + + static llvm::Optional + parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger); + static std::string unparse(const DidChangeConfigurationParams &P); +}; + struct FormattingOptions { /// Size of a tab in spaces. int tabSize; Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -531,6 +531,59 @@ return Result; } +llvm::Optional +DidChangeConfigurationParams::parse(llvm::yaml::MappingNode *Params, + clangd::Logger &Logger) { + DidChangeConfigurationParams Result; + for (auto &NextKeyValue : *Params) { + auto *KeyString = dyn_cast(NextKeyValue.getKey()); + if (!KeyString) + return llvm::None; + + llvm::SmallString<10> KeyStorage; + StringRef KeyValue = KeyString->getValue(KeyStorage); + auto *Value = + dyn_cast_or_null(NextKeyValue.getValue()); + if (!Value) + return llvm::None; + + llvm::SmallString<10> Storage; + if (KeyValue == "settings") { + auto Parsed = ClangdConfigurationParams::parse(Value, Logger); + if (!Parsed) + return llvm::None; + Result.settings = Parsed.getValue(); + } else { + logIgnoredField(KeyValue, Logger); + } + } + + return Result; +} + +llvm::Optional +ClangdConfigurationParams::parse(llvm::yaml::MappingNode *Params, + clangd::Logger &Logger) { + ClangdConfigurationParams Result; + for (auto &NextKeyValue : *Params) { + auto *KeyString = dyn_cast(NextKeyValue.getKey()); + if (!KeyString) + return llvm::None; + + llvm::SmallString<10> KeyStorage; + StringRef KeyValue = KeyString->getValue(KeyStorage); + auto *Value = + dyn_cast_or_null(NextKeyValue.getValue()); + if (!Value) + return llvm::None; + + if (KeyValue == "compilationDatabasePath") { + Result.compilationDatabasePath = Value->getValue(KeyStorage); + } + } + return Result; +} + llvm::Optional TextDocumentContentChangeEvent::parse(llvm::yaml::MappingNode *Params, clangd::Logger &Logger) { Index: clangd/ProtocolHandlers.h =================================================================== --- clangd/ProtocolHandlers.h +++ clangd/ProtocolHandlers.h @@ -52,6 +52,8 @@ virtual void onGoToDefinition(Ctx C, TextDocumentPositionParams &Params) = 0; virtual void onSwitchSourceHeader(Ctx C, TextDocumentIdentifier &Params) = 0; virtual void onFileEvent(Ctx C, DidChangeWatchedFilesParams &Params) = 0; + virtual void onChangeConfiguration(Ctx C, + DidChangeConfigurationParams &Params) = 0; }; void registerCallbackHandlers(JSONRPCDispatcher &Dispatcher, JSONOutput &Out, Index: clangd/ProtocolHandlers.cpp =================================================================== --- clangd/ProtocolHandlers.cpp +++ clangd/ProtocolHandlers.cpp @@ -72,4 +72,6 @@ Register("textDocument/switchSourceHeader", &ProtocolCallbacks::onSwitchSourceHeader); Register("workspace/didChangeWatchedFiles", &ProtocolCallbacks::onFileEvent); + Register("workspace/didChangeConfiguration", + &ProtocolCallbacks::onChangeConfiguration); }