From 5eca1ff8736f37abb51179b893d172038b5f715d Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 10 Nov 2022 13:33:25 +0100 Subject: [PATCH] LanguageClient: use internal filtering if we got all completions ... at the current position. This reduces the amount of requested completions. Change-Id: I0fa35269bc123513217e3b3abd2c921bd92d8d10 Reviewed-by: Christian Kandeler --- .../languageclientcompletionassist.cpp | 9 ++++++- .../texteditor/codeassist/codeassistant.cpp | 26 +++++++++++++------ .../texteditor/codeassist/iassistproposal.cpp | 8 +++--- .../texteditor/codeassist/iassistproposal.h | 8 +++--- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index 2c757d7808f..02875c55249 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -411,9 +411,11 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( } QList items; + bool isComplete = false; if (std::holds_alternative(*result)) { const auto &list = std::get(*result); items = list.items().value_or(QList()); + isComplete = !list.isIncomplete(); } else if (std::holds_alternative>(*result)) { items = std::get>(*result); } @@ -428,7 +430,12 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( model); proposal->m_document = m_assistInterface->textDocument(); proposal->m_pos = m_pos; - proposal->setSupportsPrefix(false); + const QString completePrefix = Utils::Text::textAt(QTextCursor(m_document), + m_basePos, + m_pos - m_basePos); + proposal->setPrefixChecker([isComplete, completePrefix](const QString &candidate) { + return isComplete && candidate.startsWith(completePrefix); + }); setAsyncProposalAvailable(proposal); m_client->removeAssistProcessor(this); qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : " diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp index 819a68d64aa..c38c0a6724f 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.cpp +++ b/src/plugins/texteditor/codeassist/codeassistant.cpp @@ -51,6 +51,7 @@ public: void displayProposal(IAssistProposal *newProposal, AssistReason reason); bool isDisplayingProposal() const; bool isWaitingForProposal() const; + QString proposalPrefix() const; void notifyChange(); bool hasContext() const; @@ -134,7 +135,7 @@ void CodeAssistantPrivate::invoke(AssistKind kind, IAssistProvider *provider) stopAutomaticProposalTimer(); if (isDisplayingProposal() && m_assistKind == kind && !m_proposal->isFragile() - && m_proposal->supportsPrefix()) { + && m_proposal->supportsPrefixFiltering(proposalPrefix())) { m_proposalWidget->setReason(ExplicitlyInvoked); m_proposalWidget->updateProposal(m_editorWidget->textAt( m_proposal->basePosition(), @@ -426,6 +427,14 @@ bool CodeAssistantPrivate::isWaitingForProposal() const return m_requestRunner != nullptr || m_asyncProcessor != nullptr; } +QString CodeAssistantPrivate::proposalPrefix() const +{ + if (!isDisplayingProposal()) + return {}; + return m_editorWidget->textAt(m_proposal->basePosition(), + m_editorWidget->position() - m_proposal->basePosition()); +} + void CodeAssistantPrivate::invalidateCurrentRequestData() { m_asyncProcessor = nullptr; @@ -468,14 +477,15 @@ void CodeAssistantPrivate::notifyChange() QTC_ASSERT(m_proposal, return); if (m_editorWidget->position() < m_proposal->basePosition()) { destroyContext(); - } else if (m_proposal->supportsPrefix()) { - m_proposalWidget->updateProposal( - m_editorWidget->textAt(m_proposal->basePosition(), - m_editorWidget->position() - m_proposal->basePosition())); - if (!isDisplayingProposal()) - requestActivationCharProposal(); } else { - requestProposal(m_proposal->reason(), m_assistKind, m_requestProvider, true); + const QString prefix = proposalPrefix(); + if (m_proposal->supportsPrefixFiltering(prefix)) { + m_proposalWidget->updateProposal(prefix); + if (!isDisplayingProposal()) + requestActivationCharProposal(); + } else { + requestProposal(m_proposal->reason(), m_assistKind, m_requestProvider, true); + } } } } diff --git a/src/plugins/texteditor/codeassist/iassistproposal.cpp b/src/plugins/texteditor/codeassist/iassistproposal.cpp index 24f85f4cfd5..b2c7dffc9f3 100644 --- a/src/plugins/texteditor/codeassist/iassistproposal.cpp +++ b/src/plugins/texteditor/codeassist/iassistproposal.cpp @@ -68,9 +68,9 @@ bool IAssistProposal::isFragile() const return m_isFragile; } -bool IAssistProposal::supportsPrefix() const +bool IAssistProposal::supportsPrefixFiltering(const QString &prefix) const { - return m_supportsPrefix; + return !m_prefixChecker || m_prefixChecker(prefix); } /*! @@ -103,9 +103,9 @@ void IAssistProposal::setFragile(bool fragile) m_isFragile = fragile; } -void IAssistProposal::setSupportsPrefix(bool supportsPrefix) +void IAssistProposal::setPrefixChecker(const PrefixChecker checker) { - m_supportsPrefix = supportsPrefix; + m_prefixChecker = checker; } /*! diff --git a/src/plugins/texteditor/codeassist/iassistproposal.h b/src/plugins/texteditor/codeassist/iassistproposal.h index 946b98c8aab..5c64a880665 100644 --- a/src/plugins/texteditor/codeassist/iassistproposal.h +++ b/src/plugins/texteditor/codeassist/iassistproposal.h @@ -23,7 +23,7 @@ public: int basePosition() const; bool isFragile() const; - bool supportsPrefix() const; + bool supportsPrefixFiltering(const QString &prefix) const; virtual bool hasItemsToPropose(const QString &, AssistReason) const { return true; } virtual bool isCorrective(TextEditorWidget *editorWidget) const; virtual void makeCorrection(TextEditorWidget *editorWidget); @@ -31,18 +31,20 @@ public: virtual IAssistProposalWidget *createWidget() const = 0; void setFragile(bool fragile); - void setSupportsPrefix(bool supportsPrefix); Utils::Id id() const { return m_id; } AssistReason reason() const { return m_reason; } void setReason(const AssistReason &reason) { m_reason = reason; } + using PrefixChecker = std::function; + void setPrefixChecker(const PrefixChecker checker); + protected: Utils::Id m_id; int m_basePosition; bool m_isFragile = false; - bool m_supportsPrefix = true; + PrefixChecker m_prefixChecker; AssistReason m_reason = IdleEditor; };