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 <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-11-10 13:33:25 +01:00
parent 63a8218680
commit 5eca1ff873
4 changed files with 35 additions and 16 deletions

View File

@@ -411,9 +411,11 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
}
QList<CompletionItem> items;
bool isComplete = false;
if (std::holds_alternative<CompletionList>(*result)) {
const auto &list = std::get<CompletionList>(*result);
items = list.items().value_or(QList<CompletionItem>());
isComplete = !list.isIncomplete();
} else if (std::holds_alternative<QList<CompletionItem>>(*result)) {
items = std::get<QList<CompletionItem>>(*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() << " : "

View File

@@ -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,10 +477,10 @@ 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()));
} else {
const QString prefix = proposalPrefix();
if (m_proposal->supportsPrefixFiltering(prefix)) {
m_proposalWidget->updateProposal(prefix);
if (!isDisplayingProposal())
requestActivationCharProposal();
} else {
@@ -479,6 +488,7 @@ void CodeAssistantPrivate::notifyChange()
}
}
}
}
bool CodeAssistantPrivate::hasContext() const
{

View File

@@ -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;
}
/*!

View File

@@ -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<bool(const QString &)>;
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;
};