diff options
Diffstat (limited to 'src/plugins/languageclient/languageclientcompletionassist.cpp')
-rw-r--r-- | src/plugins/languageclient/languageclientcompletionassist.cpp | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index 8b5aa94dba..0b38b42edc 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -40,7 +40,6 @@ #include <QDebug> #include <QLoggingCategory> -#include <QRegExp> #include <QRegularExpression> #include <QTextBlock> #include <QTextDocument> @@ -275,6 +274,7 @@ class LanguageClientCompletionAssistProcessor : public IAssistProcessor { public: LanguageClientCompletionAssistProcessor(Client *client); + ~LanguageClientCompletionAssistProcessor() override; IAssistProposal *perform(const AssistInterface *interface) override; bool running() override; bool needsRestart() const override { return true; } @@ -285,7 +285,8 @@ private: QPointer<QTextDocument> m_document; QPointer<Client> m_client; - MessageId m_currentRequest; + Utils::optional<MessageId> m_currentRequest; + QMetaObject::Connection m_postponedUpdateConnection; int m_pos = -1; }; @@ -293,6 +294,11 @@ LanguageClientCompletionAssistProcessor::LanguageClientCompletionAssistProcessor : m_client(client) { } +LanguageClientCompletionAssistProcessor::~LanguageClientCompletionAssistProcessor() +{ + QTC_ASSERT(!running(), cancel()); +} + static QString assistReasonString(AssistReason reason) { switch (reason) { @@ -309,18 +315,37 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn m_pos = interface->position(); if (interface->reason() == IdleEditor) { // Trigger an automatic completion request only when we are on a word with more than 2 "identifier" character - const QRegExp regexp("[_a-zA-Z0-9]*"); + const QRegularExpression regexp("[_a-zA-Z0-9]+"); + auto hasMatch = [®exp](const QString &txt) { return regexp.match(txt).hasMatch(); }; int delta = 0; - while (m_pos - delta > 0 && regexp.exactMatch(interface->textAt(m_pos - delta - 1, delta + 1))) + while (m_pos - delta > 0 && hasMatch(interface->textAt(m_pos - delta - 1, delta + 1))) ++delta; if (delta < 3) return nullptr; + if (m_client->documentUpdatePostponed(interface->fileName())) { + m_postponedUpdateConnection + = QObject::connect(m_client, + &Client::documentUpdated, + [this, interface](TextEditor::TextDocument *document) { + if (document->filePath() + == Utils::FilePath::fromString(interface->fileName())) + perform(interface); + }); + return nullptr; + } } + if (m_postponedUpdateConnection) + QObject::disconnect(m_postponedUpdateConnection); CompletionRequest completionRequest; CompletionParams::CompletionContext context; - context.setTriggerKind(interface->reason() == ActivationCharacter - ? CompletionParams::TriggerCharacter - : CompletionParams::Invoked); + if (interface->reason() == ActivationCharacter) { + context.setTriggerKind(CompletionParams::TriggerCharacter); + QChar triggerCharacter = interface->characterAt(interface->position() - 1); + if (!triggerCharacter.isNull()) + context.setTriggerCharacter(triggerCharacter); + } else { + context.setTriggerKind(CompletionParams::Invoked); + } auto params = completionRequest.params().value_or(CompletionParams()); int line; int column; @@ -337,6 +362,7 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn }); completionRequest.setParams(params); m_client->sendContent(completionRequest); + m_client->addAssistProcessor(this); m_currentRequest = completionRequest.id(); m_document = interface->textDocument(); qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() @@ -347,14 +373,17 @@ IAssistProposal *LanguageClientCompletionAssistProcessor::perform(const AssistIn bool LanguageClientCompletionAssistProcessor::running() { - return m_currentRequest.isValid(); + return m_currentRequest.has_value() || m_postponedUpdateConnection; } void LanguageClientCompletionAssistProcessor::cancel() { - if (running()) { - m_client->cancelRequest(m_currentRequest); - m_currentRequest = MessageId(); + if (m_currentRequest.has_value()) { + m_client->cancelRequest(m_currentRequest.value()); + m_client->removeAssistProcessor(this); + m_currentRequest.reset(); + } else if (m_postponedUpdateConnection) { + QObject::disconnect(m_postponedUpdateConnection); } } @@ -363,7 +392,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( { // We must report back to the code assistant under all circumstances qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : got completions"; - m_currentRequest = MessageId(); + m_currentRequest.reset(); QTC_ASSERT(m_client, setAsyncProposalAvailable(nullptr); return); if (auto error = response.error()) m_client->log(error.value()); @@ -371,6 +400,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( const Utils::optional<CompletionResult> &result = response.result(); if (!result || Utils::holds_alternative<std::nullptr_t>(*result)) { setAsyncProposalAvailable(nullptr); + m_client->removeAssistProcessor(this); return; } @@ -391,6 +421,7 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( proposal->setFragile(true); proposal->setSupportsPrefix(false); setAsyncProposalAvailable(proposal); + m_client->removeAssistProcessor(this); qCDebug(LOGLSPCOMPLETION) << QTime::currentTime() << " : " << items.count() << " completions handled"; } |