Index: clangd/ClangdLSPServer.cpp =================================================================== --- clangd/ClangdLSPServer.cpp +++ clangd/ClangdLSPServer.cpp @@ -12,6 +12,7 @@ #include "JSONRPCDispatcher.h" #include "SourceCode.h" #include "URI.h" +#include "clang/Basic/Version.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Errc.h" #include "llvm/Support/FormatVariadic.h" @@ -214,6 +215,28 @@ reply("Fix applied."); ApplyEdit(*Params.workspaceEdit); + } else if (Params.command == ExecuteCommandParams::CLANGD_SERVER_INFO) { + json::Object Info{ + {"version", getClangToolFullVersion("clangd")}, + }; + if (const auto *DynIndex = Server->dynamicIndex()) { + Info["dynamicIndex"] = json::Object{ + {"memory", int64_t(DynIndex->estimateMemoryUsage())}, + }; + } + json::Object TrackedFiles; + auto MemUse = Server->getUsedBytesPerFile(); + DenseMap MemUseMap = {MemUse.begin(), MemUse.end()}; + for (const auto &File : DraftMgr.getActiveFiles()) { + json::Object FileInfo; + if (auto Data = DraftMgr.getDraft(File)) + FileInfo["size"] = int64_t(Data->size()); + if (auto Mem = MemUseMap.lookup(File)) + FileInfo["memory"] = int64_t(Mem); + TrackedFiles[File] = std::move(FileInfo); + } + Info["files"] = std::move(TrackedFiles); + reply(std::move(Info)); } else { // We should not get here because ExecuteCommandParams would not have // parsed in the first place and this handler should not be called. But if Index: clangd/Protocol.h =================================================================== --- clangd/Protocol.h +++ clangd/Protocol.h @@ -661,6 +661,8 @@ struct ExecuteCommandParams { // Command to apply fix-its. Uses WorkspaceEdit as argument. const static llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND; + // Retrieve information about the server state. No arguments. + const static llvm::StringLiteral CLANGD_SERVER_INFO; /// The command identifier, e.g. CLANGD_APPLY_FIX_COMMAND std::string command; Index: clangd/Protocol.cpp =================================================================== --- clangd/Protocol.cpp +++ clangd/Protocol.cpp @@ -408,6 +408,8 @@ const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND = "clangd.applyFix"; +const llvm::StringLiteral ExecuteCommandParams::CLANGD_SERVER_INFO = + "clangd.serverInfo"; bool fromJSON(const json::Value &Params, ExecuteCommandParams &R) { json::ObjectMapper O(Params); if (!O || !O.map("command", R.command)) @@ -417,6 +419,8 @@ if (R.command == ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND) { return Args && Args->size() == 1 && fromJSON(Args->front(), R.workspaceEdit); + } else if (R.command == ExecuteCommandParams::CLANGD_SERVER_INFO) { + return true; // No args. } return false; // Unrecognized command. }