From c6cc4fa4ac7eea8948b42b21eba2476af4bb2ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 10 Apr 2024 21:35:56 -0300 Subject: [PATCH] Display error when LSP Server fails to initialize. --- projects/linux/ee.creator.user | 30 +++++++++- src/tools/ecode/notificationcenter.cpp | 12 ++-- src/tools/ecode/notificationcenter.hpp | 2 +- .../ecode/plugins/lsp/lspclientserver.cpp | 58 +++++++++++++------ .../ecode/plugins/lsp/lspclientserver.hpp | 3 + .../plugins/lsp/lspclientservermanager.cpp | 12 ++-- src/tools/ecode/plugins/lsp/lspprotocol.hpp | 1 + 7 files changed, 88 insertions(+), 30 deletions(-) diff --git a/projects/linux/ee.creator.user b/projects/linux/ee.creator.user index dd796ba51..c3e529404 100644 --- a/projects/linux/ee.creator.user +++ b/projects/linux/ee.creator.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -937,6 +937,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-test-debug eepp-test-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -958,6 +959,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-test eepp-test-release ProjectExplorer.CustomExecutableRunConfiguration @@ -979,6 +981,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-physics-demo-debug eepp-physics-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1000,6 +1003,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-http-request-debug eepp-http-request-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1020,6 +1024,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}../../../bin/eeiv-debug eeiv-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1041,6 +1046,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-TextureAtlasEditor-debug eepp-TextureAtlasEditor-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1062,6 +1068,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-MapEditor-debug eepp-MapEditor-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1084,6 +1091,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-UIEditor-debug eepp-UIEditor-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1105,6 +1113,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-ui-hello-world-debug eepp-ui-hello-world-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1125,6 +1134,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-TexturePacker-debug eepp-TexturePacker-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1147,6 +1157,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-ui-perf-test-debug eepp-ui-perf-test-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1168,6 +1179,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/ecode-debug ecode-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1189,6 +1201,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-empty-window-debug eepp-empty-window-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1210,6 +1223,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eterm-debug eterm-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1231,6 +1245,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-crud-debug eepp-7guis-crud-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1252,6 +1267,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-timer-debug eepp-7guis-timer-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1273,6 +1289,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-counter-debug eepp-7guis-counter-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1294,6 +1311,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-temperature-converter-debug eepp-7guis-temperature-converter-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1315,6 +1333,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-flight-booker-debug eepp-7guis-flight-booker-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1336,6 +1355,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-circle-drawer-debug eepp-7guis-circle-drawer ProjectExplorer.CustomExecutableRunConfiguration @@ -1357,6 +1377,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-7guis-cells-debug eepp-7guis-cells-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1378,6 +1399,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-empty-window eepp-empty-window-release ProjectExplorer.CustomExecutableRunConfiguration @@ -1399,6 +1421,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-external-shader-debug eepp-external-shader-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1419,6 +1442,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-external-shader eepp-external-shader-release ProjectExplorer.CustomExecutableRunConfiguration @@ -1439,6 +1463,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-sound-debug eepp-sound-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1459,6 +1484,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-sprites-debug eepp-sprites-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1479,6 +1505,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-fonts-debug eepp-fonts-debug ProjectExplorer.CustomExecutableRunConfiguration @@ -1500,6 +1527,7 @@ 2 false + -e cpu-cycles --call-graph dwarf,4096 -F 250 %{buildDir}/../../bin/eepp-vbo-fbo-batch-debug eepp-vbo-fbo-batch-debug ProjectExplorer.CustomExecutableRunConfiguration diff --git a/src/tools/ecode/notificationcenter.cpp b/src/tools/ecode/notificationcenter.cpp index 32623ed88..52423e823 100644 --- a/src/tools/ecode/notificationcenter.cpp +++ b/src/tools/ecode/notificationcenter.cpp @@ -11,7 +11,7 @@ NotificationCenter::NotificationCenter( UILayout* layout, PluginManager* pluginM if ( msg.type == PluginMessageType::ShowMessage ) { auto sm = msg.asShowMessage(); if ( !sm.message.empty() ) - addNotification( sm.message, Seconds( 10 ) ); + addNotification( sm.message, Seconds( 10 ), sm.allowCopy ); } else if ( msg.type == PluginMessageType::ShowDocument ) { auto sd = msg.asShowDocument(); if ( !sd.uri.empty() ) { @@ -24,12 +24,13 @@ NotificationCenter::NotificationCenter( UILayout* layout, PluginManager* pluginM } ); } -void NotificationCenter::addNotification( const String& text, const Time& delay ) { - auto action = [this, text, delay]() { +void NotificationCenter::addNotification( const String& text, const Time& delay, bool allowCopy ) { + auto action = [this, text, delay, allowCopy]() { UITextView* tv = UITextView::New(); - tv->addEventListener( Event::MouseClick, [tv]( const Event* event ) { + tv->on( Event::MouseClick, [tv, allowCopy]( const Event* event ) { const MouseEvent* mouseEvent = static_cast( event ); - if ( mouseEvent->getFlags() & EE_BUTTON_LMASK ) + if ( mouseEvent->getFlags() & + ( allowCopy ? EE_BUTTON_MMASK : ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) ) tv->close(); } ); tv->setParent( mLayout ); @@ -37,6 +38,7 @@ void NotificationCenter::addNotification( const String& text, const Time& delay tv->setFlags( UI_WORD_WRAP ); tv->setText( text ); tv->addClass( "notification" ); + tv->setTextSelection( allowCopy ); Action* sequence = Actions::Sequence::New( { Actions::FadeIn::New( Seconds( 0.125 ) ), Actions::Delay::New( delay ), Actions::FadeOut::New( Seconds( 0.125 ) ), Actions::Close::New() } ); diff --git a/src/tools/ecode/notificationcenter.hpp b/src/tools/ecode/notificationcenter.hpp index 218fc1435..e5ed81215 100644 --- a/src/tools/ecode/notificationcenter.hpp +++ b/src/tools/ecode/notificationcenter.hpp @@ -10,7 +10,7 @@ class NotificationCenter { public: NotificationCenter( UILayout* layout, PluginManager* pluginManager ); - void addNotification( const String& text, const Time& delay = Seconds( 2.5 ) ); + void addNotification( const String& text, const Time& delay = Seconds( 2.5 ), bool allowCopy = false ); void addShowRequest( const String& uri, const String& actionText, const Time& delay = Seconds( 2.5 ) ); diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index d854f65b0..bfaadeda2 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -1218,15 +1218,19 @@ bool LSPClientServer::start() { if ( !cmd.empty() ) { bool ret = mProcess.create( cmd, Process::getDefaultOptions() | Process::EnableAsync, mLSP.env, mRootPath ); - if ( ret && mProcess.isAlive() ) { - mUsingProcess = true; + if ( ret ) { + if ( mProcess.isAlive() ) { + mUsingProcess = true; - mProcess.startAsyncRead( - [this]( const char* bytes, size_t n ) { readStdOut( bytes, n ); }, - [this]( const char* bytes, size_t n ) { readStdErr( bytes, n ); } ); + mProcess.startAsyncRead( + [this]( const char* bytes, size_t n ) { readStdOut( bytes, n ); }, + [this]( const char* bytes, size_t n ) { readStdErr( bytes, n ); } ); - if ( mLSP.host.empty() ) - initialize(); + if ( mLSP.host.empty() ) + initialize(); + } else { + ret = false; + } } if ( ret && !mLSP.host.empty() ) { @@ -1313,8 +1317,10 @@ LSPClientServer::LSPRequestHandle LSPClientServer::write( json&& msg, const Json LSPRequestHandle ret; ret.server = this; - if ( !isRunning() ) + if ( !isRunning() ) { + notifyServerError(); return ret; + } msg["jsonrpc"] = "2.0"; @@ -1394,6 +1400,7 @@ LSPClientServer::LSPRequestHandle LSPClientServer::send( json&& msg, const JsonR } else { Log::warning( "LSPClientServer server %s Send for non-running server: %s", mLSP.name.c_str(), mLSP.name.c_str() ); + notifyServerError(); } return LSPRequestHandle(); } @@ -1405,6 +1412,7 @@ LSPClientServer::LSPRequestHandle LSPClientServer::sendSync( json&& msg, const J } else { Log::warning( "LSPClientServer server %s Send for non-running server: %s", mLSP.name.c_str(), mLSP.name.c_str() ); + notifyServerError(); } return LSPRequestHandle(); } @@ -1897,20 +1905,32 @@ void LSPClientServer::readStdOut( const char* bytes, size_t n ) { } } +void LSPClientServer::notifyServerError() { + if ( mNotifiedServerError || mReady ) + return; + mNotifiedServerError = true; + LSPShowMessageParams msg; + msg.message = String::format( "LSP Server %s failed to initialize, received some error:\n%s", + mLSP.name, mReceiveErr ); + msg.type = LSPMessageType::Error; + mManager->getPluginManager()->sendBroadcast( PluginMessageType::ShowMessage, + PluginMessageFormat::ShowMessage, &msg ); +} + void LSPClientServer::readStdErr( const char* bytes, size_t n ) { if ( mEnded ) return; - mReceiveErr += std::string( bytes, n ); - LSPShowMessageParams msg; - const auto lastNewLineIndex = mReceiveErr.find_last_of( '\n' ); - if ( lastNewLineIndex != std::string::npos ) { - msg.message = mReceiveErr.substr( 0, lastNewLineIndex ); - mReceiveErr.erase( 0, lastNewLineIndex + 1 ); - } - if ( !msg.message.empty() ) { - Log::debug( "LSPClientServer::readStdErr server %s:\n%s", mLSP.name.c_str(), - msg.message.c_str() ); - } + + std::string_view received( bytes, n ); + received = String::trim( received, '\n' ); + received = String::trim( received, ' ' ); + mReceiveErr = received; + + if ( !received.empty() ) + Log::debug( "LSPClientServer::readStdErr server %s:\n%s", mLSP.name, received ); + + if ( !isRunning() ) + notifyServerError(); } void LSPClientServer::sendQueuedMessages() { diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.hpp b/src/tools/ecode/plugins/lsp/lspclientserver.hpp index 06b6d8359..09a7e968e 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.hpp @@ -262,6 +262,7 @@ class LSPClientServer { bool mEnded{ false }; bool mUsingProcess{ false }; bool mUsingSocket{ false }; + bool mNotifiedServerError{ false }; struct QueueMessage { json msg; JsonReplyHandler h; @@ -319,6 +320,8 @@ class LSPClientServer { void refreshCodeLens(); bool trimLogs() const; + + void notifyServerError(); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 70cece4de..ffcbd5b84 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -115,8 +115,13 @@ void LSPClientServerManager::tryRunServer( const std::shared_ptr& runLSPServer( id, rlsp, rootPath, languagesSupported ); if ( ( server = serverUP.get() ) ) { mClients[id] = std::move( serverUP ); - if ( !mLSPWorkspaceFolder.uri.empty() ) - server->didChangeWorkspaceFolders( { mLSPWorkspaceFolder }, {}, true ); + if ( server->isRunning() ) { + if ( !mLSPWorkspaceFolder.uri.empty() ) + server->didChangeWorkspaceFolders( { mLSPWorkspaceFolder }, {}, true ); + } else { + Log::debug( "LSP Server: %s failed to initialize.", + server->getDefinition().name ); + } } } else { server = clientIt->second.get(); @@ -466,8 +471,7 @@ const std::vector& LSPClientServerManager::getLSPs() const { return mLSPs; } -LSPDefinition -LSPClientServerManager::getLSPForLang( const std::string& lang ) const { +LSPDefinition LSPClientServerManager::getLSPForLang( const std::string& lang ) const { for ( const auto& lsp : mLSPs ) { if ( lsp.language == lang ) return lsp; diff --git a/src/tools/ecode/plugins/lsp/lspprotocol.hpp b/src/tools/ecode/plugins/lsp/lspprotocol.hpp index 232aee72c..e5059b574 100644 --- a/src/tools/ecode/plugins/lsp/lspprotocol.hpp +++ b/src/tools/ecode/plugins/lsp/lspprotocol.hpp @@ -175,6 +175,7 @@ struct LSPShowMessageParams { LSPMessageType type{ LSPMessageType::Log }; std::string message; std::vector actions; + bool allowCopy{ false }; }; struct LSPTextDocumentContentChangeEvent {