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 <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2023-08-08 15:30:55 +02:00
parent 098ddf11e8
commit a137f2b23d
5 changed files with 37 additions and 7 deletions

View File

@@ -328,6 +328,7 @@ public:
ProjectExplorer::Project *m_project = nullptr;
QSet<TextEditor::IAssistProcessor *> 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)
{

View File

@@ -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<LanguageServerProtocol::Diagnostic> diagnosticsAt(const Utils::FilePath &filePath,

View File

@@ -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) {

View File

@@ -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<Utils::Link> 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

View File

@@ -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);