diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 77462e1833f..79108970594 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -34,9 +34,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -356,16 +358,41 @@ void Client::closeDocument(TextEditor::TextDocument *document) } } +void Client::updateCompletionProvider(TextEditor::TextDocument *document) +{ + bool useLanguageServer = m_serverCapabilities.completionProvider().has_value(); + auto clientCompletionProvider = static_cast( + m_clientProviders.completionAssistProvider.data()); + if (m_dynamicCapabilities.isRegistered(CompletionRequest::methodName).value_or(false)) { + const QJsonValue &options = m_dynamicCapabilities.option(CompletionRequest::methodName); + const TextDocumentRegistrationOptions docOptions(options); + useLanguageServer = docOptions.filterApplies(document->filePath(), + Utils::mimeTypeForName(document->mimeType())); + + const ServerCapabilities::CompletionOptions completionOptions(options); + if (completionOptions.isValid(nullptr)) + clientCompletionProvider->setTriggerCharacters(completionOptions.triggerCharacters()); + } + + if (document->completionAssistProvider() != clientCompletionProvider) { + if (useLanguageServer) { + m_resetAssistProvider[document].completionAssistProvider + = document->completionAssistProvider(); + document->setCompletionAssistProvider(clientCompletionProvider); + } + } else if (!useLanguageServer) { + document->setCompletionAssistProvider( + m_resetAssistProvider[document].completionAssistProvider); + } +} + void Client::activateDocument(TextEditor::TextDocument *document) { auto uri = DocumentUri::fromFilePath(document->filePath()); m_diagnosticManager.showDiagnostics(uri); SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities()); // only replace the assist provider if the language server support it - if (m_serverCapabilities.completionProvider()) { - m_resetAssistProvider[document].completionAssistProvider = document->completionAssistProvider(); - document->setCompletionAssistProvider(m_clientProviders.completionAssistProvider); - } + updateCompletionProvider(document); if (m_serverCapabilities.signatureHelpProvider()) { m_resetAssistProvider[document].functionHintProvider = document->functionHintAssistProvider(); document->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider); @@ -527,6 +554,11 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document, void Client::registerCapabilities(const QList ®istrations) { m_dynamicCapabilities.registerCapability(registrations); + if (Utils::anyOf(registrations, + Utils::equal(&Registration::method, QString(CompletionRequest::methodName)))) { + for (auto document : m_openedDocument.keys()) + updateCompletionProvider(document); + } } void Client::unregisterCapabilities(const QList &unregistrations) @@ -1124,7 +1156,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon } else if (method == RegisterCapabilityRequest::methodName) { auto params = dynamic_cast(content)->params().value_or(RegistrationParams()); if (params.isValid(&error)) - m_dynamicCapabilities.registerCapability(params.registrations()); + registerCapabilities(params.registrations()); else logError(params); } else if (method == UnregisterCapabilityRequest::methodName) { @@ -1265,8 +1297,7 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse) completionProvider->setTriggerCharacters( m_serverCapabilities.completionProvider() .value_or(ServerCapabilities::CompletionOptions()) - .triggerCharacters() - .value_or(QList())); + .triggerCharacters()); } if (auto functionHintAssistProvider = qobject_cast( m_clientProviders.functionHintProvider)) { diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 9d8d8487ce8..a8c200f9a04 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -208,6 +208,8 @@ private: void resetAssistProviders(TextEditor::TextDocument *document); void sendPostponedDocumentUpdates(); + void updateCompletionProvider(TextEditor::TextDocument *document); + using ContentHandler = std::function; diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index 2114257faef..34567c5a690 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -451,10 +451,12 @@ bool LanguageClientCompletionAssistProvider::isActivationCharSequence(const QStr }); } -void LanguageClientCompletionAssistProvider::setTriggerCharacters(QList triggerChars) +void LanguageClientCompletionAssistProvider::setTriggerCharacters( + const Utils::optional> triggerChars) { - m_triggerChars = triggerChars; - for (const QString &trigger : triggerChars) { + m_activationCharSequenceLength = 0; + m_triggerChars = triggerChars.value_or(QList()); + for (const QString &trigger : qAsConst(m_triggerChars)) { if (trigger.length() > m_activationCharSequenceLength) m_activationCharSequenceLength = trigger.length(); } diff --git a/src/plugins/languageclient/languageclientcompletionassist.h b/src/plugins/languageclient/languageclientcompletionassist.h index 828a33ec758..34bf7b209ac 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.h +++ b/src/plugins/languageclient/languageclientcompletionassist.h @@ -27,6 +27,8 @@ #include +#include + namespace LanguageClient { class Client; @@ -45,7 +47,7 @@ public: bool isActivationCharSequence(const QString &sequence) const override; bool isContinuationChar(const QChar &) const override { return true; } - void setTriggerCharacters(QList triggerChars); + void setTriggerCharacters(const Utils::optional> triggerChars); private: QList m_triggerChars;