forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -81,7 +81,9 @@ private:
|
|||||||
class ClangdCompletionAssistProcessor : public LanguageClientCompletionAssistProcessor
|
class ClangdCompletionAssistProcessor : public LanguageClientCompletionAssistProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClangdCompletionAssistProcessor(ClangdClient *client, const QString &snippetsGroup);
|
ClangdCompletionAssistProcessor(ClangdClient *client,
|
||||||
|
const IAssistProvider *provider,
|
||||||
|
const QString &snippetsGroup);
|
||||||
~ClangdCompletionAssistProcessor();
|
~ClangdCompletionAssistProcessor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -164,7 +166,7 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
|
|||||||
: QString();
|
: QString();
|
||||||
qCDebug(clangdLogCompletion) << "creating proper completion processor"
|
qCDebug(clangdLogCompletion) << "creating proper completion processor"
|
||||||
<< (snippetsGroup.isEmpty() ? "without" : "with") << "snippets";
|
<< (snippetsGroup.isEmpty() ? "without" : "with") << "snippets";
|
||||||
return new ClangdCompletionAssistProcessor(m_client, snippetsGroup);
|
return new ClangdCompletionAssistProcessor(m_client, this, snippetsGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClangdCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const
|
bool ClangdCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const
|
||||||
@@ -554,8 +556,9 @@ QList<AssistProposalItemInterface *> CustomAssistProcessor::completeIncludePath(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClangdCompletionAssistProcessor::ClangdCompletionAssistProcessor(ClangdClient *client,
|
ClangdCompletionAssistProcessor::ClangdCompletionAssistProcessor(ClangdClient *client,
|
||||||
|
const IAssistProvider *provider,
|
||||||
const QString &snippetsGroup)
|
const QString &snippetsGroup)
|
||||||
: LanguageClientCompletionAssistProcessor(client, snippetsGroup)
|
: LanguageClientCompletionAssistProcessor(client, provider, snippetsGroup)
|
||||||
, m_client(client)
|
, m_client(client)
|
||||||
{
|
{
|
||||||
m_timer.start();
|
m_timer.start();
|
||||||
|
@@ -42,6 +42,7 @@ public:
|
|||||||
: TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR;
|
: TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR;
|
||||||
if (Core::Command *command = Core::ActionManager::command(id))
|
if (Core::Command *command = Core::ActionManager::command(id))
|
||||||
m_sequence = command->keySequence();
|
m_sequence = command->keySequence();
|
||||||
|
setFragile(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -169,9 +170,7 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor(const AssistInt
|
|||||||
VirtualFunctionProposal::VirtualFunctionProposal(
|
VirtualFunctionProposal::VirtualFunctionProposal(
|
||||||
int cursorPos, const QList<AssistProposalItemInterface *> &items, bool openInSplit)
|
int cursorPos, const QList<AssistProposalItemInterface *> &items, bool openInSplit)
|
||||||
: GenericProposal(cursorPos, items), m_openInSplit(openInSplit)
|
: GenericProposal(cursorPos, items), m_openInSplit(openInSplit)
|
||||||
{
|
{ }
|
||||||
setFragile(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
IAssistProposalWidget *VirtualFunctionProposal::createWidget() const
|
IAssistProposalWidget *VirtualFunctionProposal::createWidget() const
|
||||||
{
|
{
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <texteditor/codeassist/assistinterface.h>
|
#include <texteditor/codeassist/assistinterface.h>
|
||||||
#include <texteditor/codeassist/genericproposal.h>
|
#include <texteditor/codeassist/genericproposal.h>
|
||||||
#include <texteditor/codeassist/genericproposalmodel.h>
|
#include <texteditor/codeassist/genericproposalmodel.h>
|
||||||
|
#include <texteditor/codeassist/genericproposalwidget.h>
|
||||||
#include <texteditor/snippets/snippet.h>
|
#include <texteditor/snippets/snippet.h>
|
||||||
#include <texteditor/snippets/snippetassistcollector.h>
|
#include <texteditor/snippets/snippetassistcollector.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
@@ -224,6 +225,13 @@ public:
|
|||||||
bool supportsPrefixExpansion() const override { return false; }
|
bool supportsPrefixExpansion() const override { return false; }
|
||||||
|
|
||||||
QList<AssistProposalItemInterface *> items() const { return m_currentItems; }
|
QList<AssistProposalItemInterface *> items() const { return m_currentItems; }
|
||||||
|
|
||||||
|
bool isComplete(const QString prefix)
|
||||||
|
{ return m_completePrefix && prefix.startsWith(*m_completePrefix); }
|
||||||
|
void setCompletePrefix(const QString &completePrefix) { m_completePrefix = completePrefix; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::optional<QString> m_completePrefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool LanguageClientCompletionModel::isSortable(const QString &) const
|
bool LanguageClientCompletionModel::isSortable(const QString &) const
|
||||||
@@ -252,13 +260,85 @@ void LanguageClientCompletionModel::sort(const QString &prefix)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LanguageClientCompletionWidget : public GenericProposalWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LanguageClientCompletionWidget(const IAssistProvider *provider)
|
||||||
|
: m_provider(provider)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~LanguageClientCompletionWidget() { deleteCurrentProcessor(); }
|
||||||
|
|
||||||
|
void deleteCurrentProcessor()
|
||||||
|
{
|
||||||
|
if (m_processor) {
|
||||||
|
m_processor->cancel();
|
||||||
|
delete m_processor;
|
||||||
|
m_processor = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isComplete(const AssistInterface *interface)
|
||||||
|
{
|
||||||
|
const QString prefix = interface->textAt(basePosition(),
|
||||||
|
interface->position() - basePosition());
|
||||||
|
return static_cast<LanguageClientCompletionModel *>(model().data())->isComplete(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setProposal(IAssistProposal *proposal)
|
||||||
|
{
|
||||||
|
if (!proposal)
|
||||||
|
return;
|
||||||
|
updateModel(proposal->model());
|
||||||
|
delete proposal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateProposal(std::unique_ptr<AssistInterface> &&interface) override
|
||||||
|
{
|
||||||
|
deleteCurrentProcessor();
|
||||||
|
if (!m_provider || isComplete(interface.get())) {
|
||||||
|
GenericProposalWidget::updateProposal(std::move(interface));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto processor = m_provider->createProcessor(interface.get());
|
||||||
|
QTC_ASSERT(processor, return);
|
||||||
|
|
||||||
|
processor->setAsyncCompletionAvailableHandler([this, processor](IAssistProposal *proposal) {
|
||||||
|
QTC_ASSERT(processor == m_processor, return);
|
||||||
|
if (!processor->running()) {
|
||||||
|
// do not delete this processor directly since this function is called from within the processor
|
||||||
|
QMetaObject::invokeMethod(
|
||||||
|
QCoreApplication::instance(),
|
||||||
|
[processor] { delete processor; },
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
m_processor = nullptr;
|
||||||
|
}
|
||||||
|
setProposal(proposal);
|
||||||
|
});
|
||||||
|
|
||||||
|
setProposal(processor->start(std::move(interface)));
|
||||||
|
if (processor->running())
|
||||||
|
m_processor = processor;
|
||||||
|
else
|
||||||
|
delete processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointer<const IAssistProvider> m_provider;
|
||||||
|
std::optional<MessageId> m_currentRequestId;
|
||||||
|
IAssistProcessor *m_processor = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
class LanguageClientCompletionProposal : public GenericProposal
|
class LanguageClientCompletionProposal : public GenericProposal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LanguageClientCompletionProposal(int cursorPos, LanguageClientCompletionModel *model)
|
LanguageClientCompletionProposal(const IAssistProvider *provider,
|
||||||
|
int cursorPos,
|
||||||
|
LanguageClientCompletionModel *model)
|
||||||
: GenericProposal(cursorPos, GenericProposalModelPtr(model))
|
: GenericProposal(cursorPos, GenericProposalModelPtr(model))
|
||||||
, m_model(model)
|
, m_model(model)
|
||||||
{ }
|
, m_provider(provider)
|
||||||
|
{}
|
||||||
|
|
||||||
// IAssistProposal interface
|
// IAssistProposal interface
|
||||||
bool hasItemsToPropose(const QString &/*text*/, AssistReason reason) const override
|
bool hasItemsToPropose(const QString &/*text*/, AssistReason reason) const override
|
||||||
@@ -274,15 +354,21 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAssistProposalWidget *createWidget() const override
|
||||||
|
{
|
||||||
|
return new LanguageClientCompletionWidget(m_provider);
|
||||||
|
}
|
||||||
|
|
||||||
LanguageClientCompletionModel *m_model;
|
LanguageClientCompletionModel *m_model;
|
||||||
QPointer<QTextDocument> m_document;
|
QPointer<QTextDocument> m_document;
|
||||||
|
QPointer<const IAssistProvider> m_provider;
|
||||||
int m_pos = -1;
|
int m_pos = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
LanguageClientCompletionAssistProcessor::LanguageClientCompletionAssistProcessor(
|
LanguageClientCompletionAssistProcessor::LanguageClientCompletionAssistProcessor(
|
||||||
Client *client,
|
Client *client, const IAssistProvider *provider, const QString &snippetsGroup)
|
||||||
const QString &snippetsGroup)
|
|
||||||
: m_client(client)
|
: m_client(client)
|
||||||
|
, m_provider(provider)
|
||||||
, m_snippetsGroup(snippetsGroup)
|
, m_snippetsGroup(snippetsGroup)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -409,32 +495,36 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QString prefix = Utils::Text::textAt(QTextCursor(document()),
|
||||||
|
m_basePos,
|
||||||
|
m_pos - m_basePos);
|
||||||
|
|
||||||
QList<CompletionItem> items;
|
QList<CompletionItem> items;
|
||||||
bool isComplete = false;
|
bool isComplete = true;
|
||||||
if (std::holds_alternative<CompletionList>(*result)) {
|
if (std::holds_alternative<CompletionList>(*result)) {
|
||||||
const auto &list = std::get<CompletionList>(*result);
|
const auto &list = std::get<CompletionList>(*result);
|
||||||
items = list.items().value_or(QList<CompletionItem>());
|
items = list.items().value_or(QList<CompletionItem>());
|
||||||
isComplete = !list.isIncomplete();
|
if (list.isIncomplete())
|
||||||
|
isComplete = false;
|
||||||
} else if (std::holds_alternative<QList<CompletionItem>>(*result)) {
|
} else if (std::holds_alternative<QList<CompletionItem>>(*result)) {
|
||||||
items = std::get<QList<CompletionItem>>(*result);
|
items = std::get<QList<CompletionItem>>(*result);
|
||||||
}
|
}
|
||||||
auto proposalItems = generateCompletionItems(items);
|
auto proposalItems = generateCompletionItems(items);
|
||||||
if (!m_snippetsGroup.isEmpty()) {
|
if (!m_snippetsGroup.isEmpty()) {
|
||||||
proposalItems << TextEditor::SnippetAssistCollector(
|
proposalItems << TextEditor::SnippetAssistCollector(m_snippetsGroup,
|
||||||
m_snippetsGroup, QIcon(":/texteditor/images/snippet.png")).collect();
|
QIcon(
|
||||||
|
":/texteditor/images/snippet.png"))
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
auto model = new LanguageClientCompletionModel();
|
auto model = new LanguageClientCompletionModel();
|
||||||
model->loadContent(proposalItems);
|
model->loadContent(proposalItems);
|
||||||
LanguageClientCompletionProposal *proposal = new LanguageClientCompletionProposal(m_basePos,
|
if (isComplete)
|
||||||
|
model->setCompletePrefix(prefix);
|
||||||
|
LanguageClientCompletionProposal *proposal = new LanguageClientCompletionProposal(m_provider,
|
||||||
|
m_basePos,
|
||||||
model);
|
model);
|
||||||
proposal->m_document = document();
|
proposal->m_document = document();
|
||||||
proposal->m_pos = m_pos;
|
proposal->m_pos = m_pos;
|
||||||
const QString completePrefix = Utils::Text::textAt(QTextCursor(document()),
|
|
||||||
m_basePos,
|
|
||||||
m_pos - m_basePos);
|
|
||||||
proposal->setPrefixChecker([isComplete, completePrefix](const QString &candidate) {
|
|
||||||
return isComplete && candidate.startsWith(completePrefix);
|
|
||||||
});
|
|
||||||
setAsyncProposalAvailable(proposal);
|
setAsyncProposalAvailable(proposal);
|
||||||
m_client->removeAssistProcessor(this);
|
m_client->removeAssistProcessor(this);
|
||||||
qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : "
|
qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : "
|
||||||
@@ -449,8 +539,7 @@ LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(C
|
|||||||
IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor(
|
IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor(
|
||||||
const AssistInterface *) const
|
const AssistInterface *) const
|
||||||
{
|
{
|
||||||
return new LanguageClientCompletionAssistProcessor(m_client,
|
return new LanguageClientCompletionAssistProcessor(m_client, this, m_snippetsGroup);
|
||||||
m_snippetsGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LanguageClientCompletionAssistProvider::activationCharSequenceLength() const
|
int LanguageClientCompletionAssistProvider::activationCharSequenceLength() const
|
||||||
@@ -460,7 +549,7 @@ int LanguageClientCompletionAssistProvider::activationCharSequenceLength() const
|
|||||||
|
|
||||||
bool LanguageClientCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const
|
bool LanguageClientCompletionAssistProvider::isActivationCharSequence(const QString &sequence) const
|
||||||
{
|
{
|
||||||
return Utils::anyOf(m_triggerChars, [sequence](const QString &trigger){
|
return Utils::anyOf(m_triggerChars, [sequence](const QString &trigger) {
|
||||||
return trigger.endsWith(sequence);
|
return trigger.endsWith(sequence);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,9 @@ class LANGUAGECLIENT_EXPORT LanguageClientCompletionAssistProcessor
|
|||||||
: public TextEditor::IAssistProcessor
|
: public TextEditor::IAssistProcessor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LanguageClientCompletionAssistProcessor(Client *client, const QString &snippetsGroup);
|
LanguageClientCompletionAssistProcessor(Client *client,
|
||||||
|
const TextEditor::IAssistProvider *provider,
|
||||||
|
const QString &snippetsGroup);
|
||||||
~LanguageClientCompletionAssistProcessor() override;
|
~LanguageClientCompletionAssistProcessor() override;
|
||||||
TextEditor::IAssistProposal *perform() override;
|
TextEditor::IAssistProposal *perform() override;
|
||||||
bool running() override;
|
bool running() override;
|
||||||
@@ -76,6 +78,7 @@ private:
|
|||||||
|
|
||||||
Utils::FilePath m_filePath;
|
Utils::FilePath m_filePath;
|
||||||
QPointer<Client> m_client;
|
QPointer<Client> m_client;
|
||||||
|
QPointer<const TextEditor::IAssistProvider> m_provider;
|
||||||
std::optional<LanguageServerProtocol::MessageId> m_currentRequest;
|
std::optional<LanguageServerProtocol::MessageId> m_currentRequest;
|
||||||
QMetaObject::Connection m_postponedUpdateConnection;
|
QMetaObject::Connection m_postponedUpdateConnection;
|
||||||
const QString m_snippetsGroup;
|
const QString m_snippetsGroup;
|
||||||
|
@@ -77,12 +77,10 @@ private:
|
|||||||
private:
|
private:
|
||||||
CodeAssistant *q = nullptr;
|
CodeAssistant *q = nullptr;
|
||||||
TextEditorWidget *m_editorWidget = nullptr;
|
TextEditorWidget *m_editorWidget = nullptr;
|
||||||
QMetaObject::Connection m_runnerConnection;
|
|
||||||
IAssistProvider *m_requestProvider = nullptr;
|
IAssistProvider *m_requestProvider = nullptr;
|
||||||
IAssistProcessor *m_processor = nullptr;
|
IAssistProcessor *m_processor = nullptr;
|
||||||
AssistKind m_assistKind = TextEditor::Completion;
|
AssistKind m_assistKind = TextEditor::Completion;
|
||||||
IAssistProposalWidget *m_proposalWidget = nullptr;
|
IAssistProposalWidget *m_proposalWidget = nullptr;
|
||||||
QScopedPointer<IAssistProposal> m_proposal;
|
|
||||||
bool m_receivedContentWhileWaiting = false;
|
bool m_receivedContentWhileWaiting = false;
|
||||||
QTimer m_automaticProposalTimer;
|
QTimer m_automaticProposalTimer;
|
||||||
CompletionSettings m_settings;
|
CompletionSettings m_settings;
|
||||||
@@ -117,12 +115,11 @@ void CodeAssistantPrivate::invoke(AssistKind kind, IAssistProvider *provider)
|
|||||||
{
|
{
|
||||||
stopAutomaticProposalTimer();
|
stopAutomaticProposalTimer();
|
||||||
|
|
||||||
if (isDisplayingProposal() && m_assistKind == kind && !m_proposal->isFragile()
|
if (isDisplayingProposal() && m_assistKind == kind && !m_proposalWidget->isFragile()) {
|
||||||
&& m_proposal->supportsPrefixFiltering(proposalPrefix())) {
|
|
||||||
m_proposalWidget->setReason(ExplicitlyInvoked);
|
m_proposalWidget->setReason(ExplicitlyInvoked);
|
||||||
m_proposalWidget->updateProposal(m_editorWidget->textAt(
|
m_proposalWidget->filterProposal(m_editorWidget->textAt(
|
||||||
m_proposal->basePosition(),
|
m_proposalWidget->basePosition(),
|
||||||
m_editorWidget->position() - m_proposal->basePosition()));
|
m_editorWidget->position() - m_proposalWidget->basePosition()));
|
||||||
} else {
|
} else {
|
||||||
requestProposal(ExplicitlyInvoked, kind, provider);
|
requestProposal(ExplicitlyInvoked, kind, provider);
|
||||||
}
|
}
|
||||||
@@ -239,14 +236,12 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: The proposal should own the model until someone takes it explicitly away.
|
// 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()
|
if (isDisplayingProposal() && !m_proposalWidget->isFragile())
|
||||||
&& !m_proposalWidget->supportsModelUpdate(proposalCandidate->id())) {
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
int basePosition = proposalCandidate->basePosition();
|
int basePosition = newProposal->basePosition();
|
||||||
if (m_editorWidget->position() < basePosition) {
|
if (m_editorWidget->position() < basePosition) {
|
||||||
destroyContext();
|
destroyContext();
|
||||||
return;
|
return;
|
||||||
@@ -266,28 +261,16 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
|||||||
return;
|
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();
|
destroyContext();
|
||||||
|
|
||||||
clearAbortedPosition();
|
clearAbortedPosition();
|
||||||
m_proposal.reset(proposalCandidate.take());
|
|
||||||
m_proposal->setReason(reason);
|
|
||||||
|
|
||||||
if (m_proposal->isCorrective(m_editorWidget))
|
if (newProposal->isCorrective(m_editorWidget))
|
||||||
m_proposal->makeCorrection(m_editorWidget);
|
newProposal->makeCorrection(m_editorWidget);
|
||||||
|
|
||||||
m_editorWidget->keepAutoCompletionHighlight(true);
|
m_editorWidget->keepAutoCompletionHighlight(true);
|
||||||
basePosition = m_proposal->basePosition();
|
basePosition = newProposal->basePosition();
|
||||||
m_proposalWidget = m_proposal->createWidget();
|
m_proposalWidget = newProposal->createWidget();
|
||||||
connect(m_proposalWidget, &QObject::destroyed,
|
connect(m_proposalWidget, &QObject::destroyed,
|
||||||
this, &CodeAssistantPrivate::finalizeProposal);
|
this, &CodeAssistantPrivate::finalizeProposal);
|
||||||
connect(m_proposalWidget, &IAssistProposalWidget::prefixExpanded,
|
connect(m_proposalWidget, &IAssistProposalWidget::prefixExpanded,
|
||||||
@@ -301,7 +284,7 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
|||||||
m_proposalWidget->setKind(m_assistKind);
|
m_proposalWidget->setKind(m_assistKind);
|
||||||
m_proposalWidget->setBasePosition(basePosition);
|
m_proposalWidget->setBasePosition(basePosition);
|
||||||
m_proposalWidget->setUnderlyingWidget(m_editorWidget);
|
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->setDisplayRect(m_editorWidget->cursorRect(basePosition));
|
||||||
m_proposalWidget->setIsSynchronized(!m_receivedContentWhileWaiting);
|
m_proposalWidget->setIsSynchronized(!m_receivedContentWhileWaiting);
|
||||||
m_proposalWidget->showProposal(prefix);
|
m_proposalWidget->showProposal(prefix);
|
||||||
@@ -309,9 +292,9 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
|||||||
|
|
||||||
void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *proposalItem)
|
void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *proposalItem)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_proposal, return);
|
QTC_ASSERT(m_proposalWidget, return);
|
||||||
TextDocumentManipulator manipulator(m_editorWidget);
|
TextDocumentManipulator manipulator(m_editorWidget);
|
||||||
proposalItem->apply(manipulator, m_proposal->basePosition());
|
proposalItem->apply(manipulator, m_proposalWidget->basePosition());
|
||||||
destroyContext();
|
destroyContext();
|
||||||
m_editorWidget->encourageApply();
|
m_editorWidget->encourageApply();
|
||||||
if (!proposalItem->isSnippet())
|
if (!proposalItem->isSnippet())
|
||||||
@@ -320,34 +303,33 @@ void CodeAssistantPrivate::processProposalItem(AssistProposalItemInterface *prop
|
|||||||
|
|
||||||
void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix)
|
void CodeAssistantPrivate::handlePrefixExpansion(const QString &newPrefix)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_proposal, return);
|
QTC_ASSERT(m_proposalWidget, return);
|
||||||
|
|
||||||
QTextCursor cursor(m_editorWidget->document());
|
QTextCursor cursor(m_editorWidget->document());
|
||||||
cursor.setPosition(m_proposal->basePosition());
|
cursor.setPosition(m_proposalWidget->basePosition());
|
||||||
cursor.movePosition(QTextCursor::EndOfWord);
|
cursor.movePosition(QTextCursor::EndOfWord);
|
||||||
|
|
||||||
int currentPosition = m_editorWidget->position();
|
int currentPosition = m_editorWidget->position();
|
||||||
const QString textAfterCursor = m_editorWidget->textAt(currentPosition,
|
const QString textAfterCursor = m_editorWidget->textAt(currentPosition,
|
||||||
cursor.position() - currentPosition);
|
cursor.position() - currentPosition);
|
||||||
if (!textAfterCursor.startsWith(newPrefix)) {
|
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();
|
currentPosition = cursor.position();
|
||||||
const QStringView prefixAddition = QStringView(newPrefix).mid(currentPosition
|
const QStringView prefixAddition = QStringView(newPrefix).mid(currentPosition
|
||||||
- m_proposal->basePosition());
|
- m_proposalWidget->basePosition());
|
||||||
// If remaining string starts with the prefix addition
|
// If remaining string starts with the prefix addition
|
||||||
if (textAfterCursor.startsWith(prefixAddition))
|
if (textAfterCursor.startsWith(prefixAddition))
|
||||||
currentPosition += prefixAddition.size();
|
currentPosition += prefixAddition.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_editorWidget->setCursorPosition(m_proposal->basePosition());
|
m_editorWidget->setCursorPosition(m_proposalWidget->basePosition());
|
||||||
m_editorWidget->replace(currentPosition - m_proposal->basePosition(), newPrefix);
|
m_editorWidget->replace(currentPosition - m_proposalWidget->basePosition(), newPrefix);
|
||||||
notifyChange();
|
notifyChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeAssistantPrivate::finalizeProposal()
|
void CodeAssistantPrivate::finalizeProposal()
|
||||||
{
|
{
|
||||||
stopAutomaticProposalTimer();
|
stopAutomaticProposalTimer();
|
||||||
m_proposal.reset();
|
|
||||||
m_proposalWidget = nullptr;
|
m_proposalWidget = nullptr;
|
||||||
if (m_receivedContentWhileWaiting)
|
if (m_receivedContentWhileWaiting)
|
||||||
m_receivedContentWhileWaiting = false;
|
m_receivedContentWhileWaiting = false;
|
||||||
@@ -367,8 +349,8 @@ QString CodeAssistantPrivate::proposalPrefix() const
|
|||||||
{
|
{
|
||||||
if (!isDisplayingProposal())
|
if (!isDisplayingProposal())
|
||||||
return {};
|
return {};
|
||||||
return m_editorWidget->textAt(m_proposal->basePosition(),
|
return m_editorWidget->textAt(m_proposalWidget->basePosition(),
|
||||||
m_editorWidget->position() - m_proposal->basePosition());
|
m_editorWidget->position() - m_proposalWidget->basePosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeAssistantPrivate::invalidateCurrentRequestData()
|
void CodeAssistantPrivate::invalidateCurrentRequestData()
|
||||||
@@ -409,18 +391,14 @@ void CodeAssistantPrivate::notifyChange()
|
|||||||
stopAutomaticProposalTimer();
|
stopAutomaticProposalTimer();
|
||||||
|
|
||||||
if (isDisplayingProposal()) {
|
if (isDisplayingProposal()) {
|
||||||
QTC_ASSERT(m_proposal, return);
|
QTC_ASSERT(m_proposalWidget, return);
|
||||||
if (m_editorWidget->position() < m_proposal->basePosition()) {
|
if (m_editorWidget->position() < m_proposalWidget->basePosition()) {
|
||||||
destroyContext();
|
destroyContext();
|
||||||
} else {
|
} else {
|
||||||
const QString prefix = proposalPrefix();
|
m_proposalWidget->updateProposal(
|
||||||
if (m_proposal->supportsPrefixFiltering(prefix)) {
|
m_editorWidget->createAssistInterface(m_assistKind, m_proposalWidget->reason()));
|
||||||
m_proposalWidget->updateProposal(prefix);
|
if (!isDisplayingProposal())
|
||||||
if (!isDisplayingProposal())
|
requestActivationCharProposal();
|
||||||
requestActivationCharProposal();
|
|
||||||
} else {
|
|
||||||
requestProposal(m_proposal->reason(), m_assistKind, m_requestProvider, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +444,7 @@ void CodeAssistantPrivate::automaticProposalTimeout()
|
|||||||
{
|
{
|
||||||
if (isWaitingForProposal()
|
if (isWaitingForProposal()
|
||||||
|| m_editorWidget->multiTextCursor().hasMultipleCursors()
|
|| m_editorWidget->multiTextCursor().hasMultipleCursors()
|
||||||
|| (isDisplayingProposal() && !m_proposal->isFragile())) {
|
|| (isDisplayingProposal() && !m_proposalWidget->isFragile())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,8 +466,8 @@ void CodeAssistantPrivate::updateFromCompletionSettings(
|
|||||||
|
|
||||||
void CodeAssistantPrivate::explicitlyAborted()
|
void CodeAssistantPrivate::explicitlyAborted()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_proposal, return);
|
QTC_ASSERT(m_proposalWidget, return);
|
||||||
m_abortedBasePosition = m_proposal->basePosition();
|
m_abortedBasePosition = m_proposalWidget->basePosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeAssistantPrivate::clearAbortedPosition()
|
void CodeAssistantPrivate::clearAbortedPosition()
|
||||||
|
@@ -12,9 +12,7 @@ using namespace TextEditor;
|
|||||||
FunctionHintProposal::FunctionHintProposal(int cursorPos, FunctionHintProposalModelPtr model)
|
FunctionHintProposal::FunctionHintProposal(int cursorPos, FunctionHintProposalModelPtr model)
|
||||||
: IAssistProposal(functionHintId, cursorPos)
|
: IAssistProposal(functionHintId, cursorPos)
|
||||||
, m_model(model)
|
, m_model(model)
|
||||||
{
|
{}
|
||||||
setFragile(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionHintProposal::~FunctionHintProposal() = default;
|
FunctionHintProposal::~FunctionHintProposal() = default;
|
||||||
|
|
||||||
|
@@ -138,6 +138,7 @@ FunctionHintProposalWidget::FunctionHintProposalWidget()
|
|||||||
});
|
});
|
||||||
|
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
|
setFragile(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionHintProposalWidget::~FunctionHintProposalWidget()
|
FunctionHintProposalWidget::~FunctionHintProposalWidget()
|
||||||
@@ -150,9 +151,6 @@ void FunctionHintProposalWidget::setAssistant(CodeAssistant *assistant)
|
|||||||
d->m_assistant = assistant;
|
d->m_assistant = assistant;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionHintProposalWidget::setReason(AssistReason)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void FunctionHintProposalWidget::setKind(AssistKind)
|
void FunctionHintProposalWidget::setKind(AssistKind)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -190,7 +188,7 @@ void FunctionHintProposalWidget::showProposal(const QString &prefix)
|
|||||||
d->m_popupFrame->show();
|
d->m_popupFrame->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FunctionHintProposalWidget::updateProposal(const QString &prefix)
|
void FunctionHintProposalWidget::filterProposal(const QString &prefix)
|
||||||
{
|
{
|
||||||
updateAndCheck(prefix);
|
updateAndCheck(prefix);
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,6 @@ public:
|
|||||||
~FunctionHintProposalWidget() override;
|
~FunctionHintProposalWidget() override;
|
||||||
|
|
||||||
void setAssistant(CodeAssistant *assistant) override;
|
void setAssistant(CodeAssistant *assistant) override;
|
||||||
void setReason(AssistReason reason) override;
|
|
||||||
void setKind(AssistKind kind) override;
|
void setKind(AssistKind kind) override;
|
||||||
void setUnderlyingWidget(const QWidget *underlyingWidget) override;
|
void setUnderlyingWidget(const QWidget *underlyingWidget) override;
|
||||||
void setModel(ProposalModelPtr model) override;
|
void setModel(ProposalModelPtr model) override;
|
||||||
@@ -27,7 +26,7 @@ public:
|
|||||||
void setIsSynchronized(bool isSync) override;
|
void setIsSynchronized(bool isSync) override;
|
||||||
|
|
||||||
void showProposal(const QString &prefix) override;
|
void showProposal(const QString &prefix) override;
|
||||||
void updateProposal(const QString &prefix) override;
|
void filterProposal(const QString &prefix) override;
|
||||||
void closeProposal() override;
|
void closeProposal() override;
|
||||||
|
|
||||||
bool proposalIsVisible() const override;
|
bool proposalIsVisible() const override;
|
||||||
|
@@ -249,7 +249,6 @@ public:
|
|||||||
QRect m_displayRect;
|
QRect m_displayRect;
|
||||||
bool m_isSynchronized = true;
|
bool m_isSynchronized = true;
|
||||||
bool m_explicitlySelected = false;
|
bool m_explicitlySelected = false;
|
||||||
AssistReason m_reason = IdleEditor;
|
|
||||||
AssistKind m_kind = Completion;
|
AssistKind m_kind = Completion;
|
||||||
bool m_justInvoked = false;
|
bool m_justInvoked = false;
|
||||||
QPointer<GenericProposalInfoFrame> m_infoFrame;
|
QPointer<GenericProposalInfoFrame> m_infoFrame;
|
||||||
@@ -358,9 +357,9 @@ void GenericProposalWidget::setAssistant(CodeAssistant *assistant)
|
|||||||
|
|
||||||
void GenericProposalWidget::setReason(AssistReason reason)
|
void GenericProposalWidget::setReason(AssistReason reason)
|
||||||
{
|
{
|
||||||
d->m_reason = reason;
|
if (reason == ExplicitlyInvoked)
|
||||||
if (d->m_reason == ExplicitlyInvoked)
|
|
||||||
d->m_justInvoked = true;
|
d->m_justInvoked = true;
|
||||||
|
IAssistProposalWidget::setReason(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericProposalWidget::setKind(AssistKind kind)
|
void GenericProposalWidget::setKind(AssistKind kind)
|
||||||
@@ -393,11 +392,6 @@ void GenericProposalWidget::setIsSynchronized(bool isSync)
|
|||||||
d->m_isSynchronized = isSync;
|
d->m_isSynchronized = isSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenericProposalWidget::supportsModelUpdate(const Utils::Id &proposalId) const
|
|
||||||
{
|
|
||||||
return proposalId == Constants::GENERIC_PROPOSAL_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericProposalWidget::updateModel(ProposalModelPtr model)
|
void GenericProposalWidget::updateModel(ProposalModelPtr model)
|
||||||
{
|
{
|
||||||
QString currentText;
|
QString currentText;
|
||||||
@@ -418,6 +412,7 @@ void GenericProposalWidget::updateModel(ProposalModelPtr model)
|
|||||||
d->m_completionListView->selectRow(currentRow);
|
d->m_completionListView->selectRow(currentRow);
|
||||||
else
|
else
|
||||||
d->m_explicitlySelected = false;
|
d->m_explicitlySelected = false;
|
||||||
|
updatePositionAndSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericProposalWidget::showProposal(const QString &prefix)
|
void GenericProposalWidget::showProposal(const QString &prefix)
|
||||||
@@ -431,7 +426,7 @@ void GenericProposalWidget::showProposal(const QString &prefix)
|
|||||||
d->m_completionListView->setFocus();
|
d->m_completionListView->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericProposalWidget::updateProposal(const QString &prefix)
|
void GenericProposalWidget::filterProposal(const QString &prefix)
|
||||||
{
|
{
|
||||||
if (!isVisible())
|
if (!isVisible())
|
||||||
return;
|
return;
|
||||||
@@ -470,7 +465,7 @@ bool GenericProposalWidget::updateAndCheck(const QString &prefix)
|
|||||||
if (!prefix.isEmpty())
|
if (!prefix.isEmpty())
|
||||||
d->m_model->filter(prefix);
|
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();
|
d->m_completionListView->reset();
|
||||||
abort();
|
abort();
|
||||||
return false;
|
return false;
|
||||||
@@ -660,7 +655,7 @@ bool GenericProposalWidget::eventFilter(QObject *o, QEvent *e)
|
|||||||
AssistProposalItemInterface *item =
|
AssistProposalItemInterface *item =
|
||||||
d->m_model->proposalItem(d->m_completionListView->currentIndex().row());
|
d->m_model->proposalItem(d->m_completionListView->currentIndex().row());
|
||||||
if (item->prematurelyApplies(typedChar)
|
if (item->prematurelyApplies(typedChar)
|
||||||
&& (d->m_reason == ExplicitlyInvoked || item->text().endsWith(typedChar))) {
|
&& (reason() == ExplicitlyInvoked || item->text().endsWith(typedChar))) {
|
||||||
abort();
|
abort();
|
||||||
emit proposalItemActivated(item);
|
emit proposalItemActivated(item);
|
||||||
return true;
|
return true;
|
||||||
|
@@ -31,11 +31,10 @@ public:
|
|||||||
void setDisplayRect(const QRect &rect) override;
|
void setDisplayRect(const QRect &rect) override;
|
||||||
void setIsSynchronized(bool isSync) override;
|
void setIsSynchronized(bool isSync) override;
|
||||||
|
|
||||||
bool supportsModelUpdate(const Utils::Id &proposalId) const override;
|
void updateModel(ProposalModelPtr model);
|
||||||
void updateModel(ProposalModelPtr model) override;
|
|
||||||
|
|
||||||
void showProposal(const QString &prefix) override;
|
void showProposal(const QString &prefix) override;
|
||||||
void updateProposal(const QString &prefix) override;
|
void filterProposal(const QString &prefix) override;
|
||||||
void closeProposal() override;
|
void closeProposal() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -63,16 +63,6 @@ int IAssistProposal::basePosition() const
|
|||||||
return m_basePosition;
|
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
|
\fn bool TextEditor::IAssistProposal::isCorrective() const
|
||||||
|
|
||||||
@@ -98,16 +88,6 @@ void IAssistProposal::makeCorrection(TextEditorWidget *editorWidget)
|
|||||||
Q_UNUSED(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
|
\fn IAssistModel *TextEditor::IAssistProposal::model() const
|
||||||
|
|
||||||
|
@@ -22,30 +22,17 @@ public:
|
|||||||
virtual ~IAssistProposal();
|
virtual ~IAssistProposal();
|
||||||
|
|
||||||
int basePosition() const;
|
int basePosition() const;
|
||||||
bool isFragile() const;
|
|
||||||
bool supportsPrefixFiltering(const QString &prefix) const;
|
|
||||||
virtual bool hasItemsToPropose(const QString &, AssistReason) const { return true; }
|
virtual bool hasItemsToPropose(const QString &, AssistReason) const { return true; }
|
||||||
virtual bool isCorrective(TextEditorWidget *editorWidget) const;
|
virtual bool isCorrective(TextEditorWidget *editorWidget) const;
|
||||||
virtual void makeCorrection(TextEditorWidget *editorWidget);
|
virtual void makeCorrection(TextEditorWidget *editorWidget);
|
||||||
virtual TextEditor::ProposalModelPtr model() const = 0;
|
virtual TextEditor::ProposalModelPtr model() const = 0;
|
||||||
virtual IAssistProposalWidget *createWidget() const = 0;
|
virtual IAssistProposalWidget *createWidget() const = 0;
|
||||||
|
|
||||||
void setFragile(bool fragile);
|
|
||||||
|
|
||||||
Utils::Id id() const { return m_id; }
|
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:
|
protected:
|
||||||
Utils::Id m_id;
|
Utils::Id m_id;
|
||||||
int m_basePosition;
|
int m_basePosition;
|
||||||
bool m_isFragile = false;
|
|
||||||
PrefixChecker m_prefixChecker;
|
|
||||||
AssistReason m_reason = IdleEditor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // TextEditor
|
} // TextEditor
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "iassistproposalwidget.h"
|
#include "iassistproposalwidget.h"
|
||||||
|
|
||||||
|
#include "assistinterface.h"
|
||||||
|
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -30,6 +32,11 @@ IAssistProposalWidget::IAssistProposalWidget()
|
|||||||
: QFrame(nullptr, Qt::Popup)
|
: QFrame(nullptr, Qt::Popup)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void IAssistProposalWidget::updateProposal(std::unique_ptr<AssistInterface> &&interface)
|
||||||
|
{
|
||||||
|
filterProposal(interface->textAt(m_basePosition, interface->position() - m_basePosition));
|
||||||
|
}
|
||||||
|
|
||||||
IAssistProposalWidget::~IAssistProposalWidget() = default;
|
IAssistProposalWidget::~IAssistProposalWidget() = default;
|
||||||
|
|
||||||
int IAssistProposalWidget::basePosition() const
|
int IAssistProposalWidget::basePosition() const
|
||||||
|
@@ -14,8 +14,9 @@ namespace Utils { class Id; }
|
|||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
|
|
||||||
class CodeAssistant;
|
class AssistInterface;
|
||||||
class AssistProposalItemInterface;
|
class AssistProposalItemInterface;
|
||||||
|
class CodeAssistant;
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT IAssistProposalWidget : public QFrame
|
class TEXTEDITOR_EXPORT IAssistProposalWidget : public QFrame
|
||||||
{
|
{
|
||||||
@@ -26,7 +27,7 @@ public:
|
|||||||
~IAssistProposalWidget() override;
|
~IAssistProposalWidget() override;
|
||||||
|
|
||||||
virtual void setAssistant(CodeAssistant *assistant) = 0;
|
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 setKind(AssistKind kind) = 0;
|
||||||
virtual void setUnderlyingWidget(const QWidget *underlyingWidget) = 0;
|
virtual void setUnderlyingWidget(const QWidget *underlyingWidget) = 0;
|
||||||
virtual void setModel(ProposalModelPtr model) = 0;
|
virtual void setModel(ProposalModelPtr model) = 0;
|
||||||
@@ -34,16 +35,20 @@ public:
|
|||||||
virtual void setIsSynchronized(bool isSync) = 0;
|
virtual void setIsSynchronized(bool isSync) = 0;
|
||||||
|
|
||||||
virtual void showProposal(const QString &prefix) = 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 void closeProposal() = 0;
|
||||||
|
|
||||||
virtual bool proposalIsVisible() const { return isVisible(); }
|
virtual bool proposalIsVisible() const { return isVisible(); }
|
||||||
virtual bool supportsModelUpdate(const Utils::Id &/*proposalId*/) const { return false; }
|
|
||||||
virtual void updateModel(ProposalModelPtr) {}
|
|
||||||
|
|
||||||
int basePosition() const;
|
int basePosition() const;
|
||||||
void setBasePosition(int basePosition);
|
void setBasePosition(int basePosition);
|
||||||
|
|
||||||
|
void setFragile(bool fragile) { m_isFragile = fragile; }
|
||||||
|
bool isFragile() const { return m_isFragile; }
|
||||||
|
|
||||||
|
AssistReason reason() const { return m_reason; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void prefixExpanded(const QString &newPrefix);
|
void prefixExpanded(const QString &newPrefix);
|
||||||
void proposalItemActivated(AssistProposalItemInterface *proposalItem);
|
void proposalItemActivated(AssistProposalItemInterface *proposalItem);
|
||||||
@@ -51,6 +56,8 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_basePosition = -1;
|
int m_basePosition = -1;
|
||||||
|
bool m_isFragile = false;
|
||||||
|
AssistReason m_reason = IdleEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // TextEditor
|
} // TextEditor
|
||||||
|
Reference in New Issue
Block a user