[utilities/kate] addons/lspclient: lspclient: add support for pull diagnostics
Christoph Cullmann <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit eee1b3ea340d75942a1d408da721ef7532c38843 by Christoph Cullmann, on behalf of leia uwu.
Committed on 18/08/2026 at 18:04.
Pushed by cullmann into branch 'master'.
lspclient: add support for pull diagnostics
M +28 -0 addons/lspclient/lspclientpluginview.cpp
M +12 -0 addons/lspclient/lspclientprotocol.h
M +35 -0 addons/lspclient/lspclientserver.cpp
M +3 -0 addons/lspclient/lspclientserver.h
https://invent.kde.org/utilities/kate/-/commit/eee1b3ea340d75942a1d408da721ef7532c38843
diff --git a/addons/lspclient/lspclientpluginview.cpp b/addons/lspclient/lspclientpluginview.cpp
index 90a11bdf59..b0e34d7f45 100644
--- a/addons/lspclient/lspclientpluginview.cpp
+++ b/addons/lspclient/lspclientpluginview.cpp
@@ -416,6 +416,9 @@ class LSPClientPluginViewImpl : public QObject, public KXMLGUIClient
, m_lsp(lsp)
{
name = i18n("LSP");
+
+ m_viewTracker.reset(LSPClientViewTracker::new_(mainWin, 250, 0));
+ connect(m_viewTracker.get(), &LSPClientViewTracker::newState, this, &LSPDiagnosticProvider::onViewState);
}
QJsonObject suppressions(KTextEditor::Document *doc) const override
@@ -428,8 +431,33 @@ class LSPClientPluginViewImpl : public QObject, public KXMLGUIClient
return {};
}
+ void onViewState(KTextEditor::View *view, LSPClientViewTracker::State state)
+ {
+ // ignore cursor change events, we shouldn't even receive them because the motion timer is 0
+ // and the tracker ignores motion events if its 0, but just to be safe :)
+ if (state == LSPClientViewTracker::State::LineChanged)
+ return;
+
+ auto server = m_lsp->m_serverManager->findServer(view);
+ if (server && server->capabilities().diagnosticProvider) {
+ auto url = view->document()->url();
+
+ server->documentDiagnostic(url, this, [url, this](const LSPPullDiagnosticParams ¶ms) {
+ if (params.kind == LSPPullDiagnosticKind::Unchanged)
+ return;
+
+ FileDiagnostics diagnostics{
+ .uri = url,
+ .diagnostics = params.items,
+ };
+ Q_EMIT diagnosticsAdded(diagnostics);
+ });
+ }
+ }
+
private:
LSPClientPluginViewImpl *m_lsp;
+ std::unique_ptr<LSPClientViewTracker> m_viewTracker;
};
LSPDiagnosticProvider m_diagnosticProvider;
diff --git a/addons/lspclient/lspclientprotocol.h b/addons/lspclient/lspclientprotocol.h
index 17f97590ef..4cd9e2fa3e 100644
--- a/addons/lspclient/lspclientprotocol.h
+++ b/addons/lspclient/lspclientprotocol.h
@@ -121,6 +121,7 @@ struct LSPServerCapabilities {
LSPWorkspaceFoldersServerCapabilities workspaceFolders;
bool selectionRangeProvider = false;
bool inlayHintProvider = false;
+ bool diagnosticProvider = false;
};
enum class LSPMarkupKind {
@@ -318,6 +319,17 @@ using LSPDiagnostic = Diagnostic;
using LSPPublishDiagnosticsParams = FileDiagnostics;
+enum class LSPPullDiagnosticKind {
+ Full,
+ Unchanged
+};
+
+struct LSPPullDiagnosticParams {
+ LSPPullDiagnosticKind kind;
+ QString resultId;
+ QList<Diagnostic> items;
+};
+
enum class LSPMessageType {
Error = 1,
Warning = 2,
diff --git a/addons/lspclient/lspclientserver.cpp b/addons/lspclient/lspclientserver.cpp
index e8f0c6d056..d2a5626639 100644
--- a/addons/lspclient/lspclientserver.cpp
+++ b/addons/lspclient/lspclientserver.cpp
@@ -539,6 +539,7 @@ static void from_json(LSPServerCapabilities &caps, const rapidjson::Value &json)
from_json(caps.workspaceFolders, GetJsonObjectForKey(workspace, "workspaceFolders"));
caps.selectionRangeProvider = json.HasMember("selectionRangeProvider");
caps.inlayHintProvider = json.HasMember("inlayHintProvider");
+ caps.diagnosticProvider = json.HasMember("diagnosticProvider");
}
static QUrl urlFromRemote(const QString &s, bool normalize = true)
@@ -1243,6 +1244,24 @@ static LSPPublishDiagnosticsParams parseDiagnostics(const rapidjson::Value &resu
return ret;
}
+static LSPPullDiagnosticParams parsePullDiagnostics(const rapidjson::Value &result)
+{
+ LSPPullDiagnosticParams ret;
+
+ QString kind = GetStringValue(result, "kind");
+
+ ret.kind = kind == QStringLiteral("full") ? LSPPullDiagnosticKind::Full : LSPPullDiagnosticKind::Unchanged;
+
+ ret.resultId = GetStringValue(result, "resultId");
+
+ auto it = result.FindMember(MEMBER_ITEMS);
+ if (it != result.MemberEnd()) {
+ ret.items = parseDiagnosticsArray(it->value);
+ }
+
+ return ret;
+}
+
static LSPApplyWorkspaceEditParams parseApplyWorkspaceEditParams(const rapidjson::Value &result)
{
LSPApplyWorkspaceEditParams ret;
@@ -1838,6 +1857,10 @@ private:
}},
{QLatin1String("inlayHint"), QJsonObject{
{QLatin1String("dynamicRegistration"), false}
+ }},
+ {QLatin1String("diagnostic"), QJsonObject{
+ {QLatin1String("dynamicRegistration"), false},
+ {QLatin1String("relatedInformation"), true}
}}
},
},
@@ -2121,6 +2144,13 @@ public:
return send(init_request(QStringLiteral("textDocument/inlayHint"), params), h);
}
+ RequestHandle documentDiagnostic(const QUrl &document, const GenericReplyHandler &h)
+ {
+ PushCurrentServer g(q);
+ auto params = textDocumentParams(document);
+ return send(init_request(QStringLiteral("textDocument/diagnostic"), params), h);
+ }
+
void executeCommand(const LSPCommand &command)
{
PushCurrentServer g(q);
@@ -2573,6 +2603,11 @@ LSPClientServer::documentInlayHint(const QUrl &document, const LSPRange &range,
return d->documentInlayHint(document, range, make_handler(h, context, parseInlayHints));
}
+LSPClientServer::RequestHandle LSPClientServer::documentDiagnostic(const QUrl &document, const QObject *context, const DiagnosticReplayHandler &h)
+{
+ return d->documentDiagnostic(document, make_handler(h, context, parsePullDiagnostics));
+}
+
void LSPClientServer::executeCommand(const LSPCommand &command)
{
d->executeCommand(command);
diff --git a/addons/lspclient/lspclientserver.h b/addons/lspclient/lspclientserver.h
index 815a0c3ce0..5d293a6e95 100644
--- a/addons/lspclient/lspclientserver.h
+++ b/addons/lspclient/lspclientserver.h
@@ -74,6 +74,7 @@ using WorkspaceSymbolsReplyHandler = ReplyHandler<std::vector<LSPSymbolInformati
using SelectionRangeReplyHandler = ReplyHandler<QList<std::shared_ptr<LSPSelectionRange>>>;
using InlayHintsReplyHandler = ReplyHandler<std::vector<LSPInlayHint>>;
using ConfigurationReplyHandler = ReplyHandler<QList<QJsonValue>>;
+using DiagnosticReplayHandler = ReplyHandler<LSPPullDiagnosticParams>;
class LSPClientPlugin;
@@ -210,6 +211,8 @@ public:
RequestHandle documentInlayHint(const QUrl &document, const LSPRange &range, const QObject *context, const InlayHintsReplyHandler &h);
+ RequestHandle documentDiagnostic(const QUrl &document, const QObject *context, const DiagnosticReplayHandler &h);
+
void executeCommand(const LSPCommand &command);
// rust-analyzer specific