aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/languageclient/languageclientcompletionassist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/languageclient/languageclientcompletionassist.cpp')
-rw-r--r--src/plugins/languageclient/languageclientcompletionassist.cpp55
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 = [&regexp](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";
}