diff --git a/src/common/lsp/client/client.cpp b/src/common/lsp/client/client.cpp index 2b800b02b..cc3c46e7c 100644 --- a/src/common/lsp/client/client.cpp +++ b/src/common/lsp/client/client.cpp @@ -538,7 +538,7 @@ void Client::diagnostic(const WorkspaceDiagnosticParams ¶ms) void Client::selectLspServer(const newlsp::ProjectKey &key) { - if (d->proKey == key) + if (d->proKey == key && d->isClientValid) return; d->proKey = key; @@ -1342,6 +1342,7 @@ bool ClientPrivate::calledResult(const QJsonObject &jsonObj) || !jsonObj.contains(K_RESULT)) return false; + isClientValid = true; bool any = false; any |= initResult(jsonObj); any |= openResult(jsonObj); @@ -1401,6 +1402,11 @@ lsp::SemanticTokensProvider Client::initSecTokensProvider() return d->secTokensProvider; } +bool Client::isValid() const +{ + return d->isClientValid; +} + ClientPrivate::ClientPrivate(Client *const q) : newlsp::StdoutJsonRpcParser(), q(q), requestIndex(0), requestSave({}), semanticTokenResultId(0), fileVersion({}), secTokensProvider({}), proKey({}) { diff --git a/src/common/lsp/client/client.h b/src/common/lsp/client/client.h index 2de7f0adf..489de856a 100644 --- a/src/common/lsp/client/client.h +++ b/src/common/lsp/client/client.h @@ -23,6 +23,7 @@ class COMMON_EXPORT Client : public QProcess virtual ~Client(); lsp::SemanticTokensProvider initSecTokensProvider(); + bool isValid() const; public slots: // textDocument/semanticTokens/full/delta diff --git a/src/common/lsp/client/private/client_p.h b/src/common/lsp/client/private/client_p.h index f41bea117..0ab7d187c 100644 --- a/src/common/lsp/client/private/client_p.h +++ b/src/common/lsp/client/private/client_p.h @@ -32,6 +32,7 @@ class ClientPrivate : public newlsp::StdoutJsonRpcParser QHash fileVersion; lsp::SemanticTokensProvider secTokensProvider; newlsp::ProjectKey proKey; + bool isClientValid { false }; ClientPrivate(Client *const q); @@ -39,27 +40,27 @@ class ClientPrivate : public newlsp::StdoutJsonRpcParser /* server response parse */ bool calledError(const QJsonObject &jsonObj); - bool calledResult(const QJsonObject &jsonObj); //found result key from json && not found method - bool initResult(const QJsonObject &jsonObj); // client call server rpc return - bool openResult(const QJsonObject &jsonObj); // client call server rpc return - bool changeResult(const QJsonObject &jsonObj); // client call server rpc return - bool symbolResult(const QJsonObject &jsonObj); // client call server rpc return - bool renameResult(const QJsonObject &jsonObj); // client call server rpc return - bool definitionResult(const QJsonObject &jsonObj); // client call server rpc return above uri - bool completionResult(const QJsonObject &jsonObj); // client call server rpc return - bool rangeFormattingResult(const QJsonObject &jsonObj); // client call server rpc return - bool signatureHelpResult(const QJsonObject &jsonObj); // client call server rpc return - bool hoverResult(const QJsonObject &jsonObj); // client call server rpc return - bool referencesResult(const QJsonObject &jsonObj); // client call server rpc return - bool docHighlightResult(const QJsonObject &jsonObj); // client call server rpc return - bool docSemanticTokensFullResult(const QJsonObject &jsonObj); // client call server rpc return - bool closeResult(const QJsonObject &jsonObj); // client call server rpc return + bool calledResult(const QJsonObject &jsonObj); // found result key from json && not found method + bool initResult(const QJsonObject &jsonObj); // client call server rpc return + bool openResult(const QJsonObject &jsonObj); // client call server rpc return + bool changeResult(const QJsonObject &jsonObj); // client call server rpc return + bool symbolResult(const QJsonObject &jsonObj); // client call server rpc return + bool renameResult(const QJsonObject &jsonObj); // client call server rpc return + bool definitionResult(const QJsonObject &jsonObj); // client call server rpc return above uri + bool completionResult(const QJsonObject &jsonObj); // client call server rpc return + bool rangeFormattingResult(const QJsonObject &jsonObj); // client call server rpc return + bool signatureHelpResult(const QJsonObject &jsonObj); // client call server rpc return + bool hoverResult(const QJsonObject &jsonObj); // client call server rpc return + bool referencesResult(const QJsonObject &jsonObj); // client call server rpc return + bool docHighlightResult(const QJsonObject &jsonObj); // client call server rpc return + bool docSemanticTokensFullResult(const QJsonObject &jsonObj); // client call server rpc return + bool closeResult(const QJsonObject &jsonObj); // client call server rpc return bool shutdownResult(const QJsonObject &jsonObj); bool exitResult(const QJsonObject &jsonObj); bool switchHeaderSourceResult(const QJsonObject &jsonObj); /* server called method */ - bool serverCalled(const QJsonObject &jsonObj); // not found result key from json && found key method + bool serverCalled(const QJsonObject &jsonObj); // not found result key from json && found key method bool diagnosticsCalled(const QJsonObject &jsonObj); QList parseDocumentSymbol(const QJsonArray &array); @@ -80,4 +81,4 @@ public Q_SLOTS: } -#endif // CLIENT_P_H +#endif // CLIENT_P_H diff --git a/src/plugins/codeeditor/lsp/languageclienthandler.cpp b/src/plugins/codeeditor/lsp/languageclienthandler.cpp index c4c839b70..debf8b9d1 100644 --- a/src/plugins/codeeditor/lsp/languageclienthandler.cpp +++ b/src/plugins/codeeditor/lsp/languageclienthandler.cpp @@ -523,26 +523,32 @@ void LanguageClientHandlerPrivate::handleShowContextMenu(QMenu *menu) if (!editor) return; + bool isClientValid = getClient() ? getClient()->isValid() : false; auto actionList = menu->actions(); for (auto act : actionList) { if (act->text() == tr("Refactor")) { QMenu *subMenu = new QMenu(menu); subMenu->addAction(tr("Rename Symbol Under Cursor"), q, &LanguageClientHandler::renameActionTriggered); act->setMenu(subMenu); + act->setEnabled(isClientValid); break; } } auto act = menu->addAction(tr("Switch Header/Source"), q, std::bind(&LanguageClientHandler::switchHeaderSource, q, editor->getFile())); + act->setEnabled(isClientValid); menu->insertAction(actionList.first(), act); act = menu->addAction(tr("Follow Symbol Under Cursor"), q, &LanguageClientHandler::followSymbolUnderCursor); + act->setEnabled(isClientValid); menu->insertAction(actionList.first(), act); act = menu->addAction(tr("Find Usages"), q, &LanguageClientHandler::findUsagesActionTriggered); + act->setEnabled(isClientValid); menu->insertAction(actionList.first(), act); act = menu->addAction(tr("Format Selection"), q, &LanguageClientHandler::formatSelections); + act->setEnabled(isClientValid); menu->insertAction(actionList.first(), act); menu->insertSeparator(actionList.first()); } diff --git a/src/plugins/codeeditor/lsp/lspclientmanager.cpp b/src/plugins/codeeditor/lsp/lspclientmanager.cpp index 36e0639a7..d14f59382 100644 --- a/src/plugins/codeeditor/lsp/lspclientmanager.cpp +++ b/src/plugins/codeeditor/lsp/lspclientmanager.cpp @@ -28,12 +28,17 @@ newlsp::Client *LSPClientManager::get(const newlsp::ProjectKey &key) if (!key.isValid()) return nullptr; + auto selectLSP = [key](newlsp::Client *client) { + qApp->metaObject()->invokeMethod(client, "selectLspServer", Q_ARG(const newlsp::ProjectKey &, key)); + if (!client->isValid()) + qApp->metaObject()->invokeMethod(client, "initRequest"); + }; + if (clientHash.contains(key)) { - qApp->metaObject()->invokeMethod(clientHash[key], "selectLspServer", Q_ARG(const newlsp::ProjectKey &, key)); + selectLSP(clientHash[key]); } else { auto client = new newlsp::Client(); - qApp->metaObject()->invokeMethod(client, "selectLspServer", Q_ARG(const newlsp::ProjectKey &, key)); - qApp->metaObject()->invokeMethod(client, "initRequest"); + selectLSP(client); clientHash.insert(key, client); }