diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index cfa58315945..fe495d9eed6 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -1544,8 +1544,18 @@ void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams ¶ms) return; for (const Diagnostic &diagnostic : params.diagnostics()) { const ClangdDiagnostic clangdDiagnostic(diagnostic); - for (const CodeAction &action : clangdDiagnostic.codeActions().value_or(QList{})) - LanguageClient::updateCodeActionRefactoringMarker(this, action, uri); + const auto codeActions = clangdDiagnostic.codeActions(); + if (codeActions && !codeActions->isEmpty()) { + for (const CodeAction &action : *codeActions) + LanguageClient::updateCodeActionRefactoringMarker(this, action, uri); + } else { + // We know that there's only one kind of diagnostic for which clangd has + // a quickfix tweak, so let's not be wasteful. + const Diagnostic::Code code = diagnostic.code().value_or(Diagnostic::Code()); + const QString * const codeString = Utils::get_if(&code); + if (codeString && *codeString == "-Wswitch") + requestCodeActions(uri, diagnostic); + } } } diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 467cd021665..8158254163e 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -866,7 +866,19 @@ SymbolSupport &Client::symbolSupport() return m_symbolSupport; } +void Client::requestCodeActions(const LanguageServerProtocol::DocumentUri &uri, + const LanguageServerProtocol::Diagnostic &diagnostic) +{ + requestCodeActions(uri, diagnostic.range(), {diagnostic}); +} + void Client::requestCodeActions(const DocumentUri &uri, const QList &diagnostics) +{ + requestCodeActions(uri, {}, diagnostics); +} + +void Client::requestCodeActions(const DocumentUri &uri, const Range &range, + const QList &diagnostics) { const Utils::FilePath fileName = uri.toFilePath(); TextEditor::TextDocument *doc = TextEditor::TextDocument::textDocumentForFilePath(fileName); @@ -878,10 +890,14 @@ void Client::requestCodeActions(const DocumentUri &uri, const QList context.setDiagnostics(diagnostics); codeActionParams.setContext(context); codeActionParams.setTextDocument(TextDocumentIdentifier(uri)); - Position start(0, 0); - const QTextBlock &lastBlock = doc->document()->lastBlock(); - Position end(lastBlock.blockNumber(), lastBlock.length() - 1); - codeActionParams.setRange(Range(start, end)); + if (range.isEmpty()) { + Position start(0, 0); + const QTextBlock &lastBlock = doc->document()->lastBlock(); + Position end(lastBlock.blockNumber(), lastBlock.length() - 1); + codeActionParams.setRange(Range(start, end)); + } else { + codeActionParams.setRange(range); + } CodeActionRequest request(codeActionParams); request.setResponseCallback( [uri, self = QPointer(this)](const CodeActionRequest::Response &response) { diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index a689797a968..cffdbb0ac93 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -168,6 +168,8 @@ public: void updateConfiguration(const QJsonValue &configuration); // commands + void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri, + const LanguageServerProtocol::Diagnostic &diagnostic); void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri, const QList &diagnostics); void requestCodeActions(const LanguageServerProtocol::CodeActionRequest &request); @@ -253,6 +255,9 @@ private: void requestDocumentHighlightsNow(TextEditor::TextEditorWidget *widget); LanguageServerProtocol::SemanticRequestTypes supportedSemanticRequests(TextEditor::TextDocument *document) const; void handleSemanticTokens(const LanguageServerProtocol::SemanticTokens &tokens); + void requestCodeActions(const LanguageServerProtocol::DocumentUri &uri, + const LanguageServerProtocol::Range &range, + const QList &diagnostics); void documentClosed(Core::IDocument *document); virtual void handleDocumentClosed(TextEditor::TextDocument *) {}