forked from qt-creator/qt-creator
LanguageClient: fix dynamic registered completion provider
Change-Id: I4c770b5b59b30b22a280a526b881b3b47bc43f45 Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -34,9 +34,11 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
#include <languageserverprotocol/completion.h>
|
||||||
#include <languageserverprotocol/diagnostics.h>
|
#include <languageserverprotocol/diagnostics.h>
|
||||||
#include <languageserverprotocol/languagefeatures.h>
|
#include <languageserverprotocol/languagefeatures.h>
|
||||||
#include <languageserverprotocol/messages.h>
|
#include <languageserverprotocol/messages.h>
|
||||||
|
#include <languageserverprotocol/servercapabilities.h>
|
||||||
#include <languageserverprotocol/workspace.h>
|
#include <languageserverprotocol/workspace.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
@@ -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<LanguageClientCompletionAssistProvider *>(
|
||||||
|
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)
|
void Client::activateDocument(TextEditor::TextDocument *document)
|
||||||
{
|
{
|
||||||
auto uri = DocumentUri::fromFilePath(document->filePath());
|
auto uri = DocumentUri::fromFilePath(document->filePath());
|
||||||
m_diagnosticManager.showDiagnostics(uri);
|
m_diagnosticManager.showDiagnostics(uri);
|
||||||
SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities());
|
SemanticHighligtingSupport::applyHighlight(document, m_highlights.value(uri), capabilities());
|
||||||
// only replace the assist provider if the language server support it
|
// only replace the assist provider if the language server support it
|
||||||
if (m_serverCapabilities.completionProvider()) {
|
updateCompletionProvider(document);
|
||||||
m_resetAssistProvider[document].completionAssistProvider = document->completionAssistProvider();
|
|
||||||
document->setCompletionAssistProvider(m_clientProviders.completionAssistProvider);
|
|
||||||
}
|
|
||||||
if (m_serverCapabilities.signatureHelpProvider()) {
|
if (m_serverCapabilities.signatureHelpProvider()) {
|
||||||
m_resetAssistProvider[document].functionHintProvider = document->functionHintAssistProvider();
|
m_resetAssistProvider[document].functionHintProvider = document->functionHintAssistProvider();
|
||||||
document->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider);
|
document->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider);
|
||||||
@@ -527,6 +554,11 @@ void Client::documentContentsChanged(TextEditor::TextDocument *document,
|
|||||||
void Client::registerCapabilities(const QList<Registration> ®istrations)
|
void Client::registerCapabilities(const QList<Registration> ®istrations)
|
||||||
{
|
{
|
||||||
m_dynamicCapabilities.registerCapability(registrations);
|
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<Unregistration> &unregistrations)
|
void Client::unregisterCapabilities(const QList<Unregistration> &unregistrations)
|
||||||
@@ -1124,7 +1156,7 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
|
|||||||
} else if (method == RegisterCapabilityRequest::methodName) {
|
} else if (method == RegisterCapabilityRequest::methodName) {
|
||||||
auto params = dynamic_cast<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams());
|
auto params = dynamic_cast<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams());
|
||||||
if (params.isValid(&error))
|
if (params.isValid(&error))
|
||||||
m_dynamicCapabilities.registerCapability(params.registrations());
|
registerCapabilities(params.registrations());
|
||||||
else
|
else
|
||||||
logError(params);
|
logError(params);
|
||||||
} else if (method == UnregisterCapabilityRequest::methodName) {
|
} else if (method == UnregisterCapabilityRequest::methodName) {
|
||||||
@@ -1265,8 +1297,7 @@ void Client::initializeCallback(const InitializeRequest::Response &initResponse)
|
|||||||
completionProvider->setTriggerCharacters(
|
completionProvider->setTriggerCharacters(
|
||||||
m_serverCapabilities.completionProvider()
|
m_serverCapabilities.completionProvider()
|
||||||
.value_or(ServerCapabilities::CompletionOptions())
|
.value_or(ServerCapabilities::CompletionOptions())
|
||||||
.triggerCharacters()
|
.triggerCharacters());
|
||||||
.value_or(QList<QString>()));
|
|
||||||
}
|
}
|
||||||
if (auto functionHintAssistProvider = qobject_cast<FunctionHintAssistProvider *>(
|
if (auto functionHintAssistProvider = qobject_cast<FunctionHintAssistProvider *>(
|
||||||
m_clientProviders.functionHintProvider)) {
|
m_clientProviders.functionHintProvider)) {
|
||||||
|
@@ -208,6 +208,8 @@ private:
|
|||||||
void resetAssistProviders(TextEditor::TextDocument *document);
|
void resetAssistProviders(TextEditor::TextDocument *document);
|
||||||
void sendPostponedDocumentUpdates();
|
void sendPostponedDocumentUpdates();
|
||||||
|
|
||||||
|
void updateCompletionProvider(TextEditor::TextDocument *document);
|
||||||
|
|
||||||
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
|
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
|
||||||
LanguageServerProtocol::ResponseHandlers,
|
LanguageServerProtocol::ResponseHandlers,
|
||||||
LanguageServerProtocol::MethodHandler)>;
|
LanguageServerProtocol::MethodHandler)>;
|
||||||
|
@@ -451,10 +451,12 @@ bool LanguageClientCompletionAssistProvider::isActivationCharSequence(const QStr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void LanguageClientCompletionAssistProvider::setTriggerCharacters(QList<QString> triggerChars)
|
void LanguageClientCompletionAssistProvider::setTriggerCharacters(
|
||||||
|
const Utils::optional<QList<QString>> triggerChars)
|
||||||
{
|
{
|
||||||
m_triggerChars = triggerChars;
|
m_activationCharSequenceLength = 0;
|
||||||
for (const QString &trigger : triggerChars) {
|
m_triggerChars = triggerChars.value_or(QList<QString>());
|
||||||
|
for (const QString &trigger : qAsConst(m_triggerChars)) {
|
||||||
if (trigger.length() > m_activationCharSequenceLength)
|
if (trigger.length() > m_activationCharSequenceLength)
|
||||||
m_activationCharSequenceLength = trigger.length();
|
m_activationCharSequenceLength = trigger.length();
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <texteditor/codeassist/completionassistprovider.h>
|
#include <texteditor/codeassist/completionassistprovider.h>
|
||||||
|
|
||||||
|
#include <utils/optional.h>
|
||||||
|
|
||||||
namespace LanguageClient {
|
namespace LanguageClient {
|
||||||
|
|
||||||
class Client;
|
class Client;
|
||||||
@@ -45,7 +47,7 @@ public:
|
|||||||
bool isActivationCharSequence(const QString &sequence) const override;
|
bool isActivationCharSequence(const QString &sequence) const override;
|
||||||
bool isContinuationChar(const QChar &) const override { return true; }
|
bool isContinuationChar(const QChar &) const override { return true; }
|
||||||
|
|
||||||
void setTriggerCharacters(QList<QString> triggerChars);
|
void setTriggerCharacters(const Utils::optional<QList<QString>> triggerChars);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QString> m_triggerChars;
|
QList<QString> m_triggerChars;
|
||||||
|
Reference in New Issue
Block a user