diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp --- a/clang-tools-extra/clangd/ClangdLSPServer.cpp +++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp @@ -611,7 +611,8 @@ ? llvm::json::Object{{"codeActionKinds", {CodeAction::QUICKFIX_KIND, CodeAction::REFACTOR_KIND, - CodeAction::INFO_KIND}}} + CodeAction::INFO_KIND, + CodeAction::SOURCE_ORGANIZE_IMPORT}}} : llvm::json::Value(true); @@ -988,6 +989,26 @@ } } } + if (KindAllowed(CodeAction::SOURCE_ORGANIZE_IMPORT)) { + std::lock_guard Lock(FixItsMutex); + if (auto FileFixItsIter = FixItsMap.find(File.file()); + FileFixItsIter != FixItsMap.end()) { + std::vector Edits; + for (auto &[Diag, Fixes] : FileFixItsIter->second) { + if (Diag.source == "clangd" && Diag.code == "unused-includes") + for (auto &F : Fixes) + std::copy(F.Edits.begin(), F.Edits.end(), + std::back_inserter(Edits)); + } + if (!Edits.empty()) { + FixIts.emplace_back(); + FixIts.back().title = "remove unusded includes"; + FixIts.back().kind = std::string(CodeAction::SOURCE_ORGANIZE_IMPORT); + FixIts.back().edit.emplace(); + FixIts.back().edit->changes[File.uri()] = std::move(Edits); + } + } + } // Now enumerate the semantic code actions. auto ConsumeActions = diff --git a/clang-tools-extra/clangd/Protocol.h b/clang-tools-extra/clangd/Protocol.h --- a/clang-tools-extra/clangd/Protocol.h +++ b/clang-tools-extra/clangd/Protocol.h @@ -1022,6 +1022,7 @@ const static llvm::StringLiteral QUICKFIX_KIND; const static llvm::StringLiteral REFACTOR_KIND; const static llvm::StringLiteral INFO_KIND; + const static llvm::StringLiteral SOURCE_ORGANIZE_IMPORT; /// The diagnostics that this code action resolves. std::optional> diagnostics; diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp --- a/clang-tools-extra/clangd/Protocol.cpp +++ b/clang-tools-extra/clangd/Protocol.cpp @@ -819,6 +819,7 @@ const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix"; const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor"; const llvm::StringLiteral CodeAction::INFO_KIND = "info"; +const llvm::StringLiteral CodeAction::SOURCE_ORGANIZE_IMPORT = "source.organizeImports"; llvm::json::Value toJSON(const CodeAction &CA) { auto CodeAction = llvm::json::Object{{"title", CA.title}};