From a137f2b23d9cde2fb87296847ec5fd28d76c1f67 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 8 Aug 2023 15:30:55 +0200 Subject: [PATCH] LanguageClient: cancel find link at requests on rerequest This avoids triggering the callback if we already requested a find link at for a different position. Additionally we also cancel the request if the document changes or the cursor moves inbetween requesting the link and receiving the response. Change-Id: Iffc7b08012a649397e7ca7dfc99d314a1bbf19f7 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.cpp | 22 +++++++++++++++++++ src/plugins/languageclient/client.h | 7 ++++++ .../languageclient/languageclientmanager.cpp | 2 +- .../languageclientsymbolsupport.cpp | 11 +++++----- .../languageclientsymbolsupport.h | 2 +- 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index ff646316e02..444d0d7589b 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -328,6 +328,7 @@ public: ProjectExplorer::Project *m_project = nullptr; QSet m_runningAssistProcessors; SymbolSupport m_symbolSupport; + MessageId m_runningFindLinkRequest; ProgressManager m_progressManager; bool m_activateDocAutomatically = false; SemanticTokenSupport m_tokenSupport; @@ -1112,6 +1113,8 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document, { if (!d->m_openedDocument.contains(document) || !reachable()) return; + if (d->m_runningFindLinkRequest.isValid()) + cancelRequest(d->m_runningFindLinkRequest); if (d->m_diagnosticManager) d->m_diagnosticManager->disableDiagnostics(document); const QString method(DidChangeTextDocumentNotification::methodName); @@ -1252,6 +1255,8 @@ TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget) { + if (d->m_runningFindLinkRequest.isValid()) + cancelRequest(d->m_runningFindLinkRequest); TextEditor::TextDocument *document = widget->textDocument(); if (d->m_documentsToUpdate.find(document) != d->m_documentsToUpdate.end()) return; // we are currently changing this document so postpone the DocumentHighlightsRequest @@ -1274,6 +1279,23 @@ SymbolSupport &Client::symbolSupport() return d->m_symbolSupport; } +void Client::findLinkAt(TextEditor::TextDocument *document, + const QTextCursor &cursor, + Utils::LinkHandler callback, + const bool resolveTarget) +{ + if (d->m_runningFindLinkRequest.isValid()) + cancelRequest(d->m_runningFindLinkRequest); + d->m_runningFindLinkRequest = symbolSupport().findLinkAt( + document, + cursor, + [this, callback](const Link &link) { + d->m_runningFindLinkRequest = {}; + callback(link); + }, + resolveTarget); +} + void Client::requestCodeActions(const LanguageServerProtocol::DocumentUri &uri, const LanguageServerProtocol::Diagnostic &diagnostic) { diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 006559760c5..f0c071c2a1f 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -149,6 +149,13 @@ public: void addAssistProcessor(TextEditor::IAssistProcessor *processor); void removeAssistProcessor(TextEditor::IAssistProcessor *processor); SymbolSupport &symbolSupport(); + // In contrast to the findLinkAt of symbol support this find link makes sure that there is only + // one request running at a time and cancels the running request if the document changes, cursor + // moves or another link is requested + void findLinkAt(TextEditor::TextDocument *document, + const QTextCursor &cursor, + Utils::LinkHandler callback, + const bool resolveTarget); DocumentSymbolCache *documentSymbolCache(); HoverHandler *hoverHandler(); QList diagnosticsAt(const Utils::FilePath &filePath, diff --git a/src/plugins/languageclient/languageclientmanager.cpp b/src/plugins/languageclient/languageclientmanager.cpp index a71f09255aa..dd369cfd4dc 100644 --- a/src/plugins/languageclient/languageclientmanager.cpp +++ b/src/plugins/languageclient/languageclientmanager.cpp @@ -463,7 +463,7 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor) [document = textEditor->textDocument()] (const QTextCursor &cursor, const Utils::LinkHandler &callback, bool resolveTarget) { if (auto client = clientForDocument(document)) - client->symbolSupport().findLinkAt(document, cursor, callback, resolveTarget); + client->findLinkAt(document, cursor, callback, resolveTarget); }); connect(widget, &TextEditorWidget::requestUsages, this, [document = textEditor->textDocument()](const QTextCursor &cursor) { diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index 822d910ecf3..4ef534d7f3e 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -137,13 +137,13 @@ static TextDocumentPositionParams generateDocPosParams(TextEditor::TextDocument return TextDocumentPositionParams(documentId, pos); } -void SymbolSupport::findLinkAt(TextEditor::TextDocument *document, - const QTextCursor &cursor, - Utils::LinkHandler callback, - const bool resolveTarget) +MessageId SymbolSupport::findLinkAt(TextEditor::TextDocument *document, + const QTextCursor &cursor, + Utils::LinkHandler callback, + const bool resolveTarget) { if (!m_client->reachable()) - return; + return {}; GotoDefinitionRequest request(generateDocPosParams(document, cursor, m_client)); std::optional linkUnderCursor; if (!resolveTarget) { @@ -165,6 +165,7 @@ void SymbolSupport::findLinkAt(TextEditor::TextDocument *document, request, m_client->dynamicCapabilities(), m_client->capabilities()); + return request.id(); } bool SymbolSupport::supportsFindUsages(TextEditor::TextDocument *document) const diff --git a/src/plugins/languageclient/languageclientsymbolsupport.h b/src/plugins/languageclient/languageclientsymbolsupport.h index a46ac4273a3..a26c36e7ede 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.h +++ b/src/plugins/languageclient/languageclientsymbolsupport.h @@ -25,7 +25,7 @@ class LANGUAGECLIENT_EXPORT SymbolSupport : public QObject public: explicit SymbolSupport(Client *client); - void findLinkAt(TextEditor::TextDocument *document, + LanguageServerProtocol::MessageId findLinkAt(TextEditor::TextDocument *document, const QTextCursor &cursor, Utils::LinkHandler callback, const bool resolveTarget);