From f0a37795131133e0b5acbeb355e90fbad1af3b5b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 10 Sep 2019 08:03:36 +0200 Subject: [PATCH] LanguageClient: reset all assist providers Instead of just unsetting the function assist provider and quick fix assist provider reset it to the previous provider. Change-Id: I46c5c2f14234e3da08480dd103e4634859447d57 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.cpp | 78 ++++++++++++------- src/plugins/languageclient/client.h | 14 +++- .../languageclientcompletionassist.cpp | 3 +- .../languageclientcompletionassist.h | 2 + .../languageclientfunctionhint.cpp | 3 +- .../languageclientfunctionhint.h | 2 + .../languageclient/languageclientquickfix.cpp | 4 +- 7 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index fc552ead71f..c19277babc4 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -95,13 +95,14 @@ private: Client::Client(BaseClientInterface *clientInterface) : m_id(Core::Id::fromString(QUuid::createUuid().toString())) - , m_completionProvider(this) - , m_functionHintProvider(this) - , m_quickFixProvider(this) , m_clientInterface(clientInterface) , m_documentSymbolCache(this) , m_hoverHandler(this) { + m_clientProviders.completionAssistProvider = new LanguageClientCompletionAssistProvider(this); + m_clientProviders.functionHintProvider = new FunctionHintAssistProvider(this); + m_clientProviders.quickFixAssistProvider = new LanguageClientQuickFixProvider(this); + m_contentHandler.insert(JsonRpcMessageHandler::jsonRpcMimeType(), &JsonRpcMessageHandler::parseContent); QTC_ASSERT(clientInterface, return); @@ -129,12 +130,8 @@ Client::~Client() using namespace TextEditor; // FIXME: instead of replacing the completion provider in the text document store the // completion provider as a prioritised list in the text document - for (TextDocument *document : m_resetAssistProvider.keys()) { - if (document->completionAssistProvider() == &m_completionProvider) - document->setCompletionAssistProvider(m_resetAssistProvider[document]); - document->setFunctionHintAssistProvider(nullptr); - document->setQuickFixAssistProvider(nullptr); - } + for (TextDocument *document : m_resetAssistProvider.keys()) + resetAssistProviders(document); for (Core::IEditor * editor : Core::DocumentModel::editorsForOpenedDocuments()) { if (auto textEditor = qobject_cast(editor)) { TextEditorWidget *widget = textEditor->editorWidget(); @@ -317,31 +314,39 @@ bool Client::openDocument(Core::IDocument *document) if (textDocument) { connect(textDocument, - &TextEditor::TextDocument::contentsChangedWithPosition, + &TextDocument::contentsChangedWithPosition, this, [this, textDocument](int position, int charsRemoved, int charsAdded) { documentContentsChanged(textDocument, position, charsRemoved, charsAdded); }); - auto *oldCompletionProvider = qobject_cast( - textDocument->completionAssistProvider()); - if (oldCompletionProvider || !textDocument->completionAssistProvider()) { - // only replace the completion assist provider if it is the default one or null - m_completionProvider.setTriggerCharacters( + + if (auto completionProvider = qobject_cast( + m_clientProviders.completionAssistProvider)) { + completionProvider->setTriggerCharacters( m_serverCapabilities.completionProvider() .value_or(ServerCapabilities::CompletionOptions()) .triggerCharacters() .value_or(QList())); - textDocument->setCompletionAssistProvider(&m_completionProvider); } - m_resetAssistProvider[textDocument] = oldCompletionProvider; - m_functionHintProvider.setTriggerCharacters( - m_serverCapabilities.signatureHelpProvider() - .value_or(ServerCapabilities::SignatureHelpOptions()) - .triggerCharacters() - .value_or(QList())); - textDocument->setCompletionAssistProvider(&m_completionProvider); - textDocument->setFunctionHintAssistProvider(&m_functionHintProvider); - textDocument->setQuickFixAssistProvider(&m_quickFixProvider); + if (auto functionHintAssistProvider = qobject_cast( + m_clientProviders.completionAssistProvider)) { + functionHintAssistProvider->setTriggerCharacters( + m_serverCapabilities.signatureHelpProvider() + .value_or(ServerCapabilities::SignatureHelpOptions()) + .triggerCharacters() + .value_or(QList())); + } + + auto *oldCompletionProvider = qobject_cast( + textDocument->completionAssistProvider()); + // only replace the completion assist provider if it is the default one or null + if (oldCompletionProvider || !textDocument->completionAssistProvider()) + textDocument->setCompletionAssistProvider(m_clientProviders.completionAssistProvider); + m_resetAssistProvider[textDocument] = {oldCompletionProvider, + textDocument->functionHintAssistProvider(), + textDocument->quickFixAssistProvider()}; + textDocument->setFunctionHintAssistProvider(m_clientProviders.functionHintProvider); + textDocument->setQuickFixAssistProvider(m_clientProviders.quickFixAssistProvider); connect(textDocument, &QObject::destroyed, this, [this, textDocument]{ m_resetAssistProvider.remove(textDocument); }); @@ -388,10 +393,8 @@ void Client::closeDocument(Core::IDocument *document) const DidCloseTextDocumentParams params(TextDocumentIdentifier{uri}); m_highlights[uri].clear(); sendContent(uri, DidCloseTextDocumentNotification(params)); - auto textDocument = qobject_cast(document); - if (!textDocument) - return; - textDocument->setCompletionAssistProvider(m_resetAssistProvider.take(textDocument)); + if (auto textDocument = qobject_cast(document)) + resetAssistProviders(textDocument); } bool Client::documentOpen(const Core::IDocument *document) const @@ -1034,6 +1037,23 @@ void Client::removeDiagnostics(const DocumentUri &uri) } } +void Client::resetAssistProviders(TextEditor::TextDocument *document) +{ + const AssistProviders providers = m_resetAssistProvider.take(document); + if (providers.completionAssistProvider + && document->completionAssistProvider() == m_clientProviders.completionAssistProvider) { + document->setCompletionAssistProvider(providers.completionAssistProvider); + } + if (providers.functionHintProvider + && document->functionHintAssistProvider() == m_clientProviders.functionHintProvider) { + document->setFunctionHintAssistProvider(providers.functionHintProvider); + } + if (providers.quickFixAssistProvider + && document->quickFixAssistProvider() == m_clientProviders.quickFixAssistProvider) { + document->setQuickFixAssistProvider(providers.quickFixAssistProvider); + } +} + void Client::handleResponse(const MessageId &id, const QByteArray &content, QTextCodec *codec) { if (auto handler = m_responseHandlers[id]) diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index e1d9df8807d..3441e63b981 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -193,6 +193,7 @@ private: void showDiagnostics(const LanguageServerProtocol::DocumentUri &uri); void removeDiagnostics(const LanguageServerProtocol::DocumentUri &uri); + void resetAssistProviders(TextEditor::TextDocument *document); using ContentHandler = std::function> m_resetAssistProvider; + struct AssistProviders + { + QPointer completionAssistProvider; + QPointer functionHintProvider; + QPointer quickFixAssistProvider; + }; + + AssistProviders m_clientProviders; + QMap m_resetAssistProvider; QHash m_highlightRequests; int m_restartsLeft = 5; QScopedPointer m_clientInterface; diff --git a/src/plugins/languageclient/languageclientcompletionassist.cpp b/src/plugins/languageclient/languageclientcompletionassist.cpp index a036f7beb34..c6964a9b98e 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.cpp +++ b/src/plugins/languageclient/languageclientcompletionassist.cpp @@ -385,7 +385,8 @@ void LanguageClientCompletionAssistProcessor::handleCompletionResponse( } LanguageClientCompletionAssistProvider::LanguageClientCompletionAssistProvider(Client *client) - : m_client(client) + : CompletionAssistProvider(client) + , m_client(client) { } IAssistProcessor *LanguageClientCompletionAssistProvider::createProcessor() const diff --git a/src/plugins/languageclient/languageclientcompletionassist.h b/src/plugins/languageclient/languageclientcompletionassist.h index f0ad95bc883..828a33ec758 100644 --- a/src/plugins/languageclient/languageclientcompletionassist.h +++ b/src/plugins/languageclient/languageclientcompletionassist.h @@ -33,6 +33,8 @@ class Client; class LanguageClientCompletionAssistProvider : public TextEditor::CompletionAssistProvider { + Q_OBJECT + public: LanguageClientCompletionAssistProvider(Client *client); diff --git a/src/plugins/languageclient/languageclientfunctionhint.cpp b/src/plugins/languageclient/languageclientfunctionhint.cpp index 9a1fe6fc8e9..e82c8a5163a 100644 --- a/src/plugins/languageclient/languageclientfunctionhint.cpp +++ b/src/plugins/languageclient/languageclientfunctionhint.cpp @@ -102,7 +102,8 @@ void FunctionHintProcessor::handleSignatureResponse(const SignatureHelpRequest:: } FunctionHintAssistProvider::FunctionHintAssistProvider(Client *client) - : m_client(client) + : CompletionAssistProvider(client) + , m_client(client) {} TextEditor::IAssistProcessor *FunctionHintAssistProvider::createProcessor() const diff --git a/src/plugins/languageclient/languageclientfunctionhint.h b/src/plugins/languageclient/languageclientfunctionhint.h index cf5f96d812a..d7547894f11 100644 --- a/src/plugins/languageclient/languageclientfunctionhint.h +++ b/src/plugins/languageclient/languageclientfunctionhint.h @@ -33,6 +33,8 @@ class Client; class FunctionHintAssistProvider : public TextEditor::CompletionAssistProvider { + Q_OBJECT + public: explicit FunctionHintAssistProvider(Client *client); diff --git a/src/plugins/languageclient/languageclientquickfix.cpp b/src/plugins/languageclient/languageclientquickfix.cpp index 70db31b8712..fd3d8b29765 100644 --- a/src/plugins/languageclient/languageclientquickfix.cpp +++ b/src/plugins/languageclient/languageclientquickfix.cpp @@ -148,7 +148,9 @@ void LanguageClientQuickFixAssistProcessor::handleCodeActionResponse( setAsyncProposalAvailable(GenericProposal::createProposal(m_assistInterface.data(), ops)); } -LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) : m_client(client) +LanguageClientQuickFixProvider::LanguageClientQuickFixProvider(Client *client) + : IAssistProvider(client) + , m_client(client) { QTC_CHECK(client); }