aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/texteditor/codeassist
diff options
context:
space:
mode:
authorDavid Schulz <david.schulz@qt.io>2022-11-17 14:53:47 +0100
committerDavid Schulz <david.schulz@qt.io>2022-11-29 06:04:30 +0000
commit0bd6d7a69fab1cc622f6e00ee63a15c666967e0d (patch)
tree2ba2bf7299b1fb0bb387e2ac919e1965261ca571 /src/plugins/texteditor/codeassist
parent8ff969d14995d1b81b1704bf203f142f50c5a9e7 (diff)
LanguageClient: move completion rerequest logic
...from the code assistant to the language client specific assist implementation. This further reduces the complexity of the code assistant. Change-Id: I08ba5eecea826d3ccfe7f1f5a8791a085299d6ef Reviewed-by: Christian Kandeler <christian.kandeler@qt.io> Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: David Schulz <david.schulz@qt.io>
Diffstat (limited to 'src/plugins/texteditor/codeassist')
-rw-r--r--src/plugins/texteditor/codeassist/codeassistant.cpp84
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposal.cpp4
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp6
-rw-r--r--src/plugins/texteditor/codeassist/functionhintproposalwidget.h3
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalwidget.cpp17
-rw-r--r--src/plugins/texteditor/codeassist/genericproposalwidget.h5
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposal.cpp20
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposal.h13
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposalwidget.cpp7
-rw-r--r--src/plugins/texteditor/codeassist/iassistproposalwidget.h17
10 files changed, 62 insertions, 114 deletions
diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp
index 8f583e4d38..db5553b03f 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.cpp
+++ b/src/plugins/texteditor/codeassist/codeassistant.cpp
@@ -77,12 +77,10 @@ private:
private:
CodeAssistant *q = nullptr;
TextEditorWidget *m_editorWidget = nullptr;
- QMetaObject::Connection m_runnerConnection;
IAssistProvider *m_requestProvider = nullptr;
IAssistProcessor *m_processor = nullptr;
AssistKind m_assistKind = TextEditor::Completion;
IAssistProposalWidget *m_proposalWidget = nullptr;
- QScopedPointer<IAssistProposal> m_proposal;
bool m_receivedContentWhileWaiting = false;
QTimer m_automaticProposalTimer;
CompletionSettings m_settings;
@@ -117,12 +115,11 @@ void CodeAssistantPrivate::invoke(AssistKind kind, IAssistProvider *provider)
{
stopAutomaticProposalTimer();
- if (isDisplayingProposal() && m_assistKind == kind && !m_proposal->isFragile()
- && m_proposal->supportsPrefixFiltering(proposalPrefix())) {
+ if (isDisplayingProposal() && m_assistKind == kind && !m_proposalWidget->isFragile()) {
m_proposalWidget->setReason(ExplicitlyInvoked);
- m_proposalWidget->updateProposal(m_editorWidget->textAt(
- m_proposal->basePosition(),
- m_editorWidget->position() - m_proposal->basePosition()));
+ m_proposalWidget->filterProposal(m_editorWidget->textAt(
+ m_proposalWidget->basePosition(),
+ m_editorWidget->position() - m_proposalWidget->basePosition()));
} else {
requestProposal(ExplicitlyInvoked, kind, provider);
}
@@ -239,14 +236,12 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
return;
// TODO: The proposal should own the model until someone takes it explicitly away.
- QScopedPointer<IAssistProposal> proposalCandidate(newProposal);
+ QScopedPointer<IAssistProposal> deleter(newProposal);
- if (isDisplayingProposal() && !m_proposal->isFragile()
- && !m_proposalWidget->supportsModelUpdate(proposalCandidate->id())) {
+ if (isDisplayingProposal() && !m_proposalWidget->isFragile())
return;
- }
- int basePosition = proposalCandidate->basePosition();
+ int basePosition = newProposal->basePosition();
if (m_editorWidget->position() < basePosition) {
destroyContext();
return;
@@ -266,28 +261,16 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
return;
}
- if (m_proposalWidget
- && basePosition == proposalCandidate->basePosition()
- && m_proposalWidget->supportsModelUpdate(proposalCandidate->id())) {
- m_proposal.reset(proposalCandidate.take());
- m_proposal->setReason(reason);
- m_proposalWidget->updateModel(m_proposal->model());
- m_proposalWidget->updateProposal(prefix);
- return;
- }
-
destroyContext();
clearAbortedPosition();
- m_proposal.reset(proposalCandidate.take());
- m_proposal->setReason(reason);
- if (m_proposal->isCorrective(m_editorWidget))
- m_proposal->makeCorrection(m_editorWidget);
+ if (newProposal->isCorrective(m_editorWidget))
+ newProposal->makeCorrection(m_editorWidget);
m_editorWidget->keepAutoCompletionHighlight(true);
- basePosition = m_proposal->basePosition();
- m_proposalWidget = m_proposal->createWidget();
+ basePosition = newProposal->basePosition();
+ m_proposalWidget = newProposal->createWidget();
connect(m_proposalWidget, &QObject::destroyed,
this, &CodeAssistantPrivate::finalizeProposal);
connect(m_proposalWidget, &IAssistProposalWidget::prefixExpanded,
@@ -301,7 +284,7 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
m_proposalWidget->setKind(m_assistKind);
m_proposalWidget->setBasePosition(basePosition);
m_proposalWidget->setUnderlyingWidget(m_editorWidget);
- m_proposalWidget->setModel(m_proposal->model());
+ m_proposalWidget->setModel(newProposal->model());
m_proposalWidget->setDisplayRect(m_editorWidget->cursorRect(basePosition));
m_proposalWidget->setIsSynchronized(!m_receivedContentWhileWaiting);
m_proposalWidget->showProposal(prefix);
@@ -309,9 +292,9 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *proposalItem)
{
- QTC_ASSERT(m_proposal, return);
+ QTC_ASSERT(m_proposalWidget, return);
TextDocumentManipulator manipulator(m_editorWidget);
- proposalItem->apply(manipulator, m_proposal->basePosition());
+ proposalItem->apply(manipulator, m_proposalWidget->basePosition());
destroyContext();
m_editorWidget->encourageApply();
if (!proposalItem->isSnippet())
@@ -320,34 +303,33 @@ void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *prop
void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix)
{
- QTC_ASSERT(m_proposal, return);
+ QTC_ASSERT(m_proposalWidget, return);
QTextCursor cursor(m_editorWidget->document());
- cursor.setPosition(m_proposal->basePosition());
+ cursor.setPosition(m_proposalWidget->basePosition());
cursor.movePosition(QTextCursor::EndOfWord);
int currentPosition = m_editorWidget->position();
const QString textAfterCursor = m_editorWidget->textAt(currentPosition,
cursor.position() - currentPosition);
if (!textAfterCursor.startsWith(newPrefix)) {
- if (newPrefix.indexOf(textAfterCursor, currentPosition - m_proposal->basePosition()) >= 0)
+ if (newPrefix.indexOf(textAfterCursor, currentPosition - m_proposalWidget->basePosition()) >= 0)
currentPosition = cursor.position();
const QStringView prefixAddition = QStringView(newPrefix).mid(currentPosition
- - m_proposal->basePosition());
+ - m_proposalWidget->basePosition());
// If remaining string starts with the prefix addition
if (textAfterCursor.startsWith(prefixAddition))
currentPosition += prefixAddition.size();
}
- m_editorWidget->setCursorPosition(m_proposal->basePosition());
- m_editorWidget->replace(currentPosition - m_proposal->basePosition(), newPrefix);
+ m_editorWidget->setCursorPosition(m_proposalWidget->basePosition());
+ m_editorWidget->replace(currentPosition - m_proposalWidget->basePosition(), newPrefix);
notifyChange();
}
void CodeAssistantPrivate::finalizeProposal()
{
stopAutomaticProposalTimer();
- m_proposal.reset();
m_proposalWidget = nullptr;
if (m_receivedContentWhileWaiting)
m_receivedContentWhileWaiting = false;
@@ -367,8 +349,8 @@ QString CodeAssistantPrivate::proposalPrefix() const
{
if (!isDisplayingProposal())
return {};
- return m_editorWidget->textAt(m_proposal->basePosition(),
- m_editorWidget->position() - m_proposal->basePosition());
+ return m_editorWidget->textAt(m_proposalWidget->basePosition(),
+ m_editorWidget->position() - m_proposalWidget->basePosition());
}
void CodeAssistantPrivate::invalidateCurrentRequestData()
@@ -409,18 +391,14 @@ void CodeAssistantPrivate::notifyChange()
stopAutomaticProposalTimer();
if (isDisplayingProposal()) {
- QTC_ASSERT(m_proposal, return);
- if (m_editorWidget->position() < m_proposal->basePosition()) {
+ QTC_ASSERT(m_proposalWidget, return);
+ if (m_editorWidget->position() < m_proposalWidget->basePosition()) {
destroyContext();
} else {
- 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);
- }
+ m_proposalWidget->updateProposal(
+ m_editorWidget->createAssistInterface(m_assistKind, m_proposalWidget->reason()));
+ if (!isDisplayingProposal())
+ requestActivationCharProposal();
}
}
}
@@ -466,7 +444,7 @@ void CodeAssistantPrivate::automaticProposalTimeout()
{
if (isWaitingForProposal()
|| m_editorWidget->multiTextCursor().hasMultipleCursors()
- || (isDisplayingProposal() && !m_proposal->isFragile())) {
+ || (isDisplayingProposal() && !m_proposalWidget->isFragile())) {
return;
}
@@ -488,8 +466,8 @@ void CodeAssistantPrivate::updateFromCompletionSettings(
void CodeAssistantPrivate::explicitlyAborted()
{
- QTC_ASSERT(m_proposal, return);
- m_abortedBasePosition = m_proposal->basePosition();
+ QTC_ASSERT(m_proposalWidget, return);
+ m_abortedBasePosition = m_proposalWidget->basePosition();
}
void CodeAssistantPrivate::clearAbortedPosition()
diff --git a/src/plugins/texteditor/codeassist/functionhintproposal.cpp b/src/plugins/texteditor/codeassist/functionhintproposal.cpp
index 5c713d2330..fcc3b247eb 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposal.cpp
+++ b/src/plugins/texteditor/codeassist/functionhintproposal.cpp
@@ -12,9 +12,7 @@ using namespace TextEditor;
FunctionHintProposal::FunctionHintProposal(int cursorPos, FunctionHintProposalModelPtr model)
: IAssistProposal(functionHintId, cursorPos)
, m_model(model)
-{
- setFragile(true);
-}
+{}
FunctionHintProposal::~FunctionHintProposal() = default;
diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
index 5811c100c8..e6753c4605 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp
@@ -138,6 +138,7 @@ FunctionHintProposalWidget::FunctionHintProposalWidget()
});
setFocusPolicy(Qt::NoFocus);
+ setFragile(true);
}
FunctionHintProposalWidget::~FunctionHintProposalWidget()
@@ -150,9 +151,6 @@ void FunctionHintProposalWidget::setAssistant(CodeAssistant *assistant)
d->m_assistant = assistant;
}
-void FunctionHintProposalWidget::setReason(AssistReason)
-{}
-
void FunctionHintProposalWidget::setKind(AssistKind)
{}
@@ -190,7 +188,7 @@ void FunctionHintProposalWidget::showProposal(const QString &prefix)
d->m_popupFrame->show();
}
-void FunctionHintProposalWidget::updateProposal(const QString &prefix)
+void FunctionHintProposalWidget::filterProposal(const QString &prefix)
{
updateAndCheck(prefix);
}
diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.h b/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
index 28813ccf8c..97580ede24 100644
--- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
+++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.h
@@ -19,7 +19,6 @@ public:
~FunctionHintProposalWidget() override;
void setAssistant(CodeAssistant *assistant) override;
- void setReason(AssistReason reason) override;
void setKind(AssistKind kind) override;
void setUnderlyingWidget(const QWidget *underlyingWidget) override;
void setModel(ProposalModelPtr model) override;
@@ -27,7 +26,7 @@ public:
void setIsSynchronized(bool isSync) override;
void showProposal(const QString &prefix) override;
- void updateProposal(const QString &prefix) override;
+ void filterProposal(const QString &prefix) override;
void closeProposal() override;
bool proposalIsVisible() const override;
diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
index 83fe23404f..9eb3fdcd37 100644
--- a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp
@@ -249,7 +249,6 @@ public:
QRect m_displayRect;
bool m_isSynchronized = true;
bool m_explicitlySelected = false;
- AssistReason m_reason = IdleEditor;
AssistKind m_kind = Completion;
bool m_justInvoked = false;
QPointer<GenericProposalInfoFrame> m_infoFrame;
@@ -358,9 +357,9 @@ void GenericProposalWidget::setAssistant(CodeAssistant *assistant)
void GenericProposalWidget::setReason(AssistReason reason)
{
- d->m_reason = reason;
- if (d->m_reason == ExplicitlyInvoked)
+ if (reason == ExplicitlyInvoked)
d->m_justInvoked = true;
+ IAssistProposalWidget::setReason(reason);
}
void GenericProposalWidget::setKind(AssistKind kind)
@@ -393,11 +392,6 @@ void GenericProposalWidget::setIsSynchronized(bool isSync)
d->m_isSynchronized = isSync;
}
-bool GenericProposalWidget::supportsModelUpdate(const Utils::Id &proposalId) const
-{
- return proposalId == Constants::GENERIC_PROPOSAL_ID;
-}
-
void GenericProposalWidget::updateModel(ProposalModelPtr model)
{
QString currentText;
@@ -418,6 +412,7 @@ void GenericProposalWidget::updateModel(ProposalModelPtr model)
d->m_completionListView->selectRow(currentRow);
else
d->m_explicitlySelected = false;
+ updatePositionAndSize();
}
void GenericProposalWidget::showProposal(const QString &prefix)
@@ -431,7 +426,7 @@ void GenericProposalWidget::showProposal(const QString &prefix)
d->m_completionListView->setFocus();
}
-void GenericProposalWidget::updateProposal(const QString &prefix)
+void GenericProposalWidget::filterProposal(const QString &prefix)
{
if (!isVisible())
return;
@@ -470,7 +465,7 @@ bool GenericProposalWidget::updateAndCheck(const QString &prefix)
if (!prefix.isEmpty())
d->m_model->filter(prefix);
}
- if (!d->m_model->hasItemsToPropose(prefix, d->m_reason)) {
+ if (!d->m_model->hasItemsToPropose(prefix, reason())) {
d->m_completionListView->reset();
abort();
return false;
@@ -660,7 +655,7 @@ bool GenericProposalWidget::eventFilter(QObject *o, QEvent *e)
AssistProposalItemInterface *item =
d->m_model->proposalItem(d->m_completionListView->currentIndex().row());
if (item->prematurelyApplies(typedChar)
- && (d->m_reason == ExplicitlyInvoked || item->text().endsWith(typedChar))) {
+ && (reason() == ExplicitlyInvoked || item->text().endsWith(typedChar))) {
abort();
emit proposalItemActivated(item);
return true;
diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.h b/src/plugins/texteditor/codeassist/genericproposalwidget.h
index 901a8b1dfe..c38ccc9f47 100644
--- a/src/plugins/texteditor/codeassist/genericproposalwidget.h
+++ b/src/plugins/texteditor/codeassist/genericproposalwidget.h
@@ -31,11 +31,10 @@ public:
void setDisplayRect(const QRect &rect) override;
void setIsSynchronized(bool isSync) override;
- bool supportsModelUpdate(const Utils::Id &proposalId) const override;
- void updateModel(ProposalModelPtr model) override;
+ void updateModel(ProposalModelPtr model);
void showProposal(const QString &prefix) override;
- void updateProposal(const QString &prefix) override;
+ void filterProposal(const QString &prefix) override;
void closeProposal() override;
private:
diff --git a/src/plugins/texteditor/codeassist/iassistproposal.cpp b/src/plugins/texteditor/codeassist/iassistproposal.cpp
index b2c7dffc9f..d6918ba797 100644
--- a/src/plugins/texteditor/codeassist/iassistproposal.cpp
+++ b/src/plugins/texteditor/codeassist/iassistproposal.cpp
@@ -63,16 +63,6 @@ int IAssistProposal::basePosition() const
return m_basePosition;
}
-bool IAssistProposal::isFragile() const
-{
- return m_isFragile;
-}
-
-bool IAssistProposal::supportsPrefixFiltering(const QString &prefix) const
-{
- return !m_prefixChecker || m_prefixChecker(prefix);
-}
-
/*!
\fn bool TextEditor::IAssistProposal::isCorrective() const
@@ -98,16 +88,6 @@ void IAssistProposal::makeCorrection(TextEditorWidget *editorWidget)
Q_UNUSED(editorWidget)
}
-void IAssistProposal::setFragile(bool fragile)
-{
- m_isFragile = fragile;
-}
-
-void IAssistProposal::setPrefixChecker(const PrefixChecker checker)
-{
- m_prefixChecker = checker;
-}
-
/*!
\fn IAssistModel *TextEditor::IAssistProposal::model() const
diff --git a/src/plugins/texteditor/codeassist/iassistproposal.h b/src/plugins/texteditor/codeassist/iassistproposal.h
index 5c64a88066..1761fc29bf 100644
--- a/src/plugins/texteditor/codeassist/iassistproposal.h
+++ b/src/plugins/texteditor/codeassist/iassistproposal.h
@@ -22,30 +22,17 @@ public:
virtual ~IAssistProposal();
int basePosition() const;
- bool isFragile() 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);
virtual TextEditor::ProposalModelPtr model() const = 0;
virtual IAssistProposalWidget *createWidget() const = 0;
- void setFragile(bool fragile);
-
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;
- PrefixChecker m_prefixChecker;
- AssistReason m_reason = IdleEditor;
};
} // TextEditor
diff --git a/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp b/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
index f1ea7428eb..fe5e3d823d 100644
--- a/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
+++ b/src/plugins/texteditor/codeassist/iassistproposalwidget.cpp
@@ -3,6 +3,8 @@
#include "iassistproposalwidget.h"
+#include "assistinterface.h"
+
using namespace TextEditor;
/*!
@@ -30,6 +32,11 @@ IAssistProposalWidget::IAssistProposalWidget()
: QFrame(nullptr, Qt::Popup)
{}
+void IAssistProposalWidget::updateProposal(std::unique_ptr<AssistInterface> &&interface)
+{
+ filterProposal(interface->textAt(m_basePosition, interface->position() - m_basePosition));
+}
+
IAssistProposalWidget::~IAssistProposalWidget() = default;
int IAssistProposalWidget::basePosition() const
diff --git a/src/plugins/texteditor/codeassist/iassistproposalwidget.h b/src/plugins/texteditor/codeassist/iassistproposalwidget.h
index fafe1b48b4..68600b399c 100644
--- a/src/plugins/texteditor/codeassist/iassistproposalwidget.h
+++ b/src/plugins/texteditor/codeassist/iassistproposalwidget.h
@@ -14,8 +14,9 @@ namespace Utils { class Id; }
namespace TextEditor {
-class CodeAssistant;
+class AssistInterface;
class AssistProposalItemInterface;
+class CodeAssistant;
class TEXTEDITOR_EXPORT IAssistProposalWidget : public QFrame
{
@@ -26,7 +27,7 @@ public:
~IAssistProposalWidget() override;
virtual void setAssistant(CodeAssistant *assistant) = 0;
- virtual void setReason(AssistReason reason) = 0;
+ virtual void setReason(AssistReason reason) { m_reason = reason; }
virtual void setKind(AssistKind kind) = 0;
virtual void setUnderlyingWidget(const QWidget *underlyingWidget) = 0;
virtual void setModel(ProposalModelPtr model) = 0;
@@ -34,16 +35,20 @@ public:
virtual void setIsSynchronized(bool isSync) = 0;
virtual void showProposal(const QString &prefix) = 0;
- virtual void updateProposal(const QString &prefix) = 0;
+ virtual void filterProposal(const QString &prefix) = 0;
+ virtual void updateProposal(std::unique_ptr<AssistInterface> &&interface);
virtual void closeProposal() = 0;
virtual bool proposalIsVisible() const { return isVisible(); }
- virtual bool supportsModelUpdate(const Utils::Id &/*proposalId*/) const { return false; }
- virtual void updateModel(ProposalModelPtr) {}
int basePosition() const;
void setBasePosition(int basePosition);
+ void setFragile(bool fragile) { m_isFragile = fragile; }
+ bool isFragile() const { return m_isFragile; }
+
+ AssistReason reason() const { return m_reason; }
+
signals:
void prefixExpanded(const QString &newPrefix);
void proposalItemActivated(AssistProposalItemInterface *proposalItem);
@@ -51,6 +56,8 @@ signals:
protected:
int m_basePosition = -1;
+ bool m_isFragile = false;
+ AssistReason m_reason = IdleEditor;
};
} // TextEditor