From ec67e0b13fa7848ee07b75df18a86731fa61802b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 15 Mar 2023 16:56:21 -0300 Subject: [PATCH] ecode: LSP - Don't fork a new process if the binary isn't available on the file system. Don't process notifications without method. Fix feature detection on initialize response when the server explicitly returns false for a feature. --- src/tools/ecode/plugins/lsp/lspclientserver.cpp | 12 +++++++++--- .../ecode/plugins/lsp/lspclientservermanager.cpp | 2 ++ src/tools/ecode/plugins/lsp/lspdefinition.hpp | 10 ++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/tools/ecode/plugins/lsp/lspclientserver.cpp b/src/tools/ecode/plugins/lsp/lspclientserver.cpp index 05baa8dcd..3c5a201a5 100644 --- a/src/tools/ecode/plugins/lsp/lspclientserver.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientserver.cpp @@ -294,7 +294,8 @@ static void fromJson( LSPServerCapabilities& caps, const json& json ) { // so consider an object there as a (good?) sign that the server is suitably capable auto toBoolOrObject = []( const nlohmann::json& value, const std::string& valueName ) { return value.contains( valueName ) && - ( value[valueName].is_boolean() || value[valueName].is_object() ); + ( ( value[valueName].is_boolean() && value.value( valueName, false ) ) || + value[valueName].is_object() ); }; auto& sync = json["textDocumentSync"]; @@ -1404,6 +1405,11 @@ void LSPClientServer::workDoneProgress( const LSPWorkDoneProgressParams& workDon } void LSPClientServer::processNotification( const json& msg ) { + if ( !msg.contains( MEMBER_METHOD ) ) { + Log::info( "LSPClientServer::processNotification - Unexpected notification, msg: %s", + msg.dump().c_str() ); + return; + } auto method = msg[MEMBER_METHOD].get(); if ( method == "textDocument/publishDiagnostics" ) { publishDiagnostics( msg ); @@ -1555,8 +1561,8 @@ void LSPClientServer::readStdOut( const char* bytes, size_t n ) { Log::debug( "LSPClientServer::readStdOut server %s said:\n%s", mLSP.name.c_str(), res.dump().c_str() ); - HandlersMap::iterator it = mHandlers.end(); - HandlersMap::iterator itEnd = mHandlers.end(); + HandlersMap::iterator it; + HandlersMap::iterator itEnd; JsonReplyHandler handlerOK; JsonReplyHandler handlerErr; bool handlerFound = false; diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 8e9fc4804..fe28fdd11 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -83,6 +83,8 @@ void LSPClientServerManager::tryRunServer( const std::shared_ptr& return; for ( const auto& lsp : lsps ) { + if ( !lsp.commandAvailable() ) + continue; std::string rootPath = mLSPWorkspaceFolder.isEmpty() ? findRootPath( lsp, doc ) : mLSPWorkspaceFolder.uri.getFSPath(); auto lspName = lsp.name.empty() ? lsp.command : lsp.name; diff --git a/src/tools/ecode/plugins/lsp/lspdefinition.hpp b/src/tools/ecode/plugins/lsp/lspdefinition.hpp index a0192d164..3c622ac5c 100644 --- a/src/tools/ecode/plugins/lsp/lspdefinition.hpp +++ b/src/tools/ecode/plugins/lsp/lspdefinition.hpp @@ -1,9 +1,14 @@ #ifndef ECODE_LSPDEFINITION_HPP #define ECODE_LSPDEFINITION_HPP +#include +#include #include #include #include +using namespace EE; +using namespace EE::System; + namespace ecode { struct LSPDefinition { @@ -17,6 +22,11 @@ struct LSPDefinition { nlohmann::json initializationOptions; bool disabled{ false }; + + bool commandAvailable() const { + auto cmdp( String::split( command, ' ' ) ); + return !cmdp.empty() && !Sys::which( cmdp[0] ).empty(); + } }; } // namespace ecode